amiro-os / include / amiro / util / rwlock.hpp @ 6ad5c364
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_ |