condition_variable.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Hamburg University of Applied Sciences (HAW)
3  *
4  * This file is subject to the terms and conditions of the GNU Lesser
5  * General Public License v2.1. See the file LICENSE in the top level
6  * directory for more details.
7  */
8 
24 #ifndef RIOT_CONDITION_VARIABLE_HPP
25 #define RIOT_CONDITION_VARIABLE_HPP
26 
27 #include "sched.h"
28 #include "ztimer64.h"
29 #include "priority_queue.h"
30 
31 #include "riot/mutex.hpp"
32 #include "riot/chrono.hpp"
33 
34 namespace riot {
35 
39 enum class cv_status {
40  no_timeout,
41  timeout
42 };
43 
53 public:
58  inline condition_variable() { m_queue.first = NULL; }
60 
64  void notify_one() noexcept;
68  void notify_all() noexcept;
69 
74  void wait(unique_lock<mutex>& lock) noexcept;
82  template <class Predicate>
83  void wait(unique_lock<mutex>& lock, Predicate pred);
93  const time_point& timeout_time);
106  template <class Predicate>
107  bool wait_until(unique_lock<mutex>& lock, const time_point& timeout_time,
108  Predicate pred);
109 
117  template <class Rep, class Period>
119  const std::chrono::duration<Rep, Period>& rel_time);
129  template <class Rep, class Period, class Predicate>
130  bool wait_for(unique_lock<mutex>& lock,
131  const std::chrono::duration<Rep, Period>& rel_time,
132  Predicate pred);
133 
137  inline native_handle_type native_handle() { return &m_queue; }
138 
139 private:
141  condition_variable& operator=(const condition_variable&);
142 
143  priority_queue_t m_queue;
144 };
145 
146 template <class Predicate>
147 void condition_variable::wait(unique_lock<mutex>& lock, Predicate pred) {
148  while (!pred()) {
149  wait(lock);
150  }
151 }
152 
153 template <class Predicate>
155  const time_point& timeout_time,
156  Predicate pred) {
157  while (!pred()) {
158  if (wait_until(lock, timeout_time) == cv_status::timeout) {
159  return pred();
160  }
161  }
162  return true;
163 }
164 
165 template <class Rep, class Period>
167  const std::chrono::duration
168  <Rep, Period>& timeout_duration) {
169  using namespace std::chrono;
170  using std::chrono::duration;
171  if (timeout_duration <= timeout_duration.zero()) {
172  return cv_status::timeout;
173  }
174  uint64_t timeout, before, after;
175  timeout = (duration_cast<microseconds>(timeout_duration)).count();
176  before = ztimer64_now(ZTIMER64_USEC);
177  ztimer64_t timer;
178  ztimer64_set_wakeup(ZTIMER64_USEC, &timer, timeout, thread_getpid());
179  wait(lock);
180  after = ztimer64_now(ZTIMER64_USEC);
182  if (after - before >= timeout) {
183  return cv_status::timeout;
184  }
185  return cv_status::no_timeout;
186 }
187 
188 template <class Rep, class Period, class Predicate>
190  const std::chrono::duration
191  <Rep, Period>& timeout_duration,
192  Predicate pred) {
193  return wait_until(lock, std::chrono::steady_clock::now() + timeout_duration,
194  std::move(pred));
195 }
196 
197 } // namespace riot
198 
199 #endif // RIOT_CONDITION_VARIABLE_HPP
C++11 chrono drop in replacement that adds the function now based on ztimer/timex.
C++11 compliant implementation of condition variable, uses the time point implemented in our chrono r...
void wait(unique_lock< mutex > &lock) noexcept
Block until woken up through the condition variable.
cv_status wait_for(unique_lock< mutex > &lock, const std::chrono::duration< Rep, Period > &rel_time)
Blocks until woken up through the condition variable or when the thread has been blocked for a certai...
void notify_one() noexcept
Notify one thread waiting on this condition.
void notify_all() noexcept
Notify all threads waiting on this condition variable.
native_handle_type native_handle()
Returns the native handle of the condition variable.
cv_status wait_until(unique_lock< mutex > &lock, const time_point &timeout_time)
Block until woken up through the condition variable or a specified point in time is reached.
C++11 compliant implementation of mutex, uses the time point implemented in our chrono replacement in...
Definition: mutex.hpp:43
A time point for timed wait, as clocks from the standard are not available on RIOT.
Definition: chrono.hpp:41
C++11 compliant implementation of unique lock.
Definition: mutex.hpp:142
static kernel_pid_t thread_getpid(void)
Returns the process ID of the currently running thread.
Definition: thread.h:393
static void ztimer64_set_wakeup(ztimer64_clock_t *clock, ztimer64_t *timer, uint64_t offset, kernel_pid_t pid)
Set a timer that wakes up a thread (relative version)
Definition: ztimer64.h:379
void ztimer64_remove(ztimer64_clock_t *clock, ztimer64_t *timer)
Remove a timer from a clock.
uint64_t ztimer64_now(ztimer64_clock_t *clock)
Get the current time from a clock.
ztimer64_clock_t *const ZTIMER64_USEC
Default ztimer microsecond clock.
C++11 mutex drop in replacement.
RIOT C++ namespace.
Definition: chrono.hpp:35
time_point now()
Returns the current time saved in a time point.
Definition: chrono.hpp:104
cv_status
Status for timeout-based calls of the condition variable.
A simple priority queue.
Scheduler API definition.
data type for priority queues
priority_queue_node_t * first
first queue node
ztimer64 structure
Definition: ztimer64.h:101
ztimer 64bit API