blob: 6b58e33531b30f94dd373a867962abab38d61029 [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
Alex Perrycb7da4b2019-08-28 19:35:56 -07005#include "glog/logging.h"
Brian Silvermanf5f34902015-03-29 17:57:59 -04006
Philipp Schrader790cb542023-07-05 21:06:52 -07007#include "aos/type_traits/type_traits.h"
8
Brian Silvermanf5f34902015-03-29 17:57:59 -04009namespace aos {
10
11Event::Event() : impl_(0) {
12 static_assert(shm_ok<Event>::value,
13 "Event is not safe for use in shared memory.");
14}
15
16void Event::Wait() {
Brian Silverman408511d2016-09-10 16:12:02 -040017 while (__atomic_load_n(&impl_, __ATOMIC_SEQ_CST) == 0) {
18 const int ret = futex_wait(&impl_);
19 if (ret != 0) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070020 CHECK_EQ(-1, ret);
21 PLOG(FATAL) << "futex_wait(" << &impl_ << ") failed";
Brian Silverman408511d2016-09-10 16:12:02 -040022 }
23 }
Brian Silvermanf5f34902015-03-29 17:57:59 -040024}
25
Austin Schuhf2a50ba2016-12-24 16:16:26 -080026bool Event::WaitTimeout(monotonic_clock::duration timeout) {
27 ::std::chrono::seconds sec =
28 ::std::chrono::duration_cast<::std::chrono::seconds>(timeout);
29 ::std::chrono::nanoseconds nsec =
30 ::std::chrono::duration_cast<::std::chrono::nanoseconds>(timeout - sec);
31 struct timespec timeout_timespec;
32 timeout_timespec.tv_sec = sec.count();
33 timeout_timespec.tv_nsec = nsec.count();
Brian Silverman408511d2016-09-10 16:12:02 -040034 while (true) {
35 if (__atomic_load_n(&impl_, __ATOMIC_SEQ_CST) != 0) {
36 return true;
37 }
38 const int ret = futex_wait_timeout(&impl_, &timeout_timespec);
39 if (ret != 0) {
40 if (ret == 2) return false;
Alex Perrycb7da4b2019-08-28 19:35:56 -070041 CHECK_EQ(-1, ret);
42 PLOG(FATAL) << "futex_wait(" << &impl_ << ") failed";
Brian Silverman408511d2016-09-10 16:12:02 -040043 }
44 }
Brian Silverman30608942015-04-08 19:16:46 -040045}
46
Brian Silvermanf5f34902015-03-29 17:57:59 -040047// We're not going to expose the number woken because that's not easily portable
48// to condition variable-based implementations.
49void Event::Set() {
50 if (futex_set(&impl_) == -1) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070051 PLOG(FATAL) << "futex_set(" << &impl_ << ") failed";
Brian Silvermanf5f34902015-03-29 17:57:59 -040052 }
53}
54
Brian Silverman7b266d92021-02-17 21:24:02 -080055bool Event::Clear() { return !futex_unset(&impl_); }
Brian Silvermanf5f34902015-03-29 17:57:59 -040056
57} // namespace aos