Statistics
| Branch: | Tag: | Revision:

amiro-os / include / amiro / util / rwlock.hpp @ 58fe0e0b

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_