blob: e4276b620523296f77aa584997fd5e1345c27c81 [file] [log] [blame]
John Park33858a32018-09-28 23:05:48 -07001#include "aos/condition.h"
Brian Silvermand41b4422013-09-01 14:02:33 -07002
Brian Silvermandc1eb272014-08-19 14:25:59 -04003#include <assert.h>
Austin Schuh0ad2b6f2019-06-09 21:27:07 -07004#include <inttypes.h>
5#include <time.h>
Brian Silvermand41b4422013-09-01 14:02:33 -07006
John Park33858a32018-09-28 23:05:48 -07007#include "aos/mutex/mutex.h"
Austin Schuh0ad2b6f2019-06-09 21:27:07 -07008#include "aos/type_traits/type_traits.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -07009#include "glog/logging.h"
Brian Silvermand41b4422013-09-01 14:02:33 -070010
11namespace aos {
12
Austin Schuh0ad2b6f2019-06-09 21:27:07 -070013namespace chrono = ::std::chrono;
14
Brian Silverman7f365e32014-01-01 17:59:01 -080015static_assert(shm_ok<Condition>::value,
16 "Condition should work in shared memory");
Brian Silvermand41b4422013-09-01 14:02:33 -070017
Brian Silverman08661c72013-09-01 17:24:38 -070018Condition::Condition(Mutex *m) : impl_(), m_(m) {}
Brian Silvermand41b4422013-09-01 14:02:33 -070019
Austin Schuhf4b194e2014-09-21 10:26:41 -070020bool Condition::Wait() {
Austin Schuh0ad2b6f2019-06-09 21:27:07 -070021 const int ret = condition_wait(&impl_, &m_->impl_, nullptr);
Brian Silvermandc1eb272014-08-19 14:25:59 -040022 assert(__builtin_expect(ret == 0 || ret == 1, 1));
23 return ret == 1;
Brian Silvermand41b4422013-09-01 14:02:33 -070024}
25
Austin Schuh0ad2b6f2019-06-09 21:27:07 -070026Condition::WaitResult Condition::WaitTimed(chrono::nanoseconds timeout) {
27 struct timespec end_time;
28 const bool do_timeout = timeout != chrono::nanoseconds(0);
29
30 if (do_timeout) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070031 PCHECK(clock_gettime(CLOCK_MONOTONIC, &end_time) == 0);
Austin Schuh0ad2b6f2019-06-09 21:27:07 -070032 timeout += chrono::nanoseconds(end_time.tv_nsec);
33 chrono::seconds timeout_seconds =
34 chrono::duration_cast<chrono::seconds>(timeout);
35 end_time.tv_sec += timeout_seconds.count();
36 end_time.tv_nsec = (timeout - timeout_seconds).count();
37 }
38
39 const int ret =
40 condition_wait(&impl_, &m_->impl_, do_timeout ? &end_time : nullptr);
41 assert(__builtin_expect(ret == 0 || ret == 1 || ret == -1, 1));
42 switch (ret) {
43 case 0:
44 return WaitResult::kOk;
45 case 1:
46 return WaitResult::kOwnerDied;
47 default:
48 return WaitResult::kTimeout;
49 }
Brian Silvermand41b4422013-09-01 14:02:33 -070050}
Brian Silverman08661c72013-09-01 17:24:38 -070051
Austin Schuh0ad2b6f2019-06-09 21:27:07 -070052void Condition::Signal() { condition_signal(&impl_, &m_->impl_); }
53
Brian Silverman08661c72013-09-01 17:24:38 -070054void Condition::Broadcast() {
Brian Silverman797e71e2013-09-06 17:29:39 -070055 condition_broadcast(&impl_, &m_->impl_);
Brian Silvermand41b4422013-09-01 14:02:33 -070056}
57
58} // namespace aos