Veritable Lasagna
An Allocator & Data Structure Library for C.
Loading...
Searching...
No Matches
vl_atomic.h File Reference
#include <stdatomic.h>
#include "vl_numtypes.h"
+ Include dependency graph for vl_atomic.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define VL_ATOMIC   _Atomic
 
#define VL_ATOMIC_TYPEDEF(x)   typedef VL_ATOMIC x
 
#define vlAtomicLoad(ptr)   atomic_load(ptr)
 Performs a generic atomic read operation.
 
#define vlAtomicLoadExplicit(ptr, order)   atomic_load_explicit(ptr, (memory_order)(order))
 Performs a generic atomic read operation.
 
#define vlAtomicStore(ptr, val)   atomic_store(ptr, val)
 Performs a generic atomic write operation.
 
#define vlAtomicStoreExplicit(ptr, order)   atomic_store_explicit(ptr, (memory_order)(order))
 Performs a generic atomic write operation.
 
#define vlAtomicFetchAdd(ptr, arg)   atomic_fetch_add(ptr, arg)
 Performs a generic atomic addition operation.
 
#define vlAtomicFetchSub(ptr, arg)   atomic_fetch_sub(ptr, arg)
 Performs a generic atomic subtraction operation.
 
#define vlAtomicFetchOr(ptr, arg)   atomic_fetch_or(ptr, arg)
 Performs a generic atomic bitwise OR operation.
 
#define vlAtomicFetchXor(ptr, arg)   atomic_fetch_xor(ptr, arg)
 Performs a generic atomic bitwise XOR operation.
 
#define vlAtomicFetchAnd(ptr, arg)   atomic_fetch_and(ptr, arg)
 Performs a generic atomic bitwise AND operation.
 
#define vlAtomicFetchAddExplicit(ptr, arg, order)   atomic_fetch_add_explicit(ptr, arg, (memory_order)(order))
 Performs a generic atomic addition operation.
 
#define vlAtomicFetchSubExplicit(ptr, arg, order)   atomic_fetch_sub_explicit(ptr, arg, (memory_order)(order))
 Performs a generic atomic subtraction operation.
 
#define vlAtomicFetchOrExplicit(ptr, arg, order)   atomic_fetch_or_explicit(ptr, arg, (memory_order)(order))
 Performs a generic atomic bitwise OR operation.
 
#define vlAtomicFetchXorExplicit(ptr, arg, order)   atomic_fetch_xor_explicit(ptr, arg, (memory_order)(order))
 Performs a generic atomic bitwise XOR operation.
 
#define vlAtomicFetchAndExplicit(ptr, arg, order)   atomic_fetch_and_explicit(ptr, arg, (memory_order)(order))
 Performs a generic atomic bitwise AND operation.
 
#define vlAtomicCompareExchangeWeak(ptr, expectedPtr, desired)   atomic_compare_exchange_weak(ptr, expectedPtr, desired)
 Atomically compares the memory at ptr with. If *ptr == *expectedPtr, *ptr = desired.
 
#define vlAtomicCompareExchangeStrong(ptr, expectedPtr, desired)   atomic_compare_exchange_strong(ptr, expectedPtr, desired)
 Atomically compares the memory at ptr with. If *ptr == *expectedPtr, *ptr = desired.
 
#define vlAtomicCompareExchangeWeakExplicit(ptr, expectedPtr, desired, trueOrder, falseOrder)   atomic_compare_exchange_weak_explicit(ptr, expectedPtr, desired, (memory_order)(trueOrder), (memory_order)(falseOrder))
 Atomically compares the memory at ptr with. If *ptr == *expectedPtr, *ptr = desired.
 
#define vlAtomicCompareExchangeStrongExplicit(ptr, expectedPtr, desired, trueOrder, falseOrder)   atomic_compare_exchange_strong_explicit(ptr, expectedPtr, desired, (memory_order)(trueOrder), (memory_order)(falseOrder))
 Atomically compares the memory at ptr with. If *ptr == *expectedPtr, *ptr = desired.
 
#define vlAtomicThreadFence(order)   atomic_thread_fence((memory_order)(order))
 Prepares memory synchronization of non-atomic and relaxed atomic accesses.
 
#define vlAtomicFlagTestAndSet(ptr)   atomic_flag_test_and_set(ptr)
 Atomically sets a flag to true and returns the old value.
 
#define vlAtomicFlagClear(ptr)   atomic_flag_clear(ptr)
 Atomically sets the flag to false.
 
#define vlAtomicFlagTestAndSetExplicit(ptr, order)   atomic_flag_test_and_set_explicit(ptr, (memory_order)(order))
 Atomically sets a flag to true and returns the old value.
 
#define vlAtomicFlagClearExplicit(ptr, order)   atomic_flag_clear_explicit(ptr, (memory_order)(order))
 Atomically sets a flag to false.
 
#define vlAtomicInit(ptr)   atomic_init(ptr)
 Initializes an existing atomic object.
 

Enumerations

enum  vl_memory_order_t {
  VL_MEMORY_ORDER_RELAXED = memory_order_relaxed , VL_MEMORY_ORDER_ACQUIRE = memory_order_acquire , VL_MEMORY_ORDER_RELEASE = memory_order_release , VL_MEMORY_ORDER_ACQ_REL = memory_order_acq_rel ,
  VL_MEMORY_ORDER_SEQ_CST = memory_order_seq_cst
}
 Memory order enumeration. Dictates reordering of memory accesses surrounding and including atomic operations. More...
 

Functions

 VL_ATOMIC_TYPEDEF (vl_bool_t) vl_atomic_bool_t
 
 VL_ATOMIC_TYPEDEF (vl_int_t) vl_atomic_int_t
 
 VL_ATOMIC_TYPEDEF (vl_uint_t) vl_atomic_uint_t
 
 VL_ATOMIC_TYPEDEF (vl_intptr_t) vl_atomic_intptr_t
 
 VL_ATOMIC_TYPEDEF (vl_uintptr_t) vl_atomic_uintptr_t
 
 VL_ATOMIC_TYPEDEF (vl_ularge_t) vl_atomic_ularge_t
 
 VL_ATOMIC_TYPEDEF (vl_usmall_t) vl_atomic_usmall_t
 
 VL_ATOMIC_TYPEDEF (vl_ilarge_t) vl_atomic_ilarge_t
 
 VL_ATOMIC_TYPEDEF (vl_ismall_t) vl_atomic_ismall_t
 
 VL_ATOMIC_TYPEDEF (atomic_flag) vl_atomic_flag_t
 

Macro Definition Documentation

◆ VL_ATOMIC

#define VL_ATOMIC   _Atomic

This header provides a wrapper over the C11 atomic functions, providing an abstraction using the VL number types. Primarily used for "all in one place" documentation, the header is intended to "smooth out" usage of atomic types to conform to the way the rest of the library is documented and used.

◆ VL_ATOMIC_TYPEDEF

#define VL_ATOMIC_TYPEDEF ( x)    typedef VL_ATOMIC x

◆ vlAtomicCompareExchangeStrong

#define vlAtomicCompareExchangeStrong ( ptr,
expectedPtr,
desired )   atomic_compare_exchange_strong(ptr, expectedPtr, desired)

Atomically compares the memory at ptr with. If *ptr == *expectedPtr, *ptr = desired.

If the comparison is true, this performs a read-modify-write operation. Otherwise, this only performs a read operation.

The memory order used for these operations is VL_MEMORY_ORDER_SEQ_CST.

Guarantees that if the comparison fails, it’s because the value has actually changed. Will never fail spuriously.

See also
VL_MEMORY_ORDER_SEQ_CST
Parameters
ptrPointer to the atomic object to perform the operation on.
expectedPtrPointer to do a bitwise comparison with.
desiredValue to copy to the memory pointed to by ptr.
Returns
a boolean indicating the result of the comparison *ptr == *expectedPtr

◆ vlAtomicCompareExchangeStrongExplicit

#define vlAtomicCompareExchangeStrongExplicit ( ptr,
expectedPtr,
desired,
trueOrder,
falseOrder )   atomic_compare_exchange_strong_explicit(ptr, expectedPtr, desired, (memory_order)(trueOrder), (memory_order)(falseOrder))

Atomically compares the memory at ptr with. If *ptr == *expectedPtr, *ptr = desired.

If the comparison is true, this performs a read-modify-write operation. Otherwise, this only performs a read operation.

Guarantees that if the comparison fails, it’s because the value has actually changed. Will never fail spuriously.

See also
VL_MEMORY_ORDER
Parameters
ptrPointer to the atomic object to perform the operation on.
expectedPtrPointer to do a bitwise comparison with.
desiredValue to copy to the memory pointed to by ptr.
trueOrderMemory order used in the case of a true comparison.
falseOrderMemory order used in the case of a false comparison.
Returns
a boolean indicating the result of the comparison *ptr == *expectedPtr

◆ vlAtomicCompareExchangeWeak

#define vlAtomicCompareExchangeWeak ( ptr,
expectedPtr,
desired )   atomic_compare_exchange_weak(ptr, expectedPtr, desired)

Atomically compares the memory at ptr with. If *ptr == *expectedPtr, *ptr = desired.

If the comparison is true, this performs a read-modify-write operation. Otherwise, this only performs a read operation.

The memory order used for these operations is VL_MEMORY_ORDER_SEQ_CST.

The weak variant of an atomic compare-exchange is allowed to fail spuriously. That is, act as if *ptr != *expectedPtr, even if they are equal. This variant likely offers better performance in loops.

See also
VL_MEMORY_ORDER_SEQ_CST
Parameters
ptrPointer to the atomic object to perform the operation on.
expectedPtrPointer to do a bitwise comparison with.
desiredValue to copy to the memory pointed to by ptr.
Returns
a boolean indicating the result of the comparison *ptr == *expectedPtr

◆ vlAtomicCompareExchangeWeakExplicit

#define vlAtomicCompareExchangeWeakExplicit ( ptr,
expectedPtr,
desired,
trueOrder,
falseOrder )   atomic_compare_exchange_weak_explicit(ptr, expectedPtr, desired, (memory_order)(trueOrder), (memory_order)(falseOrder))

Atomically compares the memory at ptr with. If *ptr == *expectedPtr, *ptr = desired.

If the comparison is true, this performs a read-modify-write operation. Otherwise, this only performs a read operation.

The weak variant of an atomic compare-exchange is allowed to fail spuriously. That is, act as if *ptr != *expectedPtr, even if they are equal. This variant likely offers better performance in loops.

See also
VL_MEMORY_ORDER
Parameters
ptrPointer to the atomic object to perform the operation on.
expectedPtrPointer to do a bitwise comparison with.
desiredValue to copy to the memory pointed to by ptr.
trueOrderMemory order used in the case of a true comparison.
falseOrderMemory order used in the case of a false comparison.
Returns
a boolean indicating the result of the comparison *ptr == *expectedPtr

◆ vlAtomicFetchAdd

#define vlAtomicFetchAdd ( ptr,
arg )   atomic_fetch_add(ptr, arg)

Performs a generic atomic addition operation.

The memory order used for this operation is VL_MEMORY_ORDER_SEQ_CST.

See also
VL_MEMORY_ORDER_SEQ_CST
Parameters
ptrPointer to the atomic object to perform the operation on.
Returns
The previous value held by the atomic object referred to by the specified pointer.

◆ vlAtomicFetchAddExplicit

#define vlAtomicFetchAddExplicit ( ptr,
arg,
order )   atomic_fetch_add_explicit(ptr, arg, (memory_order)(order))

Performs a generic atomic addition operation.

See also
VL_MEMORY_ORDER
Parameters
ptrPointer to the atomic object to access
orderWhich memory ordering scheme to use for the operation.
Returns
The previous value held by the atomic object referred to by the specified pointer.

◆ vlAtomicFetchAnd

#define vlAtomicFetchAnd ( ptr,
arg )   atomic_fetch_and(ptr, arg)

Performs a generic atomic bitwise AND operation.

The memory order used for this operation is VL_MEMORY_ORDER_SEQ_CST.

See also
VL_MEMORY_ORDER_SEQ_CST
Parameters
ptrPointer to the atomic object to perform the operation on.
Returns
The previous value held by the atomic object referred to by the specified pointer.

◆ vlAtomicFetchAndExplicit

#define vlAtomicFetchAndExplicit ( ptr,
arg,
order )   atomic_fetch_and_explicit(ptr, arg, (memory_order)(order))

Performs a generic atomic bitwise AND operation.

See also
VL_MEMORY_ORDER
Parameters
ptrPointer to the atomic object to access
orderWhich memory ordering scheme to use for the operation.
Returns
The previous value held by the atomic object referred to by the specified pointer.

◆ vlAtomicFetchOr

#define vlAtomicFetchOr ( ptr,
arg )   atomic_fetch_or(ptr, arg)

Performs a generic atomic bitwise OR operation.

The memory order used for this operation is VL_MEMORY_ORDER_SEQ_CST.

See also
VL_MEMORY_ORDER_SEQ_CST
Parameters
ptrPointer to the atomic object to perform the operation on.
Returns
The previous value held by the atomic object referred to by the specified pointer.

◆ vlAtomicFetchOrExplicit

#define vlAtomicFetchOrExplicit ( ptr,
arg,
order )   atomic_fetch_or_explicit(ptr, arg, (memory_order)(order))

Performs a generic atomic bitwise OR operation.

See also
VL_MEMORY_ORDER
Parameters
ptrPointer to the atomic object to access
orderWhich memory ordering scheme to use for the operation.
Returns
The previous value held by the atomic object referred to by the specified pointer.

◆ vlAtomicFetchSub

#define vlAtomicFetchSub ( ptr,
arg )   atomic_fetch_sub(ptr, arg)

Performs a generic atomic subtraction operation.

The memory order used for this operation is VL_MEMORY_ORDER_SEQ_CST.

See also
VL_MEMORY_ORDER_SEQ_CST
Parameters
ptrPointer to the atomic object to perform the operation on.
Returns
The previous value held by the atomic object referred to by the specified pointer.

◆ vlAtomicFetchSubExplicit

#define vlAtomicFetchSubExplicit ( ptr,
arg,
order )   atomic_fetch_sub_explicit(ptr, arg, (memory_order)(order))

Performs a generic atomic subtraction operation.

See also
VL_MEMORY_ORDER
Parameters
ptrPointer to the atomic object to access
orderWhich memory ordering scheme to use for the operation.
Returns
The previous value held by the atomic object referred to by the specified pointer.

◆ vlAtomicFetchXor

#define vlAtomicFetchXor ( ptr,
arg )   atomic_fetch_xor(ptr, arg)

Performs a generic atomic bitwise XOR operation.

The memory order used for this operation is VL_MEMORY_ORDER_SEQ_CST.

See also
VL_MEMORY_ORDER_SEQ_CST
Parameters
ptrPointer to the atomic object to perform the operation on.
Returns
The previous value held by the atomic object referred to by the specified pointer.

◆ vlAtomicFetchXorExplicit

#define vlAtomicFetchXorExplicit ( ptr,
arg,
order )   atomic_fetch_xor_explicit(ptr, arg, (memory_order)(order))

Performs a generic atomic bitwise XOR operation.

See also
VL_MEMORY_ORDER
Parameters
ptrPointer to the atomic object to access
orderWhich memory ordering scheme to use for the operation.
Returns
The previous value held by the atomic object referred to by the specified pointer.

◆ vlAtomicFlagClear

#define vlAtomicFlagClear ( ptr)    atomic_flag_clear(ptr)

Atomically sets the flag to false.

The memory order used for this operation is VL_MEMORY_ORDER_SEQ_CST.

See also
VL_MEMORY_ORDER_SEQ_CST
Parameters
ptrPointer to the atomic flag instance

◆ vlAtomicFlagClearExplicit

#define vlAtomicFlagClearExplicit ( ptr,
order )   atomic_flag_clear_explicit(ptr, (memory_order)(order))

Atomically sets a flag to false.

See also
VL_MEMORY_ORDER
Parameters
ptrPointer to the atomic flag instance
orderMemory order used for the operation.
Returns
the previous value of the flag pointer to by ptr

◆ vlAtomicFlagTestAndSet

#define vlAtomicFlagTestAndSet ( ptr)    atomic_flag_test_and_set(ptr)

Atomically sets a flag to true and returns the old value.

The memory order used for this operation is VL_MEMORY_ORDER_SEQ_CST.

See also
VL_MEMORY_ORDER_SEQ_CST
Parameters
ptrPointer to the atomic flag instance
Returns
the previous value of the flag pointer to by ptr

◆ vlAtomicFlagTestAndSetExplicit

#define vlAtomicFlagTestAndSetExplicit ( ptr,
order )   atomic_flag_test_and_set_explicit(ptr, (memory_order)(order))

Atomically sets a flag to true and returns the old value.

See also
VL_MEMORY_ORDER
Parameters
ptrPointer to the atomic flag instance
orderMemory order used for the operation.
Returns
the previous value of the flag pointer to by ptr

◆ vlAtomicInit

#define vlAtomicInit ( ptr)    atomic_init(ptr)

Initializes an existing atomic object.

This is the only way to properly initialize dynamically-allocated atomic objects. Atomic objects allocated on the stack and directly assigned do not need to be initialized.

\ptr Pointer to the atomic object to initialize.

◆ vlAtomicLoad

#define vlAtomicLoad ( ptr)    atomic_load(ptr)

Performs a generic atomic read operation.

This operation will use the VL_MEMORY_ORDER_SEQ_CST memory order.

See also
VL_MEMORY_ORDER_SEQ_CST
Parameters
ptrPointer to the atomic object to access
Returns
Non-atomic value at the specified pointer.

◆ vlAtomicLoadExplicit

#define vlAtomicLoadExplicit ( ptr,
order )   atomic_load_explicit(ptr, (memory_order)(order))

Performs a generic atomic read operation.

The memory order used must be among the following:

See also
VL_MEMORY_ORDER_RELAXED
VL_MEMORY_ORDER_CONSUME
VL_MEMORY_ORDER_ACQUIRE
VL_MEMORY_ORDER_SEQ_CST
Note
Using a memory order not listed here will result in undefined behavior.
Parameters
ptrPointer to the atomic object to access
orderWhich memory ordering scheme to use for the operation.
Returns
Non-atomic value at the specified pointer.

◆ vlAtomicStore

#define vlAtomicStore ( ptr,
val )   atomic_store(ptr, val)

Performs a generic atomic write operation.

This operation will use the VL_MEMORY_ORDER_SEQ_CST memory order.

See also
VL_MEMORY_ORDER_SEQ_CST
Parameters
ptrPointer to the atomic object to write.
valValue to store.

◆ vlAtomicStoreExplicit

#define vlAtomicStoreExplicit ( ptr,
order )   atomic_store_explicit(ptr, (memory_order)(order))

Performs a generic atomic write operation.

The memory order used must be among the following:

See also
VL_MEMORY_ORDER_RELAXED
VL_MEMORY_ORDER_RELEASE
VL_MEMORY_ORDER_ACQUIRE
VL_MEMORY_ORDER_SEQ_CST
Note
Using a memory order not listed here will result in undefined behavior.
Parameters
ptrPointer to the atomic object to access
orderWhich memory ordering scheme to use for the operation.

◆ vlAtomicThreadFence

#define vlAtomicThreadFence ( order)    atomic_thread_fence((memory_order)(order))

Prepares memory synchronization of non-atomic and relaxed atomic accesses.

See also
VL_MEMORY_ORDER
Parameters
orderMemory order used for the current context.

Enumeration Type Documentation

◆ vl_memory_order_t

Memory order enumeration. Dictates reordering of memory accesses surrounding and including atomic operations.

Documentation of different orders taken from the following webpage: https://en.cppreference.com/w/c/atomic/memory_order

Enumerator
VL_MEMORY_ORDER_RELAXED 

Relaxed operation: there are no synchronization or ordering constraints imposed on other reads or writes, only this operation's atomicity is guaranteed.

Useful for independent, atomic counters.

VL_MEMORY_ORDER_ACQUIRE 

A load operation with this memory order performs the acquire operation on the affected memory location: no reads or writes in the current thread can be reordered before this load. All writes in other threads that release the same atomic variable are visible in the current thread.

Useful for the consumer side of producer-consumer synchronization.

VL_MEMORY_ORDER_RELEASE 

A store operation with this memory order performs the release operation: no reads or writes in the current thread can be reordered after this store. All writes in the current thread are visible in other threads that acquire the same atomic variable and writes that carry a dependency into the atomic variable become visible in other threads that consume the same atomic.

Useful for the producer side of producer-consumer synchronization.

VL_MEMORY_ORDER_ACQ_REL 

A read-modify-write operation with this memory order is both an acquire operation and a release operation. No memory reads or writes in the current thread can be reordered before the load, nor after the store. All writes in other threads that release the same atomic variable are visible before the modification and the modification is visible in other threads that acquire the same atomic variable.

Useful for read-modify-write operations, specifically in lock-free data structures.

VL_MEMORY_ORDER_SEQ_CST 

A load operation with this memory order performs an acquire operation, a store performs a release operation, and read-modify-write performs both an acquire operation and a release operation, plus a single total order exists in which all threads observe all modifications in the same order.

Useful for the maximum amount of safety, probably at the cost of performance.

Function Documentation

◆ VL_ATOMIC_TYPEDEF() [1/10]

VL_ATOMIC_TYPEDEF ( atomic_flag )

◆ VL_ATOMIC_TYPEDEF() [2/10]

VL_ATOMIC_TYPEDEF ( vl_bool_t )

◆ VL_ATOMIC_TYPEDEF() [3/10]

VL_ATOMIC_TYPEDEF ( vl_ilarge_t )

◆ VL_ATOMIC_TYPEDEF() [4/10]

VL_ATOMIC_TYPEDEF ( vl_int_t )

◆ VL_ATOMIC_TYPEDEF() [5/10]

VL_ATOMIC_TYPEDEF ( vl_intptr_t )

◆ VL_ATOMIC_TYPEDEF() [6/10]

VL_ATOMIC_TYPEDEF ( vl_ismall_t )

◆ VL_ATOMIC_TYPEDEF() [7/10]

VL_ATOMIC_TYPEDEF ( vl_uint_t )

◆ VL_ATOMIC_TYPEDEF() [8/10]

VL_ATOMIC_TYPEDEF ( vl_uintptr_t )

◆ VL_ATOMIC_TYPEDEF() [9/10]

VL_ATOMIC_TYPEDEF ( vl_ularge_t )

◆ VL_ATOMIC_TYPEDEF() [10/10]

VL_ATOMIC_TYPEDEF ( vl_usmall_t )