|
Click
|
#include <multithread.hh>
Public Member Functions | |
| void | read_begin () |
| void | read_end () |
| void | read_get () |
| void | write_begin () |
| bool | write_attempt () |
| void | write_get () |
| void | write_end () |
| void | write_to_read () |
| bool | read_to_write () |
| uint32_t | refcnt () |
Multiple reader / single writer lock
Enclose read critical section with read_begin()/read_end() and write critical section with write_begin()/write_end()
The lock is based on an atomic counter. The lock is NOT reentrant.
Carefull : calling write_begin while read is held or vice versa will end up in a deadlock
|
inline |
Start a read critical section
You MUST call read_end() after calling read_begin(). You may also call read_to_write(), but see read_to_write documentation for specificities to use, as it may fail.
|
inline |
Finish a read critical section
|
inline |
Add one more reader.
You MUST have called read_begin() before this. You MUST call as many time read_end as you called read_get + read_begin().
|
inline |
Start a write critical section.
This function will spin loop while readers have the lock.
|
inline |
Start a write critical section only if nobody has the lock.
|
inline |
Grab a second write reference on an already held write
|
inline |
Release a write reference.
|
inline |
Convert a write lock to a read lock.
|
inline |
Try to become a writer while read is held. This is unlikely but this may fail, in which case this function returns false. You have to assume that any pointer to the protected object is now bad (a writer has grabbed the write lock while you released the read) The unlikeliness of this event makes this function worth it, if this is unacceptable, directly grab a write reference. TLDR : if false, you have loosed your read lock and neither acquired the write. NEVER have read_to_write in a loop. The correct usage is :
retry: read_begin(); //read_something //compute something if (read_to_write()) //write result else goto retry;
One may think that if read_to_write() fail, you could call write_begin(). Actually this is wrong, as another writer may have taken the lock while calling read_to_write(), and changed the value. The whole computation would therefore not be atomic anymore. Instead of the "goto retry", one may check the read value has not changed after doing a write_begin()