objc

Data Structures | Macros | Functions
Synchronization Primitives

Implements various synchronization methods for thread-safe operations. More...

Collaboration diagram for Synchronization Primitives:

Data Structures

struct  sys_atomic_t
 Underlying atomic uint32_t value. More...
 
struct  sys_mutex_t
 Mutex context structure. More...
 
struct  sys_cond_t
 Condition variable context structure. More...
 
struct  sys_waitgroup_t
 Waitgroup context structure. More...
 

Macros

#define SYS_MUTEX_CTX_SIZE   64
 Buffer size for platform-specific mutex context dataAdjust based on platform requirements.
 
#define SYS_COND_CTX_SIZE   64
 Buffer size for platform-specific condition variable context dataAdjust based on platform requirements.
 
#define SYS_WAITGROUP_CTX_SIZE   128
 Buffer size for platform-specific waitgroup context dataAdjust based on platform requirements.
 

Functions

struct sys_atomic_t __attribute__ ((aligned(4)))
 Underlying atomic uint32_t value. More...
 
static void sys_atomic_init (sys_atomic_t *a, uint32_t initial)
 Initialize an atomic with an initial value. More...
 
static uint32_t sys_atomic_get (const sys_atomic_t *a)
 Load the current value atomically. More...
 
static void sys_atomic_set (sys_atomic_t *a, uint32_t v)
 Store a new value atomically. More...
 
static uint32_t sys_atomic_inc (sys_atomic_t *a)
 Atomically increment and return the new value. More...
 
static uint32_t sys_atomic_dec (sys_atomic_t *a)
 Atomically decrement and return the new value. More...
 
static void sys_atomic_set_bits (sys_atomic_t *a, uint32_t mask)
 Atomically set bits (OR with mask). More...
 
static void sys_atomic_clear_bits (sys_atomic_t *a, uint32_t mask)
 Atomically clear bits (AND with ~mask). More...
 
sys_mutex_t sys_mutex_init (void)
 Initialize a new mutex. More...
 
bool sys_mutex_lock (sys_mutex_t *mutex)
 Lock a mutex, by blocking. More...
 
bool sys_mutex_trylock (sys_mutex_t *mutex)
 Try to lock a mutex. More...
 
bool sys_mutex_unlock (sys_mutex_t *mutex)
 Unlock a mutex. More...
 
void sys_mutex_finalize (sys_mutex_t *mutex)
 Finalize and cleanup a mutex. More...
 
sys_cond_t sys_cond_init (void)
 Initialize a new condition variable. More...
 
bool sys_cond_wait (sys_cond_t *cond, sys_mutex_t *mutex)
 Wait on a condition variable. More...
 
bool sys_cond_timedwait (sys_cond_t *cond, sys_mutex_t *mutex, uint32_t timeout_ms)
 Wait on a condition variable with timeout. More...
 
bool sys_cond_signal (sys_cond_t *cond)
 Signal one waiting thread. More...
 
bool sys_cond_broadcast (sys_cond_t *cond)
 Signal all waiting threads. More...
 
void sys_cond_finalize (sys_cond_t *cond)
 Finalize and cleanup a condition variable. More...
 
sys_waitgroup_t sys_waitgroup_init (void)
 Initialize a new waitgroup. More...
 
bool sys_waitgroup_add (sys_waitgroup_t *wg, int delta)
 Add to the waitgroup counter. More...
 
bool sys_waitgroup_done (sys_waitgroup_t *wg)
 Decrement the waitgroup counter. More...
 
void sys_waitgroup_finalize (sys_waitgroup_t *wg)
 Finalize and cleanup a waitgroup - wait for completion then cleanup. More...
 

Detailed Description

Implements various synchronization methods for thread-safe operations.

Three main synchronization primitives are provided. A mutual exclusion type (or "mutex") is used to protect shared resources from concurrent access. You will need one mutex for each shared resource that requires protection against concurrent access. You should always lock the mutex before accessing the shared resource, and unlock it after you are done.

Condition variables allow threads to wait for certain conditions to be met before proceeding. One thread can signal a condition variable, and other threads can wait on it. This is useful for implementing producer/consumer patterns, where one thread produces data and another thread consumes it.

Waitgroups allow one thread to wait for a collection of threads to finish executing. This is useful for synchronizing the completion of multiple threads before proceeding. You can add threads to a waitgroup, and then wait for all of them to complete. This is useful for ensuring that all threads have finished their work before proceeding.

Function Documentation

◆ __attribute__()

struct sys_atomic_t __attribute__ ( (aligned(4))  )

Underlying atomic uint32_t value.

Do not access the value directly; use the sys_atomic_* APIs. in order to maintain thread safety.

◆ sys_atomic_clear_bits()

static void sys_atomic_clear_bits ( sys_atomic_t a,
uint32_t  mask 
)
inlinestatic

Atomically clear bits (AND with ~mask).

Parameters
aPointer to the atomic value (must be non-NULL).
maskBit mask of bits to clear.

Performs a relaxed fetch-and with the complement of mask; no ordering is implied.

Definition at line 132 of file atomic.h.

132  {
133  (void)__atomic_fetch_and(&a->value, ~mask, __ATOMIC_RELAXED);
134 }

◆ sys_atomic_dec()

static uint32_t sys_atomic_dec ( sys_atomic_t a)
inlinestatic

Atomically decrement and return the new value.

Parameters
aPointer to the atomic value (must be non-NULL).
Returns
The decremented value after the operation.

This uses relaxed ordering and wraps modulo 2^32.

Definition at line 105 of file atomic.h.

105  {
106  return __atomic_sub_fetch(&a->value, 1, __ATOMIC_RELAXED);
107 }

◆ sys_atomic_get()

static uint32_t sys_atomic_get ( const sys_atomic_t a)
inlinestatic

Load the current value atomically.

Parameters
aPointer to the atomic value (must be non-NULL).
Returns
The current 32-bit value.

This is a relaxed load; it does not establish synchronization with other memory operations. If you need acquire semantics, introduce an explicit fence in the caller.

Definition at line 65 of file atomic.h.

65  {
66  return __atomic_load_n(&a->value, __ATOMIC_RELAXED);
67 }

◆ sys_atomic_inc()

static uint32_t sys_atomic_inc ( sys_atomic_t a)
inlinestatic

Atomically increment and return the new value.

Parameters
aPointer to the atomic value (must be non-NULL).
Returns
The incremented value after the operation.

This uses relaxed ordering and wraps modulo 2^32.

Definition at line 92 of file atomic.h.

92  {
93  return __atomic_add_fetch(&a->value, 1, __ATOMIC_RELAXED);
94 }

◆ sys_atomic_init()

static void sys_atomic_init ( sys_atomic_t a,
uint32_t  initial 
)
inlinestatic

Initialize an atomic with an initial value.

Parameters
aPointer to the atomic value to initialize (must be non-NULL).
initialThe initial 32-bit value to store.

This performs a relaxed store; it does not impose ordering with other memory operations. Use only as an initialization step before the atomic is shared with other threads.

Definition at line 50 of file atomic.h.

50  {
51  __atomic_store_n(&a->value, initial, __ATOMIC_RELAXED);
52 }

◆ sys_atomic_set()

static void sys_atomic_set ( sys_atomic_t a,
uint32_t  v 
)
inlinestatic

Store a new value atomically.

Parameters
aPointer to the atomic value (must be non-NULL).
vThe value to store.

This is a relaxed store; it does not order or publish other writes. If you need release semantics, introduce an explicit fence in the caller.

Definition at line 79 of file atomic.h.

79  {
80  __atomic_store_n(&a->value, v, __ATOMIC_RELAXED);
81 }

◆ sys_atomic_set_bits()

static void sys_atomic_set_bits ( sys_atomic_t a,
uint32_t  mask 
)
inlinestatic

Atomically set bits (OR with mask).

Parameters
aPointer to the atomic value (must be non-NULL).
maskBit mask of bits to set.

Performs a relaxed fetch-or; no ordering is implied.

Definition at line 118 of file atomic.h.

118  {
119  (void)__atomic_fetch_or(&a->value, mask, __ATOMIC_RELAXED);
120 }

◆ sys_cond_broadcast()

bool sys_cond_broadcast ( sys_cond_t cond)

Signal all waiting threads.

Parameters
condPointer to the condition variable to broadcast
Returns
true if successful, false on error

Wakes up all threads waiting on the condition variable. If no threads are waiting, this function has no effect. The associated mutex should be locked when calling this function for predictable behavior.

◆ sys_cond_finalize()

void sys_cond_finalize ( sys_cond_t cond)

Finalize and cleanup a condition variable.

Parameters
condPointer to the condition variable to finalize

Releases all resources associated with the condition variable and renders it unusable. No threads should be waiting on the condition variable when this function is called.

◆ sys_cond_init()

sys_cond_t sys_cond_init ( void  )

Initialize a new condition variable.

Returns
Initialized condition variable structure

Creates and initializes a new condition variable for thread synchronization. The condition variable is ready for use with wait/signal operations. The returned condition variable must be finalized with sys_cond_finalize()

◆ sys_cond_signal()

bool sys_cond_signal ( sys_cond_t cond)

Signal one waiting thread.

Parameters
condPointer to the condition variable to signal
Returns
true if successful, false on error

Wakes up one thread waiting on the condition variable. If no threads are waiting, this function has no effect. The associated mutex should be locked when calling this function for predictable behavior.

◆ sys_cond_timedwait()

bool sys_cond_timedwait ( sys_cond_t cond,
sys_mutex_t mutex,
uint32_t  timeout_ms 
)

Wait on a condition variable with timeout.

Parameters
condPointer to the condition variable to wait on
mutexPointer to the mutex that must be locked by the calling thread
timeout_msTimeout in milliseconds (0 = no timeout)
Returns
true if signaled, false if timeout or error

Like sys_cond_wait() but returns after timeout_ms milliseconds if not signaled. Returns true if signaled, false if timeout or error occurred.

◆ sys_cond_wait()

bool sys_cond_wait ( sys_cond_t cond,
sys_mutex_t mutex 
)

Wait on a condition variable.

Parameters
condPointer to the condition variable to wait on
mutexPointer to the mutex that must be locked by the calling thread
Returns
true if the wait completed successfully, false on error

Atomically releases the mutex and waits for the condition variable to be signaled. Upon return, the mutex is reacquired. The mutex must be locked by the calling thread before calling this function.

◆ sys_mutex_finalize()

void sys_mutex_finalize ( sys_mutex_t mutex)

Finalize and cleanup a mutex.

Parameters
mutexPointer to the mutex to finalize

Releases all resources associated with the mutex and renders it unusable. The mutex should not be locked when this function is called.

◆ sys_mutex_init()

sys_mutex_t sys_mutex_init ( void  )

Initialize a new mutex.

Returns
Initialized mutex structure

Creates and initializes a new mutex for thread synchronization. The mutex is initially unlocked and ready for use. The returned mutex must be finalized with sys_mutex_finalize()

◆ sys_mutex_lock()

bool sys_mutex_lock ( sys_mutex_t mutex)

Lock a mutex, by blocking.

Parameters
mutexPointer to the mutex to lock
Returns
true if the mutex was successfully locked, false on error

Attempts to lock the specified mutex. If the mutex is already locked by another thread, this function will block until the mutex becomes available. Every successful lock must be paired with sys_mutex_unlock() Attempting to lock an already owned mutex may result in deadlock

◆ sys_mutex_trylock()

bool sys_mutex_trylock ( sys_mutex_t mutex)

Try to lock a mutex.

Parameters
mutexPointer to the mutex to try locking
Returns
true if the mutex was successfully locked, false if already locked or on error

Attempts to lock the specified mutex without blocking. If the mutex is already locked, this function returns immediately with false. Every successful trylock must be paired with sys_mutex_unlock()

◆ sys_mutex_unlock()

bool sys_mutex_unlock ( sys_mutex_t mutex)

Unlock a mutex.

Parameters
mutexPointer to the mutex to unlock
Returns
true if the mutex was successfully unlocked, false on error

Releases a previously acquired mutex lock, allowing other threads to acquire the mutex. Only the thread that locked the mutex should unlock it.

◆ sys_waitgroup_add()

bool sys_waitgroup_add ( sys_waitgroup_t wg,
int  delta 
)

Add to the waitgroup counter.

Parameters
wgPointer to the waitgroup
deltaNumber to add to the counter (must be positive)
Returns
true if successful, false on error

Increments the waitgroup counter by delta. This should be called before starting goroutines that the waitgroup should wait for.

Examples:
clock/main.c.

◆ sys_waitgroup_done()

bool sys_waitgroup_done ( sys_waitgroup_t wg)

Decrement the waitgroup counter.

Parameters
wgPointer to the waitgroup
Returns
true if successful, false on error

Decrements the waitgroup counter by 1. This should be called when a goroutine finishes its work. If the counter reaches 0, all threads waiting on sys_waitgroup_wait() will be woken up.

Examples:
clock/main.c.

◆ sys_waitgroup_finalize()

void sys_waitgroup_finalize ( sys_waitgroup_t wg)

Finalize and cleanup a waitgroup - wait for completion then cleanup.

Parameters
wgPointer to the waitgroup to finalize

Blocks until the waitgroup counter reaches 0, then releases all resources associated with the waitgroup and renders it unusable. The waitgroup counter should reach 0 through done() calls from worker threads.

Examples:
clock/main.c.

◆ sys_waitgroup_init()

sys_waitgroup_t sys_waitgroup_init ( void  )

Initialize a new waitgroup.

Returns
Initialized waitgroup structure

Creates and initializes a new waitgroup for thread synchronization. The waitgroup counter starts at 0. The returned waitgroup must be finalized with sys_waitgroup_finalize()

Examples:
clock/main.c.