Semaphore means signal in french (or greek maybe, idk). hence an adjacent name, blinker.
This project implements simple semaphore based syncrhonisation constructs from scratch in C++20.
don't use in production directly(mostly).
signal()andwait()implemented using atomics instead of delegating it to OS semaphores.- aka
counting semaphore. - a
n-way-multiplexerisSempahore{n}.
lock()andunlock()are a wrapper over binary semaphore.- this is not the same as
std::mutexas there is no sense of ownerships in semaaphores. - but, the interface is the same so, can be used with RAII constructs like
std::lock_guard. - aka
binary semaphore.
arrive_and_wait()waits forNthreads to reach till a point then signal all at once.- aka
single-use barrier.
arrive_and_wait()waits forNthreads to reach till a point then signal all at once.- TODO: implement a completion function to run after the completion of each phase.
- aka
reusable barrier.
lock(Semaphore&)andunlock(Semaphore&)takes the same semaphore as argument.- first thread acquires the exclusive access to the resource and the last thread releases it.
- best understood by the common shared resource access problem like reader-writer problem.
- in reader-writer, a reader acquires exclusive access to the resource via a lightswitch to allow
multiple readers while the writer can simply wait on the
Semaphorepassed to that switch.
SharedMutex (exclusive-access is starvation prone)
- aka
read-critical reader-writer lock. - threads either acquire shared access to the resource via
lock_shared()or an exclusive access vialock(). - follows the traits of both
LockableandSharedLockableso, can be used with bothstd::shared_lock&std::lock. - As long as there's a shared-access thread with the access to the resource, no thread can gain exclusive-access.
- This might lead to 'Starvation'.
- For example, this can be used as a RW-lock where stale reads are acceptable.
No-Starve SharedMutex (fair contention between exclusive-access & shared-access threads)
- same interface as
SharedMutexabove. - aka
no-starve reader-writer lock. - implemented such that there's fair contention between readers and writers.
- once a writer starts waiting, while all existing readers can finish their tasks, no other reader gets exclusive-access.
- this enables for at least one writer to get exclusive-access once all existing readers finish their tasks.
- this prevents writer starvation as seen with
SharedMutexabove.
Exclusive-Prioritised SharedMutex (exclusive-access prioritised over shared-access)
- same interface as
SharedMutexabove. - aka
write-critical reader-writer lock. - once a writer gets exclusive-access to the resource, readers wait until ALL the writers are finished.
- similar to
SharedMutexbut the priority is given to thewriterinstead of thereader. - can be used as a
RW-Lockwhere writes are more critical or reading stale data is not acceptable. - CAUTION: This might starve the Readers.
$ make build # to build the project
$ make test # to run all Catch2 tests
$ make run # to run the project
$ make all # build and runNOTE
- current impl has a
doctestprovided main. - check
Makefilefor more information.