blob: af9c9c598997111d290ca67051dd50f868d5d6df [file] [log] [blame]
Brian Silvermanf5f34902015-03-29 17:57:59 -04001#include "aos/common/event.h"
2
3#include "aos/common/type_traits.h"
4#include "aos/common/logging/logging.h"
5
6namespace aos {
7
8Event::Event() : impl_(0) {
9 static_assert(shm_ok<Event>::value,
10 "Event is not safe for use in shared memory.");
11}
12
13void Event::Wait() {
Brian Silverman408511d2016-09-10 16:12:02 -040014 while (__atomic_load_n(&impl_, __ATOMIC_SEQ_CST) == 0) {
15 const int ret = futex_wait(&impl_);
16 if (ret != 0) {
17 CHECK_EQ(-1, ret);
18 PLOG(FATAL, "futex_wait(%p) failed", &impl_);
19 }
20 }
Brian Silvermanf5f34902015-03-29 17:57:59 -040021}
22
Brian Silverman30608942015-04-08 19:16:46 -040023bool Event::WaitTimeout(const ::aos::time::Time &timeout) {
24 const auto timeout_timespec = timeout.ToTimespec();
Brian Silverman408511d2016-09-10 16:12:02 -040025 while (true) {
26 if (__atomic_load_n(&impl_, __ATOMIC_SEQ_CST) != 0) {
27 return true;
28 }
29 const int ret = futex_wait_timeout(&impl_, &timeout_timespec);
30 if (ret != 0) {
31 if (ret == 2) return false;
32 CHECK_EQ(-1, ret);
33 PLOG(FATAL, "futex_wait(%p) failed", &impl_);
34 }
35 }
Brian Silverman30608942015-04-08 19:16:46 -040036}
37
Brian Silvermanf5f34902015-03-29 17:57:59 -040038// We're not going to expose the number woken because that's not easily portable
39// to condition variable-based implementations.
40void Event::Set() {
41 if (futex_set(&impl_) == -1) {
42 PLOG(FATAL, "futex_set(%p) failed", &impl_);
43 }
44}
45
46bool Event::Clear() {
47 return !futex_unset(&impl_);
48}
49
50} // namespace aos