]>
Commit | Line | Data |
---|---|---|
ada7c492 A |
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> | |
442fbc9d | 31 | #include "OSAtomicDeprecated.h" |
ada7c492 A |
32 | |
33 | #include <Availability.h> | |
34 | ||
35 | /*! @header Lockless atomic enqueue and dequeue | |
36 | * These routines manipulate singly-linked LIFO lists. | |
37 | */ | |
38 | ||
39 | __BEGIN_DECLS | |
40 | ||
41 | /*! @abstract The data structure for a queue head. | |
42 | @discussion | |
43 | You should always initialize a queue head structure with the | |
44 | initialization vector {@link OS_ATOMIC_QUEUE_INIT} before use. | |
45 | */ | |
e45b4692 | 46 | #if defined(__LP64__) |
ada7c492 A |
47 | |
48 | typedef volatile struct { | |
49 | void *opaque1; | |
50 | long opaque2; | |
51 | } __attribute__ ((aligned (16))) OSQueueHead; | |
52 | ||
53 | #else | |
54 | ||
55 | typedef volatile struct { | |
56 | void *opaque1; | |
57 | long opaque2; | |
58 | } OSQueueHead; | |
59 | ||
60 | #endif | |
61 | ||
62 | /*! @abstract The initialization vector for a queue head. */ | |
63 | #define OS_ATOMIC_QUEUE_INIT { NULL, 0 } | |
64 | ||
65 | /*! @abstract Enqueue an element onto a list. | |
66 | @discussion | |
67 | Memory barriers are incorporated as needed to permit thread-safe access | |
68 | to the queue element. | |
69 | @param __list | |
70 | The list on which you want to enqueue the element. | |
71 | @param __new | |
72 | The element to add. | |
73 | @param __offset | |
74 | The "offset" parameter is the offset (in bytes) of the link field | |
75 | from the beginning of the data structure being queued (<code>__new</code>). | |
76 | The link field should be a pointer type. | |
77 | The <code>__offset</code> value needs to be same for all enqueuing and | |
78 | dequeuing operations on the same list, even if different structure types | |
79 | are enqueued on that list. The use of <code>offsetset()</code>, defined in | |
80 | <code>stddef.h</code> is the common way to specify the <code>__offset</code> | |
81 | value. | |
82 | */ | |
83 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_4_0) | |
84 | void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset); | |
85 | ||
86 | ||
87 | /*! @abstract Dequeue an element from a list. | |
88 | @discussion | |
89 | Memory barriers are incorporated as needed to permit thread-safe access | |
90 | to the queue element. | |
91 | @param __list | |
92 | The list from which you want to dequeue an element. | |
93 | @param __offset | |
94 | The "offset" parameter is the offset (in bytes) of the link field | |
95 | from the beginning of the data structure being dequeued (<code>__new</code>). | |
96 | The link field should be a pointer type. | |
97 | The <code>__offset</code> value needs to be same for all enqueuing and | |
98 | dequeuing operations on the same list, even if different structure types | |
99 | are enqueued on that list. The use of <code>offsetset()</code>, defined in | |
100 | <code>stddef.h</code> is the common way to specify the <code>__offset</code> | |
101 | value. | |
102 | IMPORTANT: the memory backing the link field of a queue element must not be | |
103 | unmapped after OSAtomicDequeue() returns until all concurrent calls to | |
104 | OSAtomicDequeue() for the same list on other threads have also returned, | |
105 | as they may still be accessing that memory location. | |
106 | @result | |
107 | Returns the most recently enqueued element, or <code>NULL</code> if the | |
108 | list is empty. | |
109 | */ | |
110 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_4_0) | |
111 | void* OSAtomicDequeue( OSQueueHead *__list, size_t __offset); | |
112 | ||
ada7c492 A |
113 | __END_DECLS |
114 | ||
115 | #endif /* _OSATOMICQUEUE_H_ */ |