amiro-os / include / amiro / util / rwlock.hpp @ 1b3adcdd
History | View | Annotate | Download (3.016 KB)
1 |
#ifndef AMIRO_RWLOCK_H_
|
---|---|
2 |
#define AMIRO_RWLOCK_H_
|
3 |
|
4 |
#include <ch.hpp> |
5 |
|
6 |
namespace amiro {
|
7 |
|
8 |
/**
|
9 |
* @brief An enhanced mutex with parallel read but exclusive write capabilities
|
10 |
*/
|
11 |
class RWLock |
12 |
{ |
13 |
public:
|
14 |
/**
|
15 |
* @brief An enum to specify the favoritism of the RWLock
|
16 |
*/
|
17 |
enum Favor : bool { |
18 |
FAVOR_READERS = false, /**< Favors readers, even if writers are waiting */ |
19 |
FAVOR_WRITERS = true, /**< Favors writers and holds new readers back */ |
20 |
}; |
21 |
|
22 |
/**
|
23 |
* @brief An enum to specify what to wait for in the tryLockReading() and tryLockWriting() methods.
|
24 |
*/
|
25 |
enum WaitingType : uint8_t {
|
26 |
WAIT_FOR_NONE = 0, /**< does not block at all */ |
27 |
WAIT_FOR_MUTEX = 1, /**< blocks at the mutex */ |
28 |
WAIT_FOR_QUEUE = 2, /**< waits for the queues */ |
29 |
}; |
30 |
|
31 |
private:
|
32 |
/**
|
33 |
* @brief A status struct holding the current configuration of the RWLock.
|
34 |
*/
|
35 |
struct AccessStatus {
|
36 |
uint8_t reader_count : 7; /**< The number of currently active readers (128 max) */ |
37 |
uint8_t favor : 1; /**< The currently selected favoritism */ |
38 |
}; |
39 |
|
40 |
chibios_rt::Mutex mutex; /**< A mutex lock used for synchronization */
|
41 |
chibios_rt::CondVar waiting_readers; /**< A condition variable for waiting readers */
|
42 |
chibios_rt::CondVar waiting_writers; /**< A condition variable for all waiting writers */
|
43 |
AccessStatus status; /**< The current status of the RWLock */
|
44 |
|
45 |
public:
|
46 |
/**
|
47 |
* @brief Constructor of the RWLock class.
|
48 |
* @param[in] favor The initial favoritism (default: FAVOR_WRITERS)
|
49 |
*/
|
50 |
explicit RWLock(const Favor favor = FAVOR_WRITERS); |
51 |
|
52 |
/**
|
53 |
* @brief Destructor of the RWLock class.
|
54 |
*/
|
55 |
virtual ~RWLock();
|
56 |
|
57 |
/**
|
58 |
* @brief Lock the RWLock as a reader (shared mode)
|
59 |
*/
|
60 |
void lockReading();
|
61 |
|
62 |
/**
|
63 |
* @brief Lock the RWLock as a writer (exclusive mode)
|
64 |
*/
|
65 |
void lockWriting();
|
66 |
|
67 |
/**
|
68 |
* @brief Try to lock the RWLock as a reader (shared mode) but do not block
|
69 |
* @param[in] wait Can be used to wait for the mutex to lock or the queue to be empty
|
70 |
* @return True if the RWLock was successfully locked; False if not
|
71 |
*/
|
72 |
bool tryLockReading(const WaitingType wait = WAIT_FOR_NONE); |
73 |
|
74 |
/**
|
75 |
* @brief Try to lock the RWLock as a writer (exclusive mode) but do not block
|
76 |
* @param[in] wait Can be used to wait for the mutex to lock or the queue to be empty
|
77 |
* @return True if the RWLock was successfully locked; False if not
|
78 |
*/
|
79 |
bool tryLockWriting(const WaitingType wait = WAIT_FOR_NONE); |
80 |
|
81 |
/**
|
82 |
* @brief Unlocks the RWLock.
|
83 |
* If it was locked in shared or exclusive mode is detected automatically.
|
84 |
*/
|
85 |
void unlock();
|
86 |
|
87 |
/**
|
88 |
* @brief Set the favoritism of the RWLock
|
89 |
* @param[in] favor Either FAVOR_READERS or FAVOR_WRITERS
|
90 |
*/
|
91 |
void setFavoritism(const Favor favor); |
92 |
|
93 |
/**
|
94 |
* @brief Try to set the favoritism of the RWLock but do not block
|
95 |
* @param[in] favor Either FAVOR_READERS or FAVOR_WRITERS
|
96 |
* @return True if the favoritism was successfully set; False if not
|
97 |
*/
|
98 |
bool trySetFavoritism(const Favor favor); |
99 |
|
100 |
}; |
101 |
|
102 |
} // end of namespace amiro
|
103 |
|
104 |
#endif // AMIRO_RWLOCK_H_ |
105 |
|