2 .Dt ATOMIC_DEPRECATED 3
 
   6 .Nm OSAtomicAdd32Barrier ,
 
   7 .Nm OSAtomicIncrement32 ,
 
   8 .Nm OSAtomicIncrement32Barrier ,
 
   9 .Nm OSAtomicDecrement32 ,
 
  10 .Nm OSAtomicDecrement32Barrier ,
 
  12 .Nm OSAtomicOr32Barrier ,
 
  13 .Nm OSAtomicOr32Orig ,
 
  14 .Nm OSAtomicOr32OrigBarrier ,
 
  16 .Nm OSAtomicAnd32Barrier ,
 
  17 .Nm OSAtomicAnd32Orig ,
 
  18 .Nm OSAtomicAnd32OrigBarrier ,
 
  20 .Nm OSAtomicXor32Barrier ,
 
  21 .Nm OSAtomicXor32Orig ,
 
  22 .Nm OSAtomicXor32OrigBarrier ,
 
  24 .Nm OSAtomicAdd64Barrier ,
 
  25 .Nm OSAtomicIncrement64 ,
 
  26 .Nm OSAtomicIncrement64Barrier ,
 
  27 .Nm OSAtomicDecrement64 ,
 
  28 .Nm OSAtomicDecrement64Barrier ,
 
  29 .Nm OSAtomicCompareAndSwapInt ,
 
  30 .Nm OSAtomicCompareAndSwapIntBarrier ,
 
  31 .Nm OSAtomicCompareAndSwapLong ,
 
  32 .Nm OSAtomicCompareAndSwapLongBarrier ,
 
  33 .Nm OSAtomicCompareAndSwapPtr ,
 
  34 .Nm OSAtomicCompareAndSwapPtrBarrier ,
 
  35 .Nm OSAtomicCompareAndSwap32 ,
 
  36 .Nm OSAtomicCompareAndSwap32Barrier ,
 
  37 .Nm OSAtomicCompareAndSwap64 ,
 
  38 .Nm OSAtomicCompareAndSwap64Barrier ,
 
  39 .Nm OSAtomicTestAndSet ,
 
  40 .Nm OSAtomicTestAndSetBarrier ,
 
  41 .Nm OSAtomicTestAndClear ,
 
  42 .Nm OSAtomicTestAndClearBarrier ,
 
  44 .Nd deprecated atomic add, increment, decrement, or, and, xor, compare and swap, test and set, test and clear, and memory barrier
 
  46 .In libkern/OSAtomic.h
 
  48 .Fn OSAtomicAdd32 "int32_t theAmount" "volatile int32_t *theValue"
 
  50 .Fn OSAtomicAdd32Barrier "int32_t theAmount" "volatile int32_t *theValue"
 
  52 .Fn OSAtomicIncrement32 "volatile int32_t *theValue"
 
  54 .Fn OSAtomicIncrement32Barrier "volatile int32_t *theValue"
 
  56 .Fn OSAtomicDecrement32 "volatile int32_t *theValue"
 
  58 .Fn OSAtomicDecrement32Barrier "volatile int32_t *theValue"
 
  60 .Fn OSAtomicOr32 "uint32_t theMask" "volatile uint32_t *theValue"
 
  62 .Fn OSAtomicOr32Barrier "uint32_t theMask" "volatile uint32_t *theValue"
 
  64 .Fn OSAtomicAnd32 "uint32_t theMask" "volatile uint32_t *theValue"
 
  66 .Fn OSAtomicAnd32Barrier "uint32_t theMask" "volatile uint32_t *theValue"
 
  68 .Fn OSAtomicXor32 "uint32_t theMask" "volatile uint32_t *theValue"
 
  70 .Fn OSAtomicXor32Barrier "uint32_t theMask" "volatile uint32_t *theValue"
 
  72 .Fn OSAtomicOr32Orig "uint32_t theMask" "volatile uint32_t *theValue"
 
  74 .Fn OSAtomicOr32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue"
 
  76 .Fn OSAtomicAnd32Orig "uint32_t theMask" "volatile uint32_t *theValue"
 
  78 .Fn OSAtomicAnd32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue"
 
  80 .Fn OSAtomicXor32Orig "uint32_t theMask" "volatile uint32_t *theValue"
 
  82 .Fn OSAtomicXor32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue"
 
  84 .Fn OSAtomicAdd64 "int64_t theAmount" "volatile OSAtomic_int64_aligned64_t *theValue"
 
  86 .Fn OSAtomicAdd64Barrier "int64_t theAmount" "volatile OSAtomic_int64_aligned64_t *theValue"
 
  88 .Fn OSAtomicIncrement64 "volatile OSAtomic_int64_aligned64_t *theValue"
 
  90 .Fn OSAtomicIncrement64Barrier "volatile OSAtomic_int64_aligned64_t *theValue"
 
  92 .Fn OSAtomicDecrement64 "volatile OSAtomic_int64_aligned64_t *theValue"
 
  94 .Fn OSAtomicDecrement64Barrier "volatile OSAtomic_int64_aligned64_t *theValue"
 
  96 .Fn OSAtomicCompareAndSwapInt "int oldValue" "int newValue" "volatile int *theValue"
 
  98 .Fn OSAtomicCompareAndSwapIntBarrier "int oldValue" "int newValue" "volatile int *theValue"
 
 100 .Fn OSAtomicCompareAndSwapLong "long oldValue" "long newValue" "volatile long *theValue"
 
 102 .Fn OSAtomicCompareAndSwapLongBarrier "long oldValue" "long newValue" "volatile long *theValue"
 
 104 .Fn OSAtomicCompareAndSwapPtr "void* oldValue" "void* newValue" "void* volatile *theValue"
 
 106 .Fn OSAtomicCompareAndSwapPtrBarrier "void* oldValue" "void* newValue" "void* volatile *theValue"
 
 108 .Fn OSAtomicCompareAndSwap32 "int32_t oldValue" "int32_t newValue" "volatile int32_t *theValue"
 
 110 .Fn OSAtomicCompareAndSwap32Barrier "int32_t oldValue" "int32_t newValue" "volatile int32_t *theValue"
 
 112 .Fn OSAtomicCompareAndSwap64 "int64_t oldValue" "int64_t newValue" "volatile OSAtomic_int64_aligned64_t *theValue"
 
 114 .Fn OSAtomicCompareAndSwap64Barrier "int64_t oldValue" "int64_t newValue" "volatile OSAtomic_int64_aligned64_t *theValue"
 
 116 .Fn OSAtomicTestAndSet "uint32_t n" "volatile void *theAddress"
 
 118 .Fn OSAtomicTestAndSetBarrier "uint32_t n" "volatile void *theAddress"
 
 120 .Fn OSAtomicTestAndClear "uint32_t n" "volatile void *theAddress"
 
 122 .Fn OSAtomicTestAndClearBarrier "uint32_t n" "volatile void *theAddress"
 
 124 .Fn OSAtomicEnqueue "OSQueueHead *list" "void *new" "size_t offset"
 
 126 .Fn OSAtomicDequeue "OSQueueHead *list" "size_t offset"
 
 128 .Fn OSMemoryBarrier "void"
 
 131 These are deprecated interfaces for atomic and synchronization
 
 132 operations, provided for compatibility with legacy code. New code should use
 
 135 interfaces described in
 
 139 These functions are thread and multiprocessor safe.  For each function, there
 
 140 is a version which incorporates a memory barrier and another version which does
 
 142 Barriers strictly order memory access on a weakly-ordered architecture such as
 
 143 ARM. All loads and stores executed in sequential program
 
 144 order before the barrier will complete before any load or store executed after
 
 146 On some platforms, such as ARM, the barrier operation can be quite expensive.
 
 148 Most code will want to use the barrier functions to ensure that memory shared
 
 149 between threads is properly synchronized.  For example, if you want to
 
 150 initialize a shared data structure and then atomically increment a variable to
 
 151 indicate that the initialization is complete, then you must use
 
 152 .Fn OSAtomicIncrement32Barrier
 
 153 to ensure that the stores to your data structure complete before the atomic add.
 
 154 Likewise, the consumer of that data structure must use
 
 155 .Fn OSAtomicDecrement32Barrier ,
 
 156 in order to ensure that their loads of the structure are not executed before
 
 157 the atomic decrement.  On the other hand, if you are simply incrementing a
 
 158 global counter, then it is safe and potentially much faster to use
 
 159 .Fn OSAtomicIncrement32 .
 
 160 If you are unsure which version to use, prefer the barrier variants as they are
 
 163 The logical (and, or, xor) and bit test operations are layered on top of the
 
 164 .Fn OSAtomicCompareAndSwap
 
 165 primitives.  There are four versions of each logical operation, depending on
 
 166 whether or not there is a barrier, and whether the return value is the result
 
 167 of the operation (eg,
 
 169 ) or the original value before the operation (eg,
 
 175 must be "naturally aligned", i.e. 32-bit aligned for 32-bit operations and
 
 176 64-bit aligned for 64-bit operations. Note that this is not the default alignment
 
 179 in the iOS ARMv7 ABI, the
 
 180 .Vt OSAtomic_int64_aligned64_t
 
 181 type can be used to declare variables with the required alignment.
 
 184 .Fn OSAtomicCompareAndSwap
 
 193 if the comparison is equal.  The comparison and assignment
 
 194 occur as one atomic operation.
 
 196 .Fn OSAtomicTestAndSet
 
 198 .Fn OSAtomicTestAndClear
 
 199 operate on bit (0x80 >> (
 
 201 & 7)) of byte ((char*)
 
 205 >> 3)).  They set the named bit to either 1 or 0, respectively.
 
 211 function strictly orders memory accesses in a weakly ordered memory model such
 
 212 as with ARM, by creating a barrier.
 
 213 All loads and stores executed in sequential program order before the barrier
 
 214 will complete with respect to the memory coherence mechanism, before any load
 
 215 or store executed after the barrier. Used with an atomic operation, the barrier
 
 216 can be used to create custom synchronization protocols as an alternative to the
 
 217 spinlock or queue/dequeue operations. Note that this barrier does not order
 
 218 uncached loads and stores. On a uniprocessor, the barrier operation is
 
 219 typically optimized into a no-op.
 
 221 The arithmetic operations return the new value, after the operation has been
 
 222 performed. The boolean operations come in two styles, one of which returns the
 
 223 new value, and one of which (the "Orig" versions) returns the old.
 
 224 The compare-and-swap operations return true if the comparison was equal, ie if
 
 225 the swap occured. The bit test and set/clear operations return the original
 
 230 .Xr spinlock_deprecated 3
 
 232 Most of these functions first appeared in Mac OS 10.4 (Tiger).  The "Orig"
 
 233 forms of the boolean operations, the "int", "long" and "ptr" forms of
 
 234 compare-and-swap first appeared in Mac OS 10.5 (Leopard).