ADTF  3.18.3
semaphore_impl.h
Go to the documentation of this file.
1 
15 #ifndef A_UTIL_UTIL_CONCURRENCY_DETAIL_SEMAPHORE_IMPL_HEADER_INCLUDED
16 #define A_UTIL_UTIL_CONCURRENCY_DETAIL_SEMAPHORE_IMPL_HEADER_INCLUDED
17 
19 #include <a_util/system/system.h>
20 
21 #ifndef _MSC_VER
22 #include <condition_variable>
23 #include <thread>
24 #else
25 #include <mutex>
26 #endif // !_MSC_VER
27 
28 #include <stdexcept>
29 
30 namespace a_util {
31 namespace concurrency {
32 namespace detail {
33 template <typename Mutex, typename CondVar>
35  : _mutex(), _cv(), _lock_count(count)
36 {
37 }
38 
39 template <typename Mutex, typename CondVar>
41 {
42  std::unique_lock<Mutex> lock(_mutex);
43  _lock_count++;
44  _cv.notify_all();
45 }
46 
47 template <typename Mutex, typename CondVar>
49 {
50  std::unique_lock<Mutex> lock(_mutex);
51 
52  while (_lock_count == 0) {
53  _cv.wait(lock);
54  }
55  _lock_count--;
56 }
57 
58 template <typename Mutex, typename CondVar>
60 {
61  std::unique_lock<Mutex> lock(_mutex);
62  bool is_success = false;
63  if (_lock_count > 0) {
64  _lock_count--;
65  is_success = true;
66  }
67  return is_success;
68 }
69 
70 template <typename Mutex, typename CondVar>
72 {
73  std::unique_lock<Mutex> lock(_mutex);
74  _lock_count = 0;
75 }
76 
77 template <typename Mutex, typename CondVar>
79 {
80  std::unique_lock<Mutex> lock(_mutex);
81  return _lock_count > 0;
82 }
83 
84 template <typename Mutex, typename CondVar>
85 template <typename Rep, typename Period>
87  const std::chrono::duration<Rep, Period>& timeout)
88 {
89  if (timeout.count() < 0) {
90  throw std::invalid_argument("timeout.count() < 0");
91  }
92 
93  // can compute this before locking
94  const timestamp_t until =
96  std::chrono::duration_cast<std::chrono::microseconds>(timeout).count();
97 
98  std::unique_lock<Mutex> lock(_mutex);
99 
100  bool is_timeout = false;
101  while (_lock_count == 0 && !is_timeout) {
102  const timestamp_t wait_time = until - a_util::system::getCurrentMicroseconds();
103  is_timeout =
104  (wait_time <= 0) ||
105  (_cv.wait_for(lock, std::chrono::microseconds(wait_time)) == std::cv_status::timeout);
106  }
107 
108  // can lock ?
109  if (_lock_count > 0) {
110  _lock_count--;
111  return true;
112  }
113 
114  return false;
115 }
116 
117 } // namespace detail
118 } // namespace concurrency
119 } // namespace a_util
120 
121 #endif // A_UTIL_UTIL_CONCURRENCY_DETAIL_SEMAPHORE_IMPL_HEADER_INCLUDED
Semaphore implementation, combining a mutex and a condition variable to manage a counter.
void notify()
Increment the counter and notify any waiters.
bool is_set()
Check whether the counter is set.
void wait()
Decrement the counter, blocks until the count becomes non-zero (if neccessary)
void reset()
Reset the counter to 0.
bool try_wait()
Try decrementing the counter.
bool wait_for(const std::chrono::duration< Rep, Period > &timeout)
Wait for a specified duration of time and decrement the counter afterwards.
std::int64_t timestamp_t
Type of a timestamp value. If not otherwise stated, always in microseconds.
timestamp_t getCurrentMicroseconds()
Get the current microseconds passed since the first invocation (or -1 if not available)
Serves as the root component, with common functionality documented in core functionality.
Definition: base.h:24
Public API for basic_semaphore type.
Public API for system classes and functions.