Statistics
| Branch: | Tag: | Revision:

amiro-os / include / amiro / util / rwlock.hpp @ ba75ee1d

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