Loading...
sys/atomic.3 /dev/null Libc-391
--- /dev/null
+++ Libc/Libc-391/sys/atomic.3
@@ -0,0 +1,154 @@
+.Dd May 26, 2004
+.Dt ATOMIC 3
+.Os Darwin
+.Sh NAME
+.Nm OSAtomicAdd32 ,
+.Nm OSAtomicAdd32Barrier ,
+.Nm OSAtomicIncrement32 ,
+.Nm OSAtomicIncrement32Barrier ,
+.Nm OSAtomicDecrement32 ,
+.Nm OSAtomicDecrement32Barrier ,
+.Nm OSAtomicOr32 ,
+.Nm OSAtomicOr32Barrier ,
+.Nm OSAtomicAnd32 ,
+.Nm OSAtomicAnd32Barrier ,
+.Nm OSAtomicXor32 ,
+.Nm OSAtomicXor32Barrier ,
+.Nm OSAtomicAdd64 ,
+.Nm OSAtomicAdd64Barrier ,
+.Nm OSAtomicIncrement64 ,
+.Nm OSAtomicIncrement64Barrier ,
+.Nm OSAtomicDecrement64 ,
+.Nm OSAtomicDecrement64Barrier ,
+.Nm OSAtomicCompareAndSwap32 ,
+.Nm OSAtomicCompareAndSwap32Barrier ,
+.Nm OSAtomicCompareAndSwap64 ,
+.Nm OSAtomicCompareAndSwap64Barrier ,
+.Nm OSAtomicTestAndSet ,
+.Nm OSAtomicTestAndSetBarrier ,
+.Nm OSAtomicTestAndClear ,
+.Nm OSAtomicTestAndClearBarrier
+.Nd atomic add, increment, decrement, or, and, xor, compare and swap, test and set, and test and clear
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In libkern/OSAtomic.h
+.Ft int32_t
+.Fn OSAtomicAdd32 "int32_t theAmount, int32_t *theValue"
+.Ft int32_t
+.Fn OSAtomicAdd32Barrier "int32_t theAmount, int32_t *theValue"
+.Ft int32_t
+.Fn OSAtomicIncrement32 "int32_t *theValue"
+.Ft int32_t
+.Fn OSAtomicIncrement32Barrier "int32_t *theValue"
+.Ft int32_t
+.Fn OSAtomicDecrement32 "int32_t *theValue"
+.Ft int32_t
+.Fn OSAtomicDecrement32Barrier "int32_t *theValue"
+.Ft int32_t
+.Fn OSAtomicOr32 "uint32_t theMask, uint32_t *theValue"
+.Ft int32_t
+.Fn OSAtomicOr32Barrier "uint32_t theMask, uint32_t *theValue"
+.Ft int32_t
+.Fn OSAtomicAnd32 "uint32_t theMask, uint32_t *theValue"
+.Ft int32_t
+.Fn OSAtomicAnd32Barrier "uint32_t theMask, uint32_t *theValue"
+.Ft int32_t
+.Fn OSAtomicXor32 "uint32_t theMask, uint32_t *theValue"
+.Ft int32_t
+.Fn OSAtomicXor32Barrier "uint32_t theMask, uint32_t *theValue"
+.Ft int64_t
+.Fn OSAtomicAdd64 "int64_t theAmount, int64_t *theValue"
+.Ft int64_t
+.Fn OSAtomicAdd64Barrier "int64_t theAmount, int64_t *theValue"
+.Ft int64_t
+.Fn OSAtomicIncrement64 "int64_t *theValue"
+.Ft int64_t
+.Fn OSAtomicIncrement64Barrier "int64_t *theValue"
+.Ft int64_t
+.Fn OSAtomicDecrement64 "int64_t *theValue"
+.Ft int64_t
+.Fn OSAtomicDecrement64Barrier "int64_t *theValue"
+.Ft bool
+.Fn OSAtomicCompareAndSwap32 "int32_t oldValue" "int32_t newValue" "int32_t *theValue"
+.Ft bool
+.Fn OSAtomicCompareAndSwap32Barrier "int32_t oldValue" "int32_t newValue" "int32_t *theValue"
+.Ft bool
+.Fn OSAtomicCompareAndSwap64 "int64_t oldValue" "int64_t newValue" "int64_t *theValue"
+.Ft bool
+.Fn OSAtomicCompareAndSwap64Barrier "int64_t oldValue" "int64_t newValue" "int64_t *theValue"
+.Ft bool
+.Fn OSAtomicTestAndSet "uint32_t n, void *theAddress"
+.Ft bool
+.Fn OSAtomicTestAndSetBarrier "uint32_t n, void *theAddress"
+.Ft bool
+.Fn OSAtomicTestAndClear "uint32_t n, void *theAddress"
+.Ft bool
+.Fn OSAtomicTestAndClearBarrier "uint32_t n, void *theAddress"
+.Sh DESCRIPTION
+These functions are thread and multiprocessor safe.  For each function, there
+is a version that does and anoother that does not incorporate a memory barrier.
+Barriers strictly order memory access on a weakly-ordered
+architecture such as PPC.  All loads and stores executed in sequential program
+order before the barrier will complete before any load or store executed after
+the barrier.  On a uniprocessor, the barrier operation is typically a nop.
+On a multiprocessor, the barrier can be quite expensive.
+.Pp
+Most code will want to use the barrier functions to insure that memory shared
+between threads is properly synchronized.  For example, if you want to initialize
+a shared data structure and then atomically increment a variable to indicate
+that the initialization is complete, then you MUST use OSAtomicIncrement32Barrier()
+to ensure that the stores to your data structure complete before the atomic add.
+Likewise, the consumer of that data structure MUST use OSAtomicDecrement32Barrier(),
+in order to ensure that their loads of the structure are not executed before
+the atomic decrement.  On the other hand,
+if you are simply incrementing a global counter, then it is safe and potentially much
+faster to use OSAtomicIncrement32().  If you are unsure which version to use, prefer
+the barrier variants as they are safer.
+.Pp
+The logical (and, or, xor) and bit test operations are layered on top of the
+.Fn OSAtomicCompareAndSwap
+primitives.
+.Pp
+The memory address
+.Fa theValue
+must be naturally aligned, ie 32-bit aligned for 32-bit operations and 64-bit
+aligned for 64-bit operations.
+.Pp
+The 64-bit operations are only implemented for
+64-bit processes.
+.Pp
+.Fn OSAtomicCompareAndSwap32
+and
+.Fn OSAtomicCompareAndSwap64
+compare
+.Fa oldValue
+to
+.Fa *theValue ,
+and set
+.Fa *theValue
+to
+.Fa newValue
+if the comparison is equal.  The comparison and assignment
+occur as one atomic operation.
+.Pp
+.Fn OSAtomicTestAndSet
+and
+.Fn OSAtomicTestAndClear
+operate on bit (0x80 >> (
+.Fa n
+& 7)) of byte ((char*)
+.Fa theAddress
++ (
+.Fa n
+>> 3)).  They set the named bit to either 1 or 0, respectively.
+.Fa theAddress
+need not be aligned.
+.Sh RETURN VALUES
+The arithmetic and logical operations return the new value, after the operation has been performed.
+The compare-and-swap operations return true if the comparison was equal, ie if the swap occured.
+The bit test and set/clear operations return the original value of the bit.
+.Sh SEE ALSO
+.Xr atomicqueue 3 ,
+.Xr spinlock 3 ,
+.Xr barrier 3