CX Framework
Cross-platform C utility framework
Loading...
Searching...
No Matches
Reader-Writer Lock

Data Structures

struct  RWLock
 

Macros

#define RWLOCK_READER_MAX   4095
 Maximum number of concurrent readers.
 
#define RWLOCK_READWAIT_MAX   2047
 Maximum number of waiting readers.
 
#define RWLOCK_WRITER_MAX   511
 Maximum number of writers (active + pending)
 
#define rwlockInit(l, ...)   _rwlockInit(l, opt_flags(__VA_ARGS__))
 
#define withReadLock(l)   blkWrap (rwlockAcquireRead(l), rwlockReleaseRead(l))
 
#define withWriteLock(l)   blkWrap (rwlockAcquireWrite(l), rwlockReleaseWrite(l))
 

Typedefs

typedef struct RWLock RWLock
 

Enumerations

enum  RWLOCK_Flags { RWLOCK_NoSpin = 1 }
 Reader-writer lock initialization flags. More...
 

Functions

bool rwlockTryAcquireReadTimeout (RWLock *l, int64 timeout)
 
bool rwlockTryAcquireWriteTimeout (RWLock *l, int64 timeout)
 
bool rwlockTryAcquireRead (RWLock *l)
 
bool rwlockTryAcquireWrite (RWLock *l)
 
void rwlockAcquireRead (RWLock *l)
 
void rwlockAcquireWrite (RWLock *l)
 
bool rwlockReleaseRead (RWLock *l)
 
bool rwlockReleaseWrite (RWLock *l)
 
bool rwlockDowngradeWrite (RWLock *l)
 
void rwlockDestroy (RWLock *l)
 

Detailed Description

Reader-writer locks for shared read access with exclusive write access.

RWLock allows multiple threads to hold read locks simultaneously, but only one thread can hold a write lock at a time (with no concurrent readers). This is ideal for data structures with frequent reads and infrequent writes.

Implementation details:

Basic usage:

RWLock lock;
rwlockInit(&lock);
// Multiple readers can acquire simultaneously
// read data
// Writers have exclusive access
// modify data
bool rwlockReleaseWrite(RWLock *l)
#define rwlockInit(l,...)
Definition rwlock.h:105
void rwlockAcquireWrite(RWLock *l)
Definition rwlock.h:249
bool rwlockReleaseRead(RWLock *l)
Definition rwlock.h:277
void rwlockDestroy(RWLock *l)
void rwlockAcquireRead(RWLock *l)
Definition rwlock.h:204

Scoped locking:

withReadLock(&lock) {
// read access - lock released automatically
}
withWriteLock(&lock) {
// write access - lock released automatically
}
#define withWriteLock(l)
Definition rwlock.h:222
#define withReadLock(l)
Definition rwlock.h:215

Macro Definition Documentation

◆ rwlockInit

#define rwlockInit (   l,
  ... 
)    _rwlockInit(l, opt_flags(__VA_ARGS__))

void rwlockInit(RWLock *l, [flags])

Initialize a reader-writer lock for use.

Must be called before using any other rwlock operations.

Parameters
lPointer to uninitialized RWLock structure
...(flags) Optional RWLOCK_Flags (e.g., RWLOCK_NoSpin)

Definition at line 105 of file rwlock.h.

◆ withReadLock

#define withReadLock (   l)    blkWrap (rwlockAcquireRead(l), rwlockReleaseRead(l))

Execute a block with automatic read lock acquisition and release

Acquires a read lock before executing the following block, and automatically releases it when the block exits.

Parameters
lRWLock to acquire for reading

Definition at line 215 of file rwlock.h.

◆ withWriteLock

#define withWriteLock (   l)    blkWrap (rwlockAcquireWrite(l), rwlockReleaseWrite(l))

Execute a block with automatic write lock acquisition and release

Acquires a write lock before executing the following block, and automatically releases it when the block exits.

Parameters
lRWLock to acquire for writing

Definition at line 222 of file rwlock.h.

Typedef Documentation

◆ RWLock

typedef struct RWLock RWLock

Reader-writer lock synchronization primitive

Allows multiple concurrent readers or a single exclusive writer. The state field packs reader count (12 bits), waiting reader count (11 bits), and writer count (9 bits) into a single 32-bit atomic.

Enumeration Type Documentation

◆ RWLOCK_Flags

Reader-writer lock initialization flags.

Enumerator
RWLOCK_NoSpin 

Disable adaptive spinning, use kernel futex immediately.

Definition at line 63 of file rwlock.h.

Function Documentation

◆ rwlockAcquireRead()

void rwlockAcquireRead ( RWLock l)
inline

Acquire a read lock, blocking until available

Blocks the calling thread until shared read access can be acquired. This is equivalent to rwlockTryAcquireReadTimeout() with timeForever.

Parameters
lRWLock to acquire for reading

Definition at line 204 of file rwlock.h.

References relFatalError, rwlockTryAcquireReadTimeout(), and timeForever.

◆ rwlockAcquireWrite()

void rwlockAcquireWrite ( RWLock l)
inline

Acquire a write lock, blocking until available

Blocks the calling thread until exclusive write access can be acquired. This is equivalent to rwlockTryAcquireWriteTimeout() with timeForever.

Parameters
lRWLock to acquire for writing

Definition at line 249 of file rwlock.h.

References relFatalError, rwlockTryAcquireWriteTimeout(), and timeForever.

◆ rwlockDestroy()

void rwlockDestroy ( RWLock l)

Destroy a reader-writer lock and release its resources

Cleans up the RWLock after use. The lock must not be held when destroyed. After destruction, the lock must be reinitialized before it can be used again.

Parameters
lRWLock to destroy

◆ rwlockDowngradeWrite()

bool rwlockDowngradeWrite ( RWLock l)

Atomically downgrade a write lock to a read lock

Converts exclusive write access to shared read access without releasing the lock. This operation is guaranteed not to block. Useful when transitioning from a write operation to a read operation without allowing other writers to interfere.

Parameters
lRWLock currently held for writing
Returns
true on success

◆ rwlockReleaseRead()

bool rwlockReleaseRead ( RWLock l)
inline

Release a previously acquired read lock

Releases shared read access. If this was the last reader and writers are waiting, one writer will be awakened.

Parameters
lRWLock to release
Returns
true on success

Definition at line 277 of file rwlock.h.

References devAssert, and devVerify.

◆ rwlockReleaseWrite()

bool rwlockReleaseWrite ( RWLock l)

Release a previously acquired write lock

Releases exclusive write access, allowing waiting readers or writers to acquire the lock.

Parameters
lRWLock to release
Returns
true on success

◆ rwlockTryAcquireRead()

bool rwlockTryAcquireRead ( RWLock l)
inline

Attempt to acquire a read lock without blocking

Tries to acquire shared read access immediately, returning false if not possible. Does not block or wait.

Parameters
lRWLock to acquire for reading
Returns
true if the read lock was acquired, false if writers are active/pending or maximum readers reached

Definition at line 142 of file rwlock.h.

References RWLOCK_READER_MAX.

◆ rwlockTryAcquireReadTimeout()

bool rwlockTryAcquireReadTimeout ( RWLock l,
int64  timeout 
)

Attempt to acquire a read lock with a timeout

Tries to acquire shared read access, waiting up to the specified timeout. Multiple threads can hold read locks simultaneously. New read acquisitions are blocked if writers are pending (writer preference).

Parameters
lRWLock to acquire for reading
timeoutMaximum time to wait in nanoseconds (use timeForever for infinite)
Returns
true if the read lock was acquired, false if timeout expired or maximum readers reached

Referenced by rwlockAcquireRead().

◆ rwlockTryAcquireWrite()

bool rwlockTryAcquireWrite ( RWLock l)
inline

Attempt to acquire a write lock without blocking

Tries to acquire exclusive write access immediately, returning false if not possible. Does not block or wait.

Parameters
lRWLock to acquire for writing
Returns
true if the write lock was acquired, false if any readers or writers are active

Definition at line 175 of file rwlock.h.

References RWLOCK_WRITER_MAX.

◆ rwlockTryAcquireWriteTimeout()

bool rwlockTryAcquireWriteTimeout ( RWLock l,
int64  timeout 
)

Attempt to acquire a write lock with a timeout

Tries to acquire exclusive write access, waiting up to the specified timeout. Only one writer can hold the lock, and no readers can be active when a write lock is held.

Parameters
lRWLock to acquire for writing
timeoutMaximum time to wait in nanoseconds (use timeForever for infinite)
Returns
true if the write lock was acquired, false if timeout expired or maximum writers reached

Referenced by rwlockAcquireWrite().