2 * Copyright (c) 2010-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_INTERNAL__
28 #define __DISPATCH_INTROSPECTION_INTERNAL__
30 #if DISPATCH_INTROSPECTION
32 #define DISPATCH_INTROSPECTION_QUEUE_HEADER \
33 TAILQ_ENTRY(dispatch_queue_s) diq_list; \
34 dispatch_unfair_lock_s diq_order_top_head_lock; \
35 dispatch_unfair_lock_s diq_order_bottom_head_lock; \
36 TAILQ_HEAD(, dispatch_queue_order_entry_s) diq_order_top_head; \
37 TAILQ_HEAD(, dispatch_queue_order_entry_s) diq_order_bottom_head
38 #define DISPATCH_INTROSPECTION_QUEUE_HEADER_SIZE \
39 sizeof(struct { DISPATCH_INTROSPECTION_QUEUE_HEADER; })
41 struct dispatch_introspection_state_s
{
42 TAILQ_HEAD(, dispatch_introspection_thread_s
) threads
;
43 TAILQ_HEAD(, dispatch_queue_s
) queues
;
44 dispatch_unfair_lock_s threads_lock
;
45 dispatch_unfair_lock_s queues_lock
;
47 ptrdiff_t thread_queue_offset
;
49 // dispatch introspection features
50 bool debug_queue_inversions
; // DISPATCH_DEBUG_QUEUE_INVERSIONS
53 extern struct dispatch_introspection_state_s _dispatch_introspection
;
55 void _dispatch_introspection_init(void);
56 void _dispatch_introspection_thread_add(void);
57 dispatch_queue_t
_dispatch_introspection_queue_create(dispatch_queue_t dq
);
58 void _dispatch_introspection_queue_dispose(dispatch_queue_t dq
);
59 void _dispatch_introspection_queue_item_enqueue(dispatch_queue_t dq
,
60 dispatch_object_t dou
);
61 void _dispatch_introspection_queue_item_dequeue(dispatch_queue_t dq
,
62 dispatch_object_t dou
);
63 void _dispatch_introspection_queue_item_complete(dispatch_object_t dou
);
64 void _dispatch_introspection_callout_entry(void *ctxt
, dispatch_function_t f
);
65 void _dispatch_introspection_callout_return(void *ctxt
, dispatch_function_t f
);
69 static dispatch_queue_t
_dispatch_queue_get_current(void);
71 DISPATCH_ALWAYS_INLINE
73 _dispatch_introspection_queue_push_list(dispatch_queue_t dq
,
74 dispatch_object_t head
, dispatch_object_t tail
) {
75 struct dispatch_object_s
*dou
= head
._do
;
77 _dispatch_introspection_queue_item_enqueue(dq
, dou
);
78 } while (dou
!= tail
._do
&& (dou
= dou
->do_next
));
81 DISPATCH_ALWAYS_INLINE
83 _dispatch_introspection_queue_push(dispatch_queue_t dq
, dispatch_object_t dou
) {
84 _dispatch_introspection_queue_item_enqueue(dq
, dou
);
87 DISPATCH_ALWAYS_INLINE
89 _dispatch_introspection_queue_pop(dispatch_queue_t dq
, dispatch_object_t dou
) {
90 _dispatch_introspection_queue_item_dequeue(dq
, dou
);
94 _dispatch_introspection_order_record(dispatch_queue_t top_q
,
95 dispatch_queue_t bottom_q
);
98 _dispatch_introspection_target_queue_changed(dispatch_queue_t dq
);
100 DISPATCH_ALWAYS_INLINE
102 _dispatch_introspection_sync_begin(dispatch_queue_t dq
)
104 if (!_dispatch_introspection
.debug_queue_inversions
) return;
105 _dispatch_introspection_order_record(dq
, _dispatch_queue_get_current());
108 #endif // DISPATCH_PURE_C
110 #else // DISPATCH_INTROSPECTION
112 #define DISPATCH_INTROSPECTION_QUEUE_HEADER
113 #define DISPATCH_INTROSPECTION_QUEUE_HEADER_SIZE 0
115 #define _dispatch_introspection_init()
116 #define _dispatch_introspection_thread_add()
118 DISPATCH_ALWAYS_INLINE
119 static inline dispatch_queue_t
120 _dispatch_introspection_queue_create(dispatch_queue_t dq
) { return dq
; }
122 DISPATCH_ALWAYS_INLINE
124 _dispatch_introspection_queue_dispose(dispatch_queue_t dq
) { (void)dq
; }
126 DISPATCH_ALWAYS_INLINE
128 _dispatch_introspection_queue_push_list(dispatch_queue_t dq DISPATCH_UNUSED
,
129 dispatch_object_t head DISPATCH_UNUSED
,
130 dispatch_object_t tail DISPATCH_UNUSED
) {}
132 DISPATCH_ALWAYS_INLINE
134 _dispatch_introspection_queue_push(dispatch_queue_t dq DISPATCH_UNUSED
,
135 dispatch_object_t dou DISPATCH_UNUSED
) {}
137 DISPATCH_ALWAYS_INLINE
139 _dispatch_introspection_queue_pop(dispatch_queue_t dq DISPATCH_UNUSED
,
140 dispatch_object_t dou DISPATCH_UNUSED
) {}
142 DISPATCH_ALWAYS_INLINE
144 _dispatch_introspection_queue_item_complete(
145 dispatch_object_t dou DISPATCH_UNUSED
) {}
147 DISPATCH_ALWAYS_INLINE
149 _dispatch_introspection_callout_entry(void *ctxt DISPATCH_UNUSED
,
150 dispatch_function_t f DISPATCH_UNUSED
) {}
152 DISPATCH_ALWAYS_INLINE
154 _dispatch_introspection_callout_return(void *ctxt DISPATCH_UNUSED
,
155 dispatch_function_t f DISPATCH_UNUSED
) {}
157 DISPATCH_ALWAYS_INLINE
159 _dispatch_introspection_target_queue_changed(
160 dispatch_queue_t dq DISPATCH_UNUSED
) {}
162 DISPATCH_ALWAYS_INLINE
164 _dispatch_introspection_sync_begin(dispatch_queue_t dq DISPATCH_UNUSED
) {}
166 #endif // DISPATCH_INTROSPECTION
168 #endif // __DISPATCH_INTROSPECTION_INTERNAL__