blob: 940dfbd5cbbd89389f81f61bc2434e25c188be7c [file] [log] [blame]
Brian Silverman7b266d92021-02-17 21:24:02 -08001#include "aos/ipc_lib/event.h"
Brian Silvermanf5f34902015-03-29 17:57:59 -04002
Austin Schuhf2a50ba2016-12-24 16:16:26 -08003#include <chrono>
4
John Park33858a32018-09-28 23:05:48 -07005#include "aos/type_traits/type_traits.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -07006#include "glog/logging.h"
Brian Silvermanf5f34902015-03-29 17:57:59 -04007
8namespace aos {
9
10Event::Event() : impl_(0) {
11 static_assert(shm_ok<Event>::value,
12 "Event is not safe for use in shared memory.");
13}
14
15void Event::Wait() {
Brian Silverman408511d2016-09-10 16:12:02 -040016 while (__atomic_load_n(&impl_, __ATOMIC_SEQ_CST) == 0) {
17 const int ret = futex_wait(&impl_);
18 if (ret != 0) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070019 CHECK_EQ(-1, ret);
20 PLOG(FATAL) << "futex_wait(" << &impl_ << ") failed";
Brian Silverman408511d2016-09-10 16:12:02 -040021 }
22 }
Brian Silvermanf5f34902015-03-29 17:57:59 -040023}
24
Austin Schuhf2a50ba2016-12-24 16:16:26 -080025bool Event::WaitTimeout(monotonic_clock::duration timeout) {
26 ::std::chrono::seconds sec =
27 ::std::chrono::duration_cast<::std::chrono::seconds>(timeout);
28 ::std::chrono::nanoseconds nsec =
29 ::std::chrono::duration_cast<::std::chrono::nanoseconds>(timeout - sec);
30 struct timespec timeout_timespec;
31 timeout_timespec.tv_sec = sec.count();
32 timeout_timespec.tv_nsec = nsec.count();
Brian Silverman408511d2016-09-10 16:12:02 -040033 while (true) {
34 if (__atomic_load_n(&impl_, __ATOMIC_SEQ_CST) != 0) {
35 return true;
36 }
37 const int ret = futex_wait_timeout(&impl_, &timeout_timespec);
38 if (ret != 0) {
39 if (ret == 2) return false;
Alex Perrycb7da4b2019-08-28 19:35:56 -070040 CHECK_EQ(-1, ret);
41 PLOG(FATAL) << "futex_wait(" << &impl_ << ") failed";
Brian Silverman408511d2016-09-10 16:12:02 -040042 }
43 }
Brian Silverman30608942015-04-08 19:16:46 -040044}
45
Brian Silvermanf5f34902015-03-29 17:57:59 -040046// We're not going to expose the number woken because that's not easily portable
47// to condition variable-based implementations.
48void Event::Set() {
49 if (futex_set(&impl_) == -1) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070050 PLOG(FATAL) << "futex_set(" << &impl_ << ") failed";
Brian Silvermanf5f34902015-03-29 17:57:59 -040051 }
52}
53
Brian Silverman7b266d92021-02-17 21:24:02 -080054bool Event::Clear() { return !futex_unset(&impl_); }
Brian Silvermanf5f34902015-03-29 17:57:59 -040055
56} // namespace aos