]> git.saurik.com Git - apple/libplatform.git/blob - include/libkern/OSAtomicQueue.h
103f1e86ba616b7e0f68ef88a54bc8fdd902215c
[apple/libplatform.git] / include / libkern / OSAtomicQueue.h
1 /*
2 * Copyright (c) 2004-2016 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #ifndef _OSATOMICQUEUE_H_
25 #define _OSATOMICQUEUE_H_
26
27 #include <stddef.h>
28 #include <sys/cdefs.h>
29 #include <stdint.h>
30 #include <stdbool.h>
31
32 #include <Availability.h>
33
34 /*! @header Lockless atomic enqueue and dequeue
35 * These routines manipulate singly-linked LIFO lists.
36 */
37
38 __BEGIN_DECLS
39
40 /*! @abstract The data structure for a queue head.
41 @discussion
42 You should always initialize a queue head structure with the
43 initialization vector {@link OS_ATOMIC_QUEUE_INIT} before use.
44 */
45 #if defined(__LP64__)
46
47 typedef volatile struct {
48 void *opaque1;
49 long opaque2;
50 } __attribute__ ((aligned (16))) OSQueueHead;
51
52 #else
53
54 typedef volatile struct {
55 void *opaque1;
56 long opaque2;
57 } OSQueueHead;
58
59 #endif
60
61 /*! @abstract The initialization vector for a queue head. */
62 #define OS_ATOMIC_QUEUE_INIT { NULL, 0 }
63
64 /*! @abstract Enqueue an element onto a list.
65 @discussion
66 Memory barriers are incorporated as needed to permit thread-safe access
67 to the queue element.
68 @param __list
69 The list on which you want to enqueue the element.
70 @param __new
71 The element to add.
72 @param __offset
73 The "offset" parameter is the offset (in bytes) of the link field
74 from the beginning of the data structure being queued (<code>__new</code>).
75 The link field should be a pointer type.
76 The <code>__offset</code> value needs to be same for all enqueuing and
77 dequeuing operations on the same list, even if different structure types
78 are enqueued on that list. The use of <code>offsetset()</code>, defined in
79 <code>stddef.h</code> is the common way to specify the <code>__offset</code>
80 value.
81 */
82 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_4_0)
83 void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset);
84
85
86 /*! @abstract Dequeue an element from a list.
87 @discussion
88 Memory barriers are incorporated as needed to permit thread-safe access
89 to the queue element.
90 @param __list
91 The list from which you want to dequeue an element.
92 @param __offset
93 The "offset" parameter is the offset (in bytes) of the link field
94 from the beginning of the data structure being dequeued (<code>__new</code>).
95 The link field should be a pointer type.
96 The <code>__offset</code> value needs to be same for all enqueuing and
97 dequeuing operations on the same list, even if different structure types
98 are enqueued on that list. The use of <code>offsetset()</code>, defined in
99 <code>stddef.h</code> is the common way to specify the <code>__offset</code>
100 value.
101 IMPORTANT: the memory backing the link field of a queue element must not be
102 unmapped after OSAtomicDequeue() returns until all concurrent calls to
103 OSAtomicDequeue() for the same list on other threads have also returned,
104 as they may still be accessing that memory location.
105 @result
106 Returns the most recently enqueued element, or <code>NULL</code> if the
107 list is empty.
108 */
109 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_4_0)
110 void* OSAtomicDequeue( OSQueueHead *__list, size_t __offset);
111
112 #if defined(__x86_64__) || defined(__i386__)
113
114 /*! @group Lockless atomic fifo enqueue and dequeue
115 * These routines manipulate singly-linked FIFO lists.
116 */
117
118 /*! @abstract The data structure for a fifo queue head.
119 @discussion
120 You should always initialize a fifo queue head structure with the
121 initialization vector {@link OS_ATOMIC_FIFO_QUEUE_INIT} before use.
122 */
123 #if defined(__x86_64__)
124
125 typedef volatile struct {
126 void *opaque1;
127 void *opaque2;
128 int opaque3;
129 } __attribute__ ((aligned (16))) OSFifoQueueHead;
130
131 #else
132
133 typedef volatile struct {
134 void *opaque1;
135 void *opaque2;
136 int opaque3;
137 } OSFifoQueueHead;
138
139 #endif
140
141 /*! @abstract The initialization vector for a fifo queue head. */
142 #define OS_ATOMIC_FIFO_QUEUE_INIT { NULL, NULL, 0 }
143
144 /*! @abstract Enqueue an element onto a list.
145 @discussion
146 Memory barriers are incorporated as needed to permit thread-safe access
147 to the queue element.
148 @param __list
149 The list on which you want to enqueue the element.
150 @param __new
151 The element to add.
152 @param __offset
153 The "offset" parameter is the offset (in bytes) of the link field
154 from the beginning of the data structure being queued (<code>__new</code>).
155 The link field should be a pointer type.
156 The <code>__offset</code> value needs to be same for all enqueuing and
157 dequeuing operations on the same list, even if different structure types
158 are enqueued on that list. The use of <code>offsetset()</code>, defined in
159 <code>stddef.h</code> is the common way to specify the <code>__offset</code>
160 value.
161 */
162 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
163 void OSAtomicFifoEnqueue( OSFifoQueueHead *__list, void *__new, size_t __offset);
164
165 /*! @abstract Dequeue an element from a list.
166 @discussion
167 Memory barriers are incorporated as needed to permit thread-safe access
168 to the queue element.
169 @param __list
170 The list from which you want to dequeue an element.
171 @param __offset
172 The "offset" parameter is the offset (in bytes) of the link field
173 from the beginning of the data structure being dequeued (<code>__new</code>).
174 The link field should be a pointer type.
175 The <code>__offset</code> value needs to be same for all enqueuing and
176 dequeuing operations on the same list, even if different structure types
177 are enqueued on that list. The use of <code>offsetset()</code>, defined in
178 <code>stddef.h</code> is the common way to specify the <code>__offset</code>
179 value.
180 @result
181 Returns the oldest enqueued element, or <code>NULL</code> if the
182 list is empty.
183 */
184 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
185 void* OSAtomicFifoDequeue( OSFifoQueueHead *__list, size_t __offset);
186
187 #endif /* __i386__ || __x86_64__ */
188
189 __END_DECLS
190
191 #endif /* _OSATOMICQUEUE_H_ */