The friendly Operating System for the Internet of Things
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 "xtimer.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);
92  cv_status wait_until(unique_lock<mutex>& lock,
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>
118  cv_status wait_for(unique_lock<mutex>& lock,
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  timex_t timeout, before, after;
175  auto s = duration_cast<seconds>(timeout_duration);
176  timeout.seconds = s.count();
177  timeout.microseconds
178  = (duration_cast<microseconds>(timeout_duration - s)).count();
179  xtimer_now_timex(&before);
180  xtimer_t timer;
182  wait(lock);
183  xtimer_now_timex(&after);
184  xtimer_remove(&timer);
185  auto passed = timex_sub(after, before);
186  auto cmp = timex_cmp(passed, timeout);
187  return cmp < 1 ? cv_status::no_timeout : cv_status::timeout;
188 }
189 
190 template <class Rep, class Period, class Predicate>
192  const std::chrono::duration
193  <Rep, Period>& timeout_duration,
194  Predicate pred) {
195  return wait_until(lock, std::chrono::steady_clock::now() + timeout_duration,
196  std::move(pred));
197 }
198 
199 } // namespace riot
200 
201 #endif // RIOT_CONDITION_VARIABLE_HPP
volatile kernel_pid_t sched_active_pid
Process ID of active thread.
Definition: chrono.hpp:34
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...
native_handle_type native_handle()
Returns the native handle of the condition variable.
int timex_cmp(const timex_t a, const timex_t b)
Compares two timex timestamps.
A timex timestamp.
Definition: timex.h:79
data type for priority queues
static uint64_t timex_uint64(const timex_t a)
Converts a timex timestamp to a 64 bit value.
Definition: timex.h:161
C++11 mutex drop in replacement.
C++11 complient implementation of mutex, uses the time point implemented in our chrono replacement in...
Definition: mutex.hpp:43
void xtimer_now_timex(timex_t *out)
get the current system time into a timex_t
A simple priority queue.
priority_queue_node_t * first
first queue node
Scheduler API definition.
A time point for timed wait, as clocks from the standard are not available on RIOT.
Definition: chrono.hpp:44
xtimer interface definitions
C++11 chrono drop in replacement that adds the function now based on xtimer/timex.
timex_t timex_sub(const timex_t a, const timex_t b)
Subtracts two timestamps.
void notify_all() noexcept
Notify all threads waiting on this 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...
C++11 compliant implementation of condition variable, uses the time point implemented in our chrono r...
void notify_one() noexcept
Notify one thread waiting on this condition.
C++11 complient implementation of unique lock.
Definition: mutex.hpp:142
void wait(unique_lock< mutex > &lock) noexcept
Block until woken up through the condition variable.
xtimer timer structure
Definition: xtimer.h:70
void xtimer_remove(xtimer_t *timer)
remove a timer
uint32_t microseconds
number of microseconds
Definition: timex.h:81
uint32_t seconds
number of seconds
Definition: timex.h:80
static void xtimer_set_wakeup(xtimer_t *timer, uint32_t offset, kernel_pid_t pid)
Set a timer that wakes up a thread.