amiro-os / include / amiro / util / rwlock.hpp @ d314ad6f
History | View | Annotate | Download (3.016 KB)
1 | 58fe0e0b | Thomas Schöpping | #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_ |