]> git.saurik.com Git - apple/libdispatch.git/blob - src/object_internal.h
libdispatch-84.5.tar.gz
[apple/libdispatch.git] / src / object_internal.h
1 /*
2 * Copyright (c) 2008-2009 Apple Inc. All rights reserved.
3 *
4 * @APPLE_APACHE_LICENSE_HEADER_START@
5 *
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
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
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.
17 *
18 * @APPLE_APACHE_LICENSE_HEADER_END@
19 */
20
21 /*
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.
25 */
26
27 #ifndef __DISPATCH_OBJECT_INTERNAL__
28 #define __DISPATCH_OBJECT_INTERNAL__
29
30 enum {
31 _DISPATCH_CONTINUATION_TYPE = 0x00000, // meta-type for continuations
32 _DISPATCH_QUEUE_TYPE = 0x10000, // meta-type for queues
33 _DISPATCH_SOURCE_TYPE = 0x20000, // meta-type for sources
34 _DISPATCH_SEMAPHORE_TYPE = 0x30000, // meta-type for semaphores
35 _DISPATCH_ATTR_TYPE = 0x10000000, // meta-type for attribute structures
36
37 DISPATCH_CONTINUATION_TYPE = _DISPATCH_CONTINUATION_TYPE,
38
39 DISPATCH_QUEUE_ATTR_TYPE = _DISPATCH_QUEUE_TYPE | _DISPATCH_ATTR_TYPE,
40
41 DISPATCH_QUEUE_TYPE = 1 | _DISPATCH_QUEUE_TYPE,
42 DISPATCH_QUEUE_GLOBAL_TYPE = 2 | _DISPATCH_QUEUE_TYPE,
43 DISPATCH_QUEUE_MGR_TYPE = 3 | _DISPATCH_QUEUE_TYPE,
44
45 DISPATCH_SEMAPHORE_TYPE = _DISPATCH_SEMAPHORE_TYPE,
46
47 DISPATCH_SOURCE_ATTR_TYPE = _DISPATCH_SOURCE_TYPE | _DISPATCH_ATTR_TYPE,
48
49 DISPATCH_SOURCE_KEVENT_TYPE = 1 | _DISPATCH_SOURCE_TYPE,
50 };
51
52 #define DISPATCH_VTABLE_HEADER(x) \
53 unsigned long const do_type; \
54 const char *const do_kind; \
55 size_t (*const do_debug)(struct x *, char *, size_t); \
56 struct dispatch_queue_s *(*const do_invoke)(struct x *); \
57 bool (*const do_probe)(struct x *); \
58 void (*const do_dispose)(struct x *)
59
60 #define dx_type(x) (x)->do_vtable->do_type
61 #define dx_kind(x) (x)->do_vtable->do_kind
62 #define dx_debug(x, y, z) (x)->do_vtable->do_debug((x), (y), (z))
63 #define dx_dispose(x) (x)->do_vtable->do_dispose(x)
64 #define dx_invoke(x) (x)->do_vtable->do_invoke(x)
65 #define dx_probe(x) (x)->do_vtable->do_probe(x)
66
67 #define DISPATCH_STRUCT_HEADER(x, y) \
68 const struct y *do_vtable; \
69 struct x *volatile do_next; \
70 unsigned int do_ref_cnt; \
71 unsigned int do_xref_cnt; \
72 unsigned int do_suspend_cnt; \
73 struct dispatch_queue_s *do_targetq; \
74 void *do_ctxt; \
75 void *do_finalizer
76
77 #define DISPATCH_OBJECT_GLOBAL_REFCNT (~0u)
78 #define DISPATCH_OBJECT_SUSPEND_LOCK 1u // "word and bit" must be a power of two to be safely subtracted
79 #define DISPATCH_OBJECT_SUSPEND_INTERVAL 2u
80 #define DISPATCH_OBJECT_SUSPENDED(x) ((x)->do_suspend_cnt >= DISPATCH_OBJECT_SUSPEND_INTERVAL)
81 #ifdef __LP64__
82 // the bottom nibble must not be zero, the rest of the bits should be random
83 // we sign extend the 64-bit version so that a better instruction encoding is generated on Intel
84 #define DISPATCH_OBJECT_LISTLESS ((void *)0xffffffff89abcdef)
85 #else
86 #define DISPATCH_OBJECT_LISTLESS ((void *)0x89abcdef)
87 #endif
88
89 #define _dispatch_trysuspend(x) __sync_bool_compare_and_swap(&(x)->do_suspend_cnt, 0, DISPATCH_OBJECT_SUSPEND_INTERVAL)
90 // _dispatch_source_invoke() relies on this testing the whole suspend count
91 // word, not just the lock bit. In other words, no point taking the lock
92 // if the source is suspended or canceled.
93 #define _dispatch_trylock(x) dispatch_atomic_cmpxchg(&(x)->do_suspend_cnt, 0, DISPATCH_OBJECT_SUSPEND_LOCK)
94
95 struct dispatch_object_vtable_s {
96 DISPATCH_VTABLE_HEADER(dispatch_object_s);
97 };
98
99 struct dispatch_object_s {
100 DISPATCH_STRUCT_HEADER(dispatch_object_s, dispatch_object_vtable_s);
101 };
102
103 size_t dispatch_object_debug_attr(dispatch_object_t dou, char* buf, size_t bufsiz);
104
105 void _dispatch_retain(dispatch_object_t dou);
106 void _dispatch_release(dispatch_object_t dou);
107 void _dispatch_dispose(dispatch_object_t dou);
108 dispatch_queue_t _dispatch_wakeup(dispatch_object_t dou);
109
110 #endif