2 * Copyright (c) 2012-2013 Apple Inc. All rights reserved.
4 * @APPLE_APACHE_LICENSE_HEADER_START@
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * @APPLE_APACHE_LICENSE_HEADER_END@
22 * IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
23 * which are subject to change in future releases of Mac OS X. Any applications
24 * relying on these interfaces WILL break.
27 #ifndef __DISPATCH_INTROSPECTION_PRIVATE__
28 #define __DISPATCH_INTROSPECTION_PRIVATE__
34 * Introspection SPI for libdispatch.
37 * This SPI is only available in the introspection version of the library,
38 * loaded by running a process with the environment variable
39 * DYLD_LIBRARY_PATH=/usr/lib/system/introspection
41 * NOTE: these functions are _not_ exported from the shared library, they are
42 * only intended to be called from a debugger context while the rest of the
43 * process is suspended.
47 #if defined(__cplusplus)
48 #define __BEGIN_DECLS extern "C" {
58 #ifndef __DISPATCH_INDIRECT__
60 * Typedefs of opaque types, for direct inclusion of header in lldb expressions
62 typedef __typeof__(sizeof(int)) size_t;
63 typedef struct _opaque_pthread_t
*pthread_t
;
64 typedef void (*dispatch_function_t
)(void *);
65 typedef struct Block_layout
*dispatch_block_t
;
66 typedef struct dispatch_continuation_s
*dispatch_continuation_t
;
67 typedef struct dispatch_queue_s
*dispatch_queue_t
;
68 typedef struct dispatch_source_s
*dispatch_source_t
;
69 typedef struct dispatch_group_s
*dispatch_group_t
;
70 typedef struct dispatch_object_s
*dispatch_object_t
;
74 * @typedef dispatch_introspection_versions_s
77 * A structure of version and size information of introspection structures.
79 * @field introspection_version
80 * Version of overall dispatch_introspection SPI.
82 * @field queue_version
83 * Version of dispatch_introspection_queue_s structure.
86 * Size of dispatch_introspection_queue_s structure.
88 * @field source_version
89 * Version of dispatch_introspection_source_s structure.
92 * Size of dispatch_introspection_source_s structure.
95 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
)
96 DISPATCH_EXPORT
const struct dispatch_introspection_versions_s
{
97 unsigned long introspection_version
;
98 unsigned long hooks_version
;
100 unsigned long queue_item_version
;
101 size_t queue_item_size
;
102 unsigned long queue_block_version
;
103 size_t queue_block_size
;
104 unsigned long queue_function_version
;
105 size_t queue_function_size
;
106 unsigned long queue_thread_version
;
107 size_t queue_thread_size
;
108 unsigned long object_version
;
110 unsigned long queue_version
;
112 unsigned long source_version
;
114 } dispatch_introspection_versions
;
117 * @typedef dispatch_introspection_queue_block_s
120 * A structure of introspection information for a block item enqueued on a
123 * @field continuation
124 * Pointer to enqueued item.
126 * @field target_queue
127 * Target queue of item (may be different to the queue the item is currently
131 * Block for enqueued item.
133 * @field block_invoke
134 * Function pointer of block for enqueued item.
137 * Group containing enqueued item (may be NULL).
140 * Thread waiting for completion of enqueued item (NULL if sync == 0).
143 * Item is a barrier on the queue (all items on serial queues are barriers).
146 * Item was enqueued by a dispatch_sync/dispatch_barrier_sync.
149 * Item is part of a dispatch_apply.
151 typedef struct dispatch_introspection_queue_block_s
{
152 dispatch_continuation_t continuation
;
153 dispatch_queue_t target_queue
;
154 dispatch_block_t block
;
155 dispatch_function_t block_invoke
;
156 dispatch_group_t group
;
158 unsigned long barrier
:1,
161 } dispatch_introspection_queue_block_s
;
162 typedef dispatch_introspection_queue_block_s
163 *dispatch_introspection_queue_block_t
;
166 * @typedef dispatch_introspection_queue_function_s
169 * A structure of introspection information for a function & context pointer
170 * item enqueued on a dispatch queue.
172 * @field continuation
173 * Pointer to enqueued item.
175 * @field target_queue
176 * Target queue of item (may be different to the queue the item is currently
180 * Context in enqueued item.
182 * @field block_invoke
183 * Function pointer in enqueued item.
186 * Group containing enqueued item (may be NULL).
189 * Thread waiting for completion of enqueued item (NULL if sync == 0).
192 * Item is a barrier on the queue (all items on serial queues are barriers).
195 * Item was enqueued by a dispatch_sync_f/dispatch_barrier_sync_f.
198 * Item is part of a dispatch_apply_f.
200 typedef struct dispatch_introspection_queue_function_s
{
201 dispatch_continuation_t continuation
;
202 dispatch_queue_t target_queue
;
204 dispatch_function_t function
;
205 dispatch_group_t group
;
207 unsigned long barrier
:1,
210 } dispatch_introspection_queue_function_s
;
211 typedef dispatch_introspection_queue_function_s
212 *dispatch_introspection_queue_function_t
;
215 * @typedef dispatch_introspection_object_s
218 * A structure of introspection information for a generic dispatch object.
223 * @field target_queue
224 * Target queue of object (may be different to the queue the object is
225 * currently enqueued on).
228 * Object class pointer.
231 * String describing the object type.
233 typedef struct dispatch_introspection_object_s
{
234 dispatch_continuation_t object
;
235 dispatch_queue_t target_queue
;
238 } dispatch_introspection_object_s
;
239 typedef dispatch_introspection_object_s
*dispatch_introspection_object_t
;
242 * @typedef dispatch_introspection_queue_s
245 * A structure of introspection information for a dispatch queue.
248 * Pointer to queue object.
250 * @field target_queue
251 * Target queue of queue (may be different to the queue the queue is currently
252 * enqueued on). NULL indicates queue is a root queue.
255 * Pointer to queue label.
258 * Queue serial number (unique per process).
261 * Queue width (1: serial queue, UINT_MAX: concurrent queue).
263 * @field suspend_count
264 * Number of times the queue has been suspended.
267 * Queue is enqueued on another queue.
270 * Queue is executing a barrier item.
273 * Queue is being drained (cannot get queue items).
276 * Queue is a global queue.
279 * Queue is the main queue.
281 typedef struct dispatch_introspection_queue_s
{
282 dispatch_queue_t queue
;
283 dispatch_queue_t target_queue
;
285 unsigned long serialnum
;
287 unsigned int suspend_count
;
288 unsigned long enqueued
:1,
293 } dispatch_introspection_queue_s
;
294 typedef dispatch_introspection_queue_s
*dispatch_introspection_queue_t
;
297 * @typedef dispatch_introspection_source_s
300 * A structure of introspection information for a dispatch source.
303 * Pointer to source object.
305 * @field target_queue
306 * Target queue of source (may be different to the queue the source is currently
310 * Source type (kevent filter)
313 * Source handle (monitored entity).
316 * Context pointer passed to source handler. Pointer to handler block if
317 * handler_is_block == 1.
320 * Source handler function. Function pointer of handler block if
321 * handler_is_block == 1.
323 * @field suspend_count
324 * Number of times the source has been suspended.
327 * Source is enqueued on a queue.
329 * @field handler_is_block
330 * Source handler is a block.
336 * Source is a dispatch_after timer.
338 typedef struct dispatch_introspection_source_s
{
339 dispatch_source_t source
;
340 dispatch_queue_t target_queue
;
342 unsigned long handle
;
344 dispatch_function_t handler
;
345 unsigned int suspend_count
;
346 unsigned long enqueued
:1,
350 } dispatch_introspection_source_s
;
351 typedef dispatch_introspection_source_s
*dispatch_introspection_source_t
;
354 * @typedef dispatch_introspection_queue_thread_s
357 * A structure of introspection information about a thread executing items for
361 * Pointer to thread object.
364 * Thread executing items for a queue.
367 * Queue introspection information. The queue.queue field is NULL if this thread
368 * is not currently executing items for a queue.
370 typedef struct dispatch_introspection_queue_thread_s
{
371 dispatch_continuation_t object
;
373 dispatch_introspection_queue_s queue
;
374 } dispatch_introspection_queue_thread_s
;
375 typedef dispatch_introspection_queue_thread_s
376 *dispatch_introspection_queue_thread_t
;
379 * @enum dispatch_introspection_queue_item_type
382 * Types of items enqueued on a dispatch queue.
384 enum dispatch_introspection_queue_item_type
{
385 dispatch_introspection_queue_item_type_none
= 0x0,
386 dispatch_introspection_queue_item_type_block
= 0x11,
387 dispatch_introspection_queue_item_type_function
= 0x12,
388 dispatch_introspection_queue_item_type_object
= 0x100,
389 dispatch_introspection_queue_item_type_queue
= 0x101,
390 dispatch_introspection_queue_item_type_source
= 0102,
394 * @typedef dispatch_introspection_queue_item_s
397 * A structure of introspection information about an item enqueued on a
401 * Indicates which of the union members applies to this item.
403 typedef struct dispatch_introspection_queue_item_s
{
404 unsigned long type
; // dispatch_introspection_queue_item_type
406 dispatch_introspection_queue_block_s block
;
407 dispatch_introspection_queue_function_s function
;
408 dispatch_introspection_object_s object
;
409 dispatch_introspection_queue_s queue
;
410 dispatch_introspection_source_s source
;
412 } dispatch_introspection_queue_item_s
;
413 typedef dispatch_introspection_queue_item_s
414 *dispatch_introspection_queue_item_t
;
417 * @typedef dispatch_introspection_hook_queue_create_t
420 * A function pointer called when a dispatch queue is created.
423 * Pointer to queue introspection structure.
425 typedef void (*dispatch_introspection_hook_queue_create_t
)(
426 dispatch_introspection_queue_t queue_info
);
429 * @typedef dispatch_introspection_hook_queue_dispose_t
432 * A function pointer called when a dispatch queue is destroyed.
435 * Pointer to queue introspection structure.
437 typedef void (*dispatch_introspection_hook_queue_dispose_t
)(
438 dispatch_introspection_queue_t queue_info
);
441 * @typedef dispatch_introspection_hook_queue_item_enqueue_t
444 * A function pointer called when an item is enqueued onto a dispatch queue.
450 * Pointer to item introspection structure.
452 typedef void (*dispatch_introspection_hook_queue_item_enqueue_t
)(
453 dispatch_queue_t queue
, dispatch_introspection_queue_item_t item
);
456 * @typedef dispatch_introspection_hook_queue_item_dequeue_t
459 * A function pointer called when an item is dequeued from a dispatch queue.
465 * Pointer to item introspection structure.
467 typedef void (*dispatch_introspection_hook_queue_item_dequeue_t
)(
468 dispatch_queue_t queue
, dispatch_introspection_queue_item_t item
);
471 * @typedef dispatch_introspection_hooks_s
474 * A structure of function pointer hoooks into libdispatch.
477 typedef struct dispatch_introspection_hooks_s
{
478 dispatch_introspection_hook_queue_create_t queue_create
;
479 dispatch_introspection_hook_queue_dispose_t queue_dispose
;
480 dispatch_introspection_hook_queue_item_enqueue_t queue_item_enqueue
;
481 dispatch_introspection_hook_queue_item_dequeue_t queue_item_dequeue
;
483 } dispatch_introspection_hooks_s
;
484 typedef dispatch_introspection_hooks_s
*dispatch_introspection_hooks_t
;
487 * @function dispatch_introspection_get_queues
490 * Retrieve introspection information about all dispatch queues in the process,
491 * in batches of specified size.
494 * Retrieving queue information and iterating through the list of all queues
495 * must take place from a debugger context (while the rest of the process is
499 * Starting point for this batch of queue information, as returned by a previous
500 * call to _dispatch_introspection_get_queues().
501 * Pass NULL to retrieve the initial batch.
504 * Number of queues to introspect.
507 * Array to fill with queue information. If less than 'count' queues are left
508 * in this batch, the end of valid entries in the array will be indicated
509 * by an entry with NULL queue member.
512 * Queue to pass to another call to _dispatch_introspection_get_queues() to
513 * retrieve information about the next batch of queues. May be NULL if there
514 * are no more queues to iterate over.
516 extern dispatch_queue_t
517 dispatch_introspection_get_queues(dispatch_queue_t start
, size_t count
,
518 dispatch_introspection_queue_t queues
);
521 * @function dispatch_introspection_get_queue_threads
524 * Retrieve introspection information about all threads in the process executing
525 * items for dispatch queues, in batches of specified size.
528 * Retrieving thread information and iterating through the list of all queue
529 * threads must take place from a debugger context (while the rest of the
530 * process is suspended).
533 * Starting point for this batch of thread information, as returned by a
534 * previous call to _dispatch_introspection_get_queue_threads().
535 * Pass NULL to retrieve the initial batch.
538 * Number of queue threads to introspect.
541 * Array to fill with queue thread information. If less than 'count' threads are
542 * left in this batch, the end of valid entries in the array will be indicated
543 * by an entry with NULL object member.
546 * Object to pass to another call to _dispatch_introspection_get_queues() to
547 * retrieve information about the next batch of queues. May be NULL if there
548 * are no more queues to iterate over.
550 extern dispatch_continuation_t
551 dispatch_introspection_get_queue_threads(dispatch_continuation_t start
,
552 size_t count
, dispatch_introspection_queue_thread_t threads
);
555 * @function dispatch_introspection_queue_get_items
558 * Retrieve introspection information about all items enqueued on a queue, in
559 * batches of specified size.
562 * Retrieving queue item information and iterating through a queue must take
563 * place from a debugger context (while the rest of the process is suspended).
566 * Queue to introspect.
569 * Starting point for this batch of queue item information, as returned by a
570 * previous call to _dispatch_introspection_queue_get_items().
571 * Pass NULL to retrieve the initial batch.
574 * Number of items to introspect.
577 * Array to fill with queue item information. If less than 'count' queues are
578 * left in this batch, the end of valid entries in the array will be indicated
579 * by an entry with type dispatch_introspection_queue_item_type_none.
582 * Item to pass to another call to _dispatch_introspection_queue_get_items() to
583 * retrieve information about the next batch of queue items. May be NULL if
584 * there are no more items to iterate over.
586 extern dispatch_continuation_t
587 dispatch_introspection_queue_get_items(dispatch_queue_t queue
,
588 dispatch_continuation_t start
, size_t count
,
589 dispatch_introspection_queue_item_t items
);
592 * @function dispatch_introspection_queue_get_info
595 * Retrieve introspection information about a specified dispatch queue.
598 * Retrieving queue information must take place from a debugger context (while
599 * the rest of the process is suspended).
602 * Queue to introspect.
605 * Queue information struct.
607 extern dispatch_introspection_queue_s
608 dispatch_introspection_queue_get_info(dispatch_queue_t queue
);
611 * @function dispatch_introspection_queue_item_get_info
614 * Retrieve introspection information about a specified dispatch queue item.
617 * Retrieving queue item information must take place from a debugger context
618 * (while the rest of the process is suspended).
621 * Queue to introspect.
624 * Item to introspect.
627 * Queue item information struct.
629 extern dispatch_introspection_queue_item_s
630 dispatch_introspection_queue_item_get_info(dispatch_queue_t queue
,
631 dispatch_continuation_t item
);
634 * @function dispatch_introspection_hooks_install
637 * Install hook functions into libdispatch.
640 * Installing hook functions must take place from a debugger context (while the
641 * rest of the process is suspended).
643 * The caller is responsible for implementing chaining to the hooks that were
644 * previously installed (if any).
647 * Pointer to structure of hook function pointers. Any of the structure members
648 * may be NULL to indicate that the hook in question should not be installed.
649 * The structure is copied on input and filled with the previously installed
654 dispatch_introspection_hooks_install(dispatch_introspection_hooks_t hooks
);
657 * @function dispatch_introspection_hook_callouts_enable
660 * Enable hook callout functions in libdispatch that a debugger can break on
661 * and get introspection arguments even if there are no hook functions
662 * installed via dispatch_introspection_hooks_install().
665 * Enabling hook callout functions must take place from a debugger context
666 * (while the rest of the process is suspended).
669 * Pointer to dispatch_introspection_hooks_s structure. For every structure
670 * member with (any) non-NULL value, the corresponding hook callout will be
671 * enabled; for every NULL member the hook callout will be disabled (if there
672 * is no hook function installed).
673 * As a convenience, the 'enable' pointer may itself be NULL to indicate that
674 * all hook callouts should be enabled.
678 dispatch_introspection_hook_callouts_enable(
679 dispatch_introspection_hooks_t enable
);
682 * @function dispatch_introspection_hook_callout_queue_create
685 * Callout to queue creation hook that a debugger can break on.
689 dispatch_introspection_hook_callout_queue_create(
690 dispatch_introspection_queue_t queue_info
);
693 * @function dispatch_introspection_hook_callout_queue_dispose
696 * Callout to queue destruction hook that a debugger can break on.
700 dispatch_introspection_hook_callout_queue_dispose(
701 dispatch_introspection_queue_t queue_info
);
704 * @function dispatch_introspection_hook_callout_queue_item_enqueue
707 * Callout to queue enqueue hook that a debugger can break on.
711 dispatch_introspection_hook_callout_queue_item_enqueue(
712 dispatch_queue_t queue
, dispatch_introspection_queue_item_t item
);
715 * @function dispatch_introspection_hook_callout_queue_item_dequeue
718 * Callout to queue dequeue hook that a debugger can break on.
722 dispatch_introspection_hook_callout_queue_item_dequeue(
723 dispatch_queue_t queue
, dispatch_introspection_queue_item_t item
);