blob: f7860be82301ad3a12799fd88cd1dac129576c8c [file] [log] [blame]
John Park33858a32018-09-28 23:05:48 -07001#include "aos/condition.h"
Brian Silvermand41b4422013-09-01 14:02:33 -07002
Tyler Chatowbf0609c2021-07-31 16:13:27 -07003#include <cassert>
4#include <cinttypes>
5#include <ctime>
Brian Silvermand41b4422013-09-01 14:02:33 -07006
Philipp Schrader790cb542023-07-05 21:06:52 -07007#include "glog/logging.h"
8
John Park33858a32018-09-28 23:05:48 -07009#include "aos/mutex/mutex.h"
Austin Schuh0ad2b6f2019-06-09 21:27:07 -070010#include "aos/type_traits/type_traits.h"
Brian Silvermand41b4422013-09-01 14:02:33 -070011
12namespace aos {
13
Austin Schuh0ad2b6f2019-06-09 21:27:07 -070014namespace chrono = ::std::chrono;
15
Brian Silverman7f365e32014-01-01 17:59:01 -080016static_assert(shm_ok<Condition>::value,
17 "Condition should work in shared memory");
Brian Silvermand41b4422013-09-01 14:02:33 -070018
Brian Silverman08661c72013-09-01 17:24:38 -070019Condition::Condition(Mutex *m) : impl_(), m_(m) {}
Brian Silvermand41b4422013-09-01 14:02:33 -070020
Austin Schuhf4b194e2014-09-21 10:26:41 -070021bool Condition::Wait() {
Austin Schuh0ad2b6f2019-06-09 21:27:07 -070022 const int ret = condition_wait(&impl_, &m_->impl_, nullptr);
Brian Silvermandc1eb272014-08-19 14:25:59 -040023 assert(__builtin_expect(ret == 0 || ret == 1, 1));
24 return ret == 1;
Brian Silvermand41b4422013-09-01 14:02:33 -070025}
26
Austin Schuh0ad2b6f2019-06-09 21:27:07 -070027Condition::WaitResult Condition::WaitTimed(chrono::nanoseconds timeout) {
28 struct timespec end_time;
29 const bool do_timeout = timeout != chrono::nanoseconds(0);
30
31 if (do_timeout) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070032 PCHECK(clock_gettime(CLOCK_MONOTONIC, &end_time) == 0);
Austin Schuh0ad2b6f2019-06-09 21:27:07 -070033 timeout += chrono::nanoseconds(end_time.tv_nsec);
34 chrono::seconds timeout_seconds =
35 chrono::duration_cast<chrono::seconds>(timeout);
36 end_time.tv_sec += timeout_seconds.count();
37 end_time.tv_nsec = (timeout - timeout_seconds).count();
38 }
39
40 const int ret =
41 condition_wait(&impl_, &m_->impl_, do_timeout ? &end_time : nullptr);
42 assert(__builtin_expect(ret == 0 || ret == 1 || ret == -1, 1));
43 switch (ret) {
44 case 0:
45 return WaitResult::kOk;
46 case 1:
47 return WaitResult::kOwnerDied;
48 default:
49 return WaitResult::kTimeout;
50 }
Brian Silvermand41b4422013-09-01 14:02:33 -070051}
Brian Silverman08661c72013-09-01 17:24:38 -070052
Austin Schuh0ad2b6f2019-06-09 21:27:07 -070053void Condition::Signal() { condition_signal(&impl_, &m_->impl_); }
54
Tyler Chatowbf0609c2021-07-31 16:13:27 -070055void Condition::Broadcast() { condition_broadcast(&impl_, &m_->impl_); }
Brian Silvermand41b4422013-09-01 14:02:33 -070056
57} // namespace aos