]>
Commit | Line | Data |
---|---|---|
59e0d9fe A |
1 | .Dd May 26, 2004 |
2 | .Dt ATOMIC 3 | |
3 | .Os Darwin | |
4 | .Sh NAME | |
5 | .Nm OSAtomicAdd32 , | |
3d9156a7 | 6 | .Nm OSAtomicAdd32Barrier , |
59e0d9fe | 7 | .Nm OSAtomicIncrement32 , |
3d9156a7 | 8 | .Nm OSAtomicIncrement32Barrier , |
59e0d9fe | 9 | .Nm OSAtomicDecrement32 , |
3d9156a7 | 10 | .Nm OSAtomicDecrement32Barrier , |
59e0d9fe | 11 | .Nm OSAtomicOr32 , |
3d9156a7 | 12 | .Nm OSAtomicOr32Barrier , |
59e0d9fe | 13 | .Nm OSAtomicAnd32 , |
3d9156a7 | 14 | .Nm OSAtomicAnd32Barrier , |
59e0d9fe | 15 | .Nm OSAtomicXor32 , |
3d9156a7 | 16 | .Nm OSAtomicXor32Barrier , |
59e0d9fe | 17 | .Nm OSAtomicAdd64 , |
3d9156a7 | 18 | .Nm OSAtomicAdd64Barrier , |
59e0d9fe | 19 | .Nm OSAtomicIncrement64 , |
3d9156a7 | 20 | .Nm OSAtomicIncrement64Barrier , |
59e0d9fe | 21 | .Nm OSAtomicDecrement64 , |
3d9156a7 | 22 | .Nm OSAtomicDecrement64Barrier , |
59e0d9fe | 23 | .Nm OSAtomicCompareAndSwap32 , |
3d9156a7 | 24 | .Nm OSAtomicCompareAndSwap32Barrier , |
59e0d9fe | 25 | .Nm OSAtomicCompareAndSwap64 , |
3d9156a7 | 26 | .Nm OSAtomicCompareAndSwap64Barrier , |
59e0d9fe | 27 | .Nm OSAtomicTestAndSet , |
3d9156a7 A |
28 | .Nm OSAtomicTestAndSetBarrier , |
29 | .Nm OSAtomicTestAndClear , | |
30 | .Nm OSAtomicTestAndClearBarrier | |
59e0d9fe A |
31 | .Nd atomic add, increment, decrement, or, and, xor, compare and swap, test and set, and test and clear |
32 | .Sh LIBRARY | |
33 | .Lb libc | |
34 | .Sh SYNOPSIS | |
35 | .In libkern/OSAtomic.h | |
36 | .Ft int32_t | |
37 | .Fn OSAtomicAdd32 "int32_t theAmount, int32_t *theValue" | |
38 | .Ft int32_t | |
3d9156a7 A |
39 | .Fn OSAtomicAdd32Barrier "int32_t theAmount, int32_t *theValue" |
40 | .Ft int32_t | |
59e0d9fe A |
41 | .Fn OSAtomicIncrement32 "int32_t *theValue" |
42 | .Ft int32_t | |
3d9156a7 A |
43 | .Fn OSAtomicIncrement32Barrier "int32_t *theValue" |
44 | .Ft int32_t | |
59e0d9fe A |
45 | .Fn OSAtomicDecrement32 "int32_t *theValue" |
46 | .Ft int32_t | |
3d9156a7 A |
47 | .Fn OSAtomicDecrement32Barrier "int32_t *theValue" |
48 | .Ft int32_t | |
59e0d9fe A |
49 | .Fn OSAtomicOr32 "uint32_t theMask, uint32_t *theValue" |
50 | .Ft int32_t | |
3d9156a7 A |
51 | .Fn OSAtomicOr32Barrier "uint32_t theMask, uint32_t *theValue" |
52 | .Ft int32_t | |
59e0d9fe A |
53 | .Fn OSAtomicAnd32 "uint32_t theMask, uint32_t *theValue" |
54 | .Ft int32_t | |
3d9156a7 A |
55 | .Fn OSAtomicAnd32Barrier "uint32_t theMask, uint32_t *theValue" |
56 | .Ft int32_t | |
59e0d9fe | 57 | .Fn OSAtomicXor32 "uint32_t theMask, uint32_t *theValue" |
3d9156a7 A |
58 | .Ft int32_t |
59 | .Fn OSAtomicXor32Barrier "uint32_t theMask, uint32_t *theValue" | |
59e0d9fe A |
60 | .Ft int64_t |
61 | .Fn OSAtomicAdd64 "int64_t theAmount, int64_t *theValue" | |
62 | .Ft int64_t | |
3d9156a7 A |
63 | .Fn OSAtomicAdd64Barrier "int64_t theAmount, int64_t *theValue" |
64 | .Ft int64_t | |
59e0d9fe A |
65 | .Fn OSAtomicIncrement64 "int64_t *theValue" |
66 | .Ft int64_t | |
3d9156a7 A |
67 | .Fn OSAtomicIncrement64Barrier "int64_t *theValue" |
68 | .Ft int64_t | |
59e0d9fe | 69 | .Fn OSAtomicDecrement64 "int64_t *theValue" |
3d9156a7 A |
70 | .Ft int64_t |
71 | .Fn OSAtomicDecrement64Barrier "int64_t *theValue" | |
59e0d9fe A |
72 | .Ft bool |
73 | .Fn OSAtomicCompareAndSwap32 "int32_t oldValue" "int32_t newValue" "int32_t *theValue" | |
74 | .Ft bool | |
3d9156a7 A |
75 | .Fn OSAtomicCompareAndSwap32Barrier "int32_t oldValue" "int32_t newValue" "int32_t *theValue" |
76 | .Ft bool | |
59e0d9fe A |
77 | .Fn OSAtomicCompareAndSwap64 "int64_t oldValue" "int64_t newValue" "int64_t *theValue" |
78 | .Ft bool | |
3d9156a7 A |
79 | .Fn OSAtomicCompareAndSwap64Barrier "int64_t oldValue" "int64_t newValue" "int64_t *theValue" |
80 | .Ft bool | |
59e0d9fe A |
81 | .Fn OSAtomicTestAndSet "uint32_t n, void *theAddress" |
82 | .Ft bool | |
3d9156a7 A |
83 | .Fn OSAtomicTestAndSetBarrier "uint32_t n, void *theAddress" |
84 | .Ft bool | |
59e0d9fe | 85 | .Fn OSAtomicTestAndClear "uint32_t n, void *theAddress" |
3d9156a7 A |
86 | .Ft bool |
87 | .Fn OSAtomicTestAndClearBarrier "uint32_t n, void *theAddress" | |
59e0d9fe | 88 | .Sh DESCRIPTION |
3d9156a7 A |
89 | These functions are thread and multiprocessor safe. For each function, there |
90 | is a version that does and anoother that does not incorporate a memory barrier. | |
91 | Barriers strictly order memory access on a weakly-ordered | |
92 | architecture such as PPC. All loads and stores executed in sequential program | |
93 | order before the barrier will complete before any load or store executed after | |
94 | the barrier. On a uniprocessor, the barrier operation is typically a nop. | |
95 | On a multiprocessor, the barrier can be quite expensive. | |
96 | .Pp | |
97 | Most code will want to use the barrier functions to insure that memory shared | |
98 | between threads is properly synchronized. For example, if you want to initialize | |
99 | a shared data structure and then atomically increment a variable to indicate | |
100 | that the initialization is complete, then you MUST use OSAtomicIncrement32Barrier() | |
101 | to ensure that the stores to your data structure complete before the atomic add. | |
102 | Likewise, the consumer of that data structure MUST use OSAtomicDecrement32Barrier(), | |
103 | in order to ensure that their loads of the structure are not executed before | |
104 | the atomic decrement. On the other hand, | |
105 | if you are simply incrementing a global counter, then it is safe and potentially much | |
106 | faster to use OSAtomicIncrement32(). If you are unsure which version to use, prefer | |
107 | the barrier variants as they are safer. | |
108 | .Pp | |
109 | The logical (and, or, xor) and bit test operations are layered on top of the | |
59e0d9fe | 110 | .Fn OSAtomicCompareAndSwap |
3d9156a7 A |
111 | primitives. |
112 | .Pp | |
113 | The memory address | |
59e0d9fe A |
114 | .Fa theValue |
115 | must be naturally aligned, ie 32-bit aligned for 32-bit operations and 64-bit | |
3d9156a7 A |
116 | aligned for 64-bit operations. |
117 | .Pp | |
118 | The 64-bit operations are only implemented for | |
59e0d9fe A |
119 | 64-bit processes. |
120 | .Pp | |
121 | .Fn OSAtomicCompareAndSwap32 | |
122 | and | |
123 | .Fn OSAtomicCompareAndSwap64 | |
124 | compare | |
125 | .Fa oldValue | |
126 | to | |
127 | .Fa *theValue , | |
128 | and set | |
129 | .Fa *theValue | |
130 | to | |
131 | .Fa newValue | |
132 | if the comparison is equal. The comparison and assignment | |
133 | occur as one atomic operation. | |
134 | .Pp | |
135 | .Fn OSAtomicTestAndSet | |
136 | and | |
137 | .Fn OSAtomicTestAndClear | |
138 | operate on bit (0x80 >> ( | |
139 | .Fa n | |
140 | & 7)) of byte ((char*) | |
141 | .Fa theAddress | |
142 | + ( | |
143 | .Fa n | |
144 | >> 3)). They set the named bit to either 1 or 0, respectively. | |
145 | .Fa theAddress | |
146 | need not be aligned. | |
147 | .Sh RETURN VALUES | |
148 | The arithmetic and logical operations return the new value, after the operation has been performed. | |
149 | The compare-and-swap operations return true if the comparison was equal, ie if the swap occured. | |
150 | The bit test and set/clear operations return the original value of the bit. | |
151 | .Sh SEE ALSO | |
152 | .Xr atomicqueue 3 , | |
153 | .Xr spinlock 3 , | |
154 | .Xr barrier 3 |