blob: b293cb4776ea43d225989a46078846e537ec3a3c [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
Austin Schuh99f7c6a2024-06-25 22:07:44 -07007#include "absl/log/check.h"
8#include "absl/log/log.h"
Philipp Schrader790cb542023-07-05 21:06:52 -07009
John Park33858a32018-09-28 23:05:48 -070010#include "aos/mutex/mutex.h"
Austin Schuh0ad2b6f2019-06-09 21:27:07 -070011#include "aos/type_traits/type_traits.h"
Brian Silvermand41b4422013-09-01 14:02:33 -070012
13namespace aos {
14
Austin Schuh0ad2b6f2019-06-09 21:27:07 -070015namespace chrono = ::std::chrono;
16
Brian Silverman7f365e32014-01-01 17:59:01 -080017static_assert(shm_ok<Condition>::value,
18 "Condition should work in shared memory");
Brian Silvermand41b4422013-09-01 14:02:33 -070019
Brian Silverman08661c72013-09-01 17:24:38 -070020Condition::Condition(Mutex *m) : impl_(), m_(m) {}
Brian Silvermand41b4422013-09-01 14:02:33 -070021
Austin Schuhf4b194e2014-09-21 10:26:41 -070022bool Condition::Wait() {
Austin Schuh0ad2b6f2019-06-09 21:27:07 -070023 const int ret = condition_wait(&impl_, &m_->impl_, nullptr);
Brian Silvermandc1eb272014-08-19 14:25:59 -040024 assert(__builtin_expect(ret == 0 || ret == 1, 1));
25 return ret == 1;
Brian Silvermand41b4422013-09-01 14:02:33 -070026}
27
Austin Schuh0ad2b6f2019-06-09 21:27:07 -070028Condition::WaitResult Condition::WaitTimed(chrono::nanoseconds timeout) {
29 struct timespec end_time;
30 const bool do_timeout = timeout != chrono::nanoseconds(0);
31
32 if (do_timeout) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070033 PCHECK(clock_gettime(CLOCK_MONOTONIC, &end_time) == 0);
Austin Schuh0ad2b6f2019-06-09 21:27:07 -070034 timeout += chrono::nanoseconds(end_time.tv_nsec);
35 chrono::seconds timeout_seconds =
36 chrono::duration_cast<chrono::seconds>(timeout);
37 end_time.tv_sec += timeout_seconds.count();
38 end_time.tv_nsec = (timeout - timeout_seconds).count();
39 }
40
41 const int ret =
42 condition_wait(&impl_, &m_->impl_, do_timeout ? &end_time : nullptr);
43 assert(__builtin_expect(ret == 0 || ret == 1 || ret == -1, 1));
44 switch (ret) {
45 case 0:
46 return WaitResult::kOk;
47 case 1:
48 return WaitResult::kOwnerDied;
49 default:
50 return WaitResult::kTimeout;
51 }
Brian Silvermand41b4422013-09-01 14:02:33 -070052}
Brian Silverman08661c72013-09-01 17:24:38 -070053
Austin Schuh0ad2b6f2019-06-09 21:27:07 -070054void Condition::Signal() { condition_signal(&impl_, &m_->impl_); }
55
Tyler Chatowbf0609c2021-07-31 16:13:27 -070056void Condition::Broadcast() { condition_broadcast(&impl_, &m_->impl_); }
Brian Silvermand41b4422013-09-01 14:02:33 -070057
58} // namespace aos