2  * Copyright (c) 2008-2009 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_QUEUE_INTERNAL__ 
  28 #define __DISPATCH_QUEUE_INTERNAL__ 
  30 #ifndef __DISPATCH_INDIRECT__ 
  31 #error "Please #include <dispatch/dispatch.h> instead of this file directly." 
  32 #include <dispatch/base.h> // for HeaderDoc 
  35 // If dc_vtable is less than 127, then the object is a continuation. 
  36 // Otherwise, the object has a private layout and memory management rules. The 
  37 // first two words must align with normal objects. 
  38 #define DISPATCH_CONTINUATION_HEADER(x) \ 
  39         const void *                            do_vtable;      \ 
  40         struct x *volatile      do_next;        \ 
  41         dispatch_function_t     dc_func;        \ 
  44 #define DISPATCH_OBJ_ASYNC_BIT  0x1 
  45 #define DISPATCH_OBJ_BARRIER_BIT        0x2 
  46 #define DISPATCH_OBJ_GROUP_BIT  0x4 
  47 // vtables are pointers far away from the low page in memory 
  48 #define DISPATCH_OBJ_IS_VTABLE(x)       ((unsigned long)(x)->do_vtable > 127ul) 
  50 struct dispatch_continuation_s 
{ 
  51         DISPATCH_CONTINUATION_HEADER(dispatch_continuation_s
); 
  52         dispatch_group_t        dc_group
; 
  56 typedef struct dispatch_continuation_s 
*dispatch_continuation_t
; 
  59 struct dispatch_queue_vtable_s 
{ 
  60         DISPATCH_VTABLE_HEADER(dispatch_queue_s
); 
  63 #define DISPATCH_QUEUE_MIN_LABEL_SIZE   64 
  65 #define DISPATCH_QUEUE_HEADER \ 
  66         uint32_t dq_running; \ 
  68         struct dispatch_object_s *dq_items_tail; \ 
  69         struct dispatch_object_s *volatile dq_items_head; \ 
  70         unsigned long dq_serialnum; \ 
  71         void *dq_finalizer_ctxt; \ 
  72         dispatch_queue_finalizer_function_t dq_finalizer_func 
  74 struct dispatch_queue_s 
{ 
  75         DISPATCH_STRUCT_HEADER(dispatch_queue_s
, dispatch_queue_vtable_s
); 
  76         DISPATCH_QUEUE_HEADER
; 
  77         char dq_label
[DISPATCH_QUEUE_MIN_LABEL_SIZE
];   // must be last 
  80 extern struct dispatch_queue_s _dispatch_mgr_q
; 
  82 void _dispatch_queue_init(dispatch_queue_t dq
); 
  83 void _dispatch_queue_drain(dispatch_queue_t dq
); 
  84 void _dispatch_queue_dispose(dispatch_queue_t dq
); 
  86 __attribute__((always_inline
)) 
  88 _dispatch_queue_push_list(dispatch_queue_t dq
, dispatch_object_t _head
, dispatch_object_t _tail
) 
  90         struct dispatch_object_s 
*prev
, *head 
= _head
._do
, *tail 
= _tail
._do
; 
  93         prev 
= fastpath(dispatch_atomic_xchg(&dq
->dq_items_tail
, tail
)); 
  95                 // if we crash here with a value less than 0x1000, then we are at a known bug in client code 
  96                 // for example, see _dispatch_queue_dispose or _dispatch_atfork_child 
  99                 dq
->dq_items_head 
= head
; 
 100                 _dispatch_wakeup(dq
); 
 104 #define _dispatch_queue_push(x, y) _dispatch_queue_push_list((x), (y), (y)) 
 106 #define DISPATCH_QUEUE_PRIORITY_COUNT 3 
 109 void dispatch_debug_queue(dispatch_queue_t dq
, const char* str
); 
 111 static inline void dispatch_debug_queue(dispatch_queue_t dq 
__attribute__((unused
)), const char* str 
__attribute__((unused
))) {} 
 114 size_t dispatch_queue_debug(dispatch_queue_t dq
, char* buf
, size_t bufsiz
); 
 115 size_t dispatch_queue_debug_attr(dispatch_queue_t dq
, char* buf
, size_t bufsiz
); 
 117 static inline dispatch_queue_t
 
 118 _dispatch_queue_get_current(void) 
 120         return _dispatch_thread_getspecific(dispatch_queue_key
); 
 123 __private_extern__ malloc_zone_t 
*_dispatch_ccache_zone
; 
 124 dispatch_continuation_t 
_dispatch_continuation_alloc_from_heap(void); 
 126 static inline dispatch_continuation_t
 
 127 _dispatch_continuation_alloc_cacheonly(void) 
 129         dispatch_continuation_t dc 
= fastpath(_dispatch_thread_getspecific(dispatch_cache_key
)); 
 131                 _dispatch_thread_setspecific(dispatch_cache_key
, dc
->do_next
);