CnxSharedMutex module
CnxSharedMutex provides several higher-level reader-writer mutex types comparable to those provided in C++'s <shared_mutex>, to make working with multi-threaded code simpler and easier.
A shared mutex is a reader-writer mutex that allows for different categories of locking, either exclusively, for writing/mutation, or non-exclusively/shared for reading. This can allow for significant throughput improvements in applications where many threads need to read the same data often, but only a comparatively small number of threads will ever try to mutate the data, by allowing the reading threads to share a lock on the mutex, while forcing a writing thread to gain an exclusive lock on the mutex to perform its mutation.
Example:
// MyThing.h #include <Cnx/sync/SharedMutex.h> static MyType my_very_important_thing; static CnxSharedMutex* my_thing_mutex; void init_my_thing(void); void update_my_thing(u64 value); u64 get_value_from_my_thing(void); // MyThing.c #include <Cnx/Allocators.h> #include "MyThing.h" void init_my_thing(void) { if(my_thing_mutex == nullptr) { my_thing_mutex = cnx_allocator_allocate_t(CnxSharedMutex, DEFAULT_ALLOCATOR); *my_thing_mutex = cnx_shared_mutex_new(); cnx_shared_mutex_lock(my_thing_mutex); my_very_important_thing = { // important intialization }; cnx_shared_mutex_unlock(my_thing_mutex); } } // only one thread at a time can `update_my_thing`, because it uses exclusive locking void update_my_thing(u64 value) { cnx_shared_mutex_lock(my_thing_mutex); my_very_important_thing.value = value; cnx_shared_mutex_unlock(my_thing_mutex); } // any number of threads can `get_value_from_my_thing` without blocking eachother, // because it uses shared locking. u64 get_value_from_my_thing(void) { cnx_shared_mutex_lock_shared(my_thing_mutex); let val = my_very_important_thing.value; cnx_shared_mutex_unlock_shared(my_thing_mutex); return val; } // do some compute intensive task... // update the value update_my_thing(new_value); my_val = get_value_from_my_thing(); // do something with my_val let_mut newval = get_value_from_my_thing(); while(newval == my_val) { cnx_this_thread_sleep_for(cnx_milliseconds(100)); newval = get_value_from_my_thing(); } my_val = newval; // do something with new value
Classes
- struct CnxSharedMutex
CnxSharedMutexis the generic (it's not timed or recursive) reader-writer mutex provided by Cnx. It's directly comparable to C++'sstd::shared_mutexand is suitable for any situation where a reader-writer mutex is necessary.- struct CnxSharedTimedMutex
CnxSharedTimedMutexis a higher-level reader-writer mutex type for use when timed backoff of mutex locking is required, and is directly comparable to C++'sstd::shared_timed_mutex. It allows for specifying a timeout, which if reached will cause execution to stop attempting to acquire the lock and signal failure to the caller, instead of blocking indefinitely until the lock was successfully acquired like a tradition mutex. For example, if an algorithm needs reader-writer synchronization, but blocking for longer than X milliseconds when trying to acquire the lock would be problematic, aCnxSharedTimedMutexwould be the appropriate mutex type to use.- struct CnxSharedMutexInterface
Functions
- CnxSharedMutex cnx_shared_mutex_new(void)
- Creates a new shared mutex.
- void cnx_shared_mutex_lock(CnxSharedMutex*restrict mutex)
- Unconditionally locks the mutex pointed to by
mutexexclusively (aka for writing) - bool cnx_shared_mutex_try_lock(CnxSharedMutex*restrict mutex)
- Attempts to lock the mutex pointed to by
mutexexclusively (aka for writing) - void cnx_shared_mutex_lock_shared(CnxSharedMutex*restrict mutex)
- Unconditionally locks the mutex pointed to by
mutexnon-exclusively (shared, aka for reading) - bool cnx_shared_mutex_try_lock_shared(CnxSharedMutex*restrict mutex)
- Attempts to lock the mutex pointed to by
mutexnon-exclusively (shared, aka for reading) - void cnx_shared_mutex_unlock(CnxSharedMutex*restrict mutex)
- Unlocks the exclusively locked mutex pointed to by
mutex - void cnx_shared_mutex_unlock_shared(CnxSharedMutex*restrict mutex)
- Unlocks the non-exclusively (aka shared) locked mutex pointed to by
mutex - void cnx_shared_mutex_free(CnxSharedMutex*restrict mutex)
- Destroys the mutex pointed to by
mutex - CnxSharedTimedMutex cnx_shared_timed_mutex_new(void)
- Creates a new shared timed mutex.
- void cnx_shared_timed_mutex_lock(CnxSharedTimedMutex*restrict mutex)
- Unconditionally locks the mutex pointed to by
mutexexclusively (aka for writing) - bool cnx_shared_timed_mutex_try_lock(CnxSharedTimedMutex*restrict mutex)
- Attempts to lock the mutex pointed to by
mutexexclusively (aka for writing) - bool cnx_shared_timed_mutex_try_lock_for(CnxSharedTimedMutex*restrict mutex, CnxDuration duration)
- Attempts to lock the mutex pointed to by
mutexexclusively (aka for writing) - bool cnx_shared_timed_mutex_try_lock_until(CnxSharedTimedMutex*restrict mutex, CnxTimePoint stop_point)
- Attempts to lock the mutex pointed to by
mutexexclusively (aka for writing) - void cnx_shared_timed_mutex_lock_shared(CnxSharedTimedMutex*restrict mutex)
- Unconditionally locks the mutex pointed to by
mutexnon-exclusively (shared, aka for reading) - bool cnx_shared_timed_mutex_try_lock_shared(CnxSharedTimedMutex*restrict mutex)
- Attempts to lock the mutex pointed to by
mutexnon-exclusively (shared, aka for reading) - bool cnx_shared_timed_mutex_try_lock_shared_for(CnxSharedTimedMutex*restrict mutex, CnxDuration duration)
- Attempts to lock the mutex pointed to by
mutexnon-exclusively (aka shared, for reading) - bool cnx_shared_timed_mutex_try_lock_shared_until(CnxSharedTimedMutex*restrict mutex, CnxTimePoint stop_point)
- Attempts to lock the mutex pointed to by
mutexnon-exclusively (aka shared, for reading) - void cnx_shared_timed_mutex_unlock(CnxSharedTimedMutex*restrict mutex)
- Unlocks the exclusively locked mutex pointed to by
mutex - void cnx_shared_timed_mutex_unlock_shared(CnxSharedTimedMutex*restrict mutex)
- Unlocks the non-exclusively (aka shared) locked mutex pointed to by
mutex - void cnx_shared_timed_mutex_free(CnxSharedTimedMutex*restrict mutex)
- Destroys the mutex pointed to by
mutex
Function documentation
CnxSharedMutex cnx_shared_mutex_new(void)
#include <include/Cnx/sync/SharedMutex.h>
Creates a new shared mutex.
| Returns | A CnxSharedMutex |
|---|
void cnx_shared_mutex_lock(CnxSharedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Unconditionally locks the mutex pointed to by mutex exclusively (aka for writing)
| Parameters | |
|---|---|
| mutex | - The mutex to lock exclusively (aka for writing) |
bool cnx_shared_mutex_try_lock(CnxSharedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Attempts to lock the mutex pointed to by mutex exclusively (aka for writing)
| Parameters | |
|---|---|
| mutex | - The mutex to lock exclusively (aka for writing) |
| Returns | true if successful |
If locking the mutex is successful, return true.
void cnx_shared_mutex_lock_shared(CnxSharedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Unconditionally locks the mutex pointed to by mutex non-exclusively (shared, aka for reading)
| Parameters | |
|---|---|
| mutex | - The mutex to lock non-exclusively (aka shared, for reading) |
bool cnx_shared_mutex_try_lock_shared(CnxSharedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Attempts to lock the mutex pointed to by mutex non-exclusively (shared, aka for reading)
| Parameters | |
|---|---|
| mutex | - The mutex to lock non-exclusively (aka shared, for reading) |
| Returns | true if successful |
If locking the mutex is successful, return true.
void cnx_shared_mutex_unlock(CnxSharedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Unlocks the exclusively locked mutex pointed to by mutex
| Parameters | |
|---|---|
| mutex | - The mutex to unlock exclusively |
void cnx_shared_mutex_unlock_shared(CnxSharedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Unlocks the non-exclusively (aka shared) locked mutex pointed to by mutex
| Parameters | |
|---|---|
| mutex | - The mutex to unlock non-exclusively |
void cnx_shared_mutex_free(CnxSharedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Destroys the mutex pointed to by mutex
| Parameters | |
|---|---|
| mutex | - The mutex to free |
CnxSharedTimedMutex cnx_shared_timed_mutex_new(void)
#include <include/Cnx/sync/SharedMutex.h>
Creates a new shared timed mutex.
| Returns | A CnxSharedTimedMutex |
|---|
void cnx_shared_timed_mutex_lock(CnxSharedTimedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Unconditionally locks the mutex pointed to by mutex exclusively (aka for writing)
| Parameters | |
|---|---|
| mutex | - The mutex to lock exclusively (aka for writing) |
bool cnx_shared_timed_mutex_try_lock(CnxSharedTimedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Attempts to lock the mutex pointed to by mutex exclusively (aka for writing)
| Parameters | |
|---|---|
| mutex | - The mutex to lock exclusively (aka for writing) |
| Returns | true if successful |
If locking the mutex is successful, return true.
bool cnx_shared_timed_mutex_try_lock_for(CnxSharedTimedMutex*restrict mutex,
CnxDuration duration)
#include <include/Cnx/sync/SharedMutex.h>
Attempts to lock the mutex pointed to by mutex exclusively (aka for writing)
| Parameters | |
|---|---|
| mutex | - The mutex to lock |
| duration | - The amount to time spend trying to lock the mutex |
| Returns | true if successful |
Tries to lock the mutex until the amount of time specified by duration has passed. If locking is successful before duration has elapsed, returns true. Otherwise stops trying to acquire the lock and returns false.
bool cnx_shared_timed_mutex_try_lock_until(CnxSharedTimedMutex*restrict mutex,
CnxTimePoint stop_point)
#include <include/Cnx/sync/SharedMutex.h>
Attempts to lock the mutex pointed to by mutex exclusively (aka for writing)
| Parameters | |
|---|---|
| mutex | - The mutex to lock |
| stop_point | - The point in time at which to quit trying to lock the mutex |
| Returns | true if successful |
Tries to lock the mutex until the the point in time specified by stop_point. If locking is successful before stop_point has occurred, returns true. Otherwise stops trying to acquire the lock and returns false.
void cnx_shared_timed_mutex_lock_shared(CnxSharedTimedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Unconditionally locks the mutex pointed to by mutex non-exclusively (shared, aka for reading)
| Parameters | |
|---|---|
| mutex | - The mutex to lock non-exclusively (aka shared, for reading) |
bool cnx_shared_timed_mutex_try_lock_shared(CnxSharedTimedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Attempts to lock the mutex pointed to by mutex non-exclusively (shared, aka for reading)
| Parameters | |
|---|---|
| mutex | - The mutex to lock non-exclusively (aka shared, for reading) |
| Returns | true if successful |
If locking the mutex is successful, return true.
bool cnx_shared_timed_mutex_try_lock_shared_for(CnxSharedTimedMutex*restrict mutex,
CnxDuration duration)
#include <include/Cnx/sync/SharedMutex.h>
Attempts to lock the mutex pointed to by mutex non-exclusively (aka shared, for reading)
| Parameters | |
|---|---|
| mutex | - The mutex to lock |
| duration | - The amount to time spend trying to lock the mutex |
| Returns | true if successful |
Tries to lock the mutex until the amount of time specified by duration has passed. If locking is successful before duration has elapsed, returns true. Otherwise stops trying to acquire the lock and returns false.
bool cnx_shared_timed_mutex_try_lock_shared_until(CnxSharedTimedMutex*restrict mutex,
CnxTimePoint stop_point)
#include <include/Cnx/sync/SharedMutex.h>
Attempts to lock the mutex pointed to by mutex non-exclusively (aka shared, for reading)
| Parameters | |
|---|---|
| mutex | - The mutex to lock |
| stop_point | - The point in time at which to quit trying to lock the mutex |
| Returns | true if successful |
Tries to lock the mutex until the the point in time specified by stop_point. If locking is successful before stop_point has occurred, returns true. Otherwise stops trying to acquire the lock and returns false.
void cnx_shared_timed_mutex_unlock(CnxSharedTimedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Unlocks the exclusively locked mutex pointed to by mutex
| Parameters | |
|---|---|
| mutex | - The mutex to unlock exclusively |
void cnx_shared_timed_mutex_unlock_shared(CnxSharedTimedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Unlocks the non-exclusively (aka shared) locked mutex pointed to by mutex
| Parameters | |
|---|---|
| mutex | - The mutex to unlock non-exclusively |
void cnx_shared_timed_mutex_free(CnxSharedTimedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Destroys the mutex pointed to by mutex
| Parameters | |
|---|---|
| mutex | - The mutex to free |