blob: b62bdb2abf341fd6bc985a93bb8473641016c969 [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
Stephan Pleines682928d2024-05-31 20:43:48 -07003#include <time.h>
4
Austin Schuhf2a50ba2016-12-24 16:16:26 -08005#include <chrono>
Stephan Pleines682928d2024-05-31 20:43:48 -07006#include <ostream>
7#include <ratio>
Austin Schuhf2a50ba2016-12-24 16:16:26 -08008
Austin Schuh99f7c6a2024-06-25 22:07:44 -07009#include "absl/log/check.h"
10#include "absl/log/log.h"
Brian Silvermanf5f34902015-03-29 17:57:59 -040011
Philipp Schrader790cb542023-07-05 21:06:52 -070012#include "aos/type_traits/type_traits.h"
13
Brian Silvermanf5f34902015-03-29 17:57:59 -040014namespace aos {
15
16Event::Event() : impl_(0) {
17 static_assert(shm_ok<Event>::value,
18 "Event is not safe for use in shared memory.");
19}
20
21void Event::Wait() {
Brian Silverman408511d2016-09-10 16:12:02 -040022 while (__atomic_load_n(&impl_, __ATOMIC_SEQ_CST) == 0) {
23 const int ret = futex_wait(&impl_);
24 if (ret != 0) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070025 CHECK_EQ(-1, ret);
26 PLOG(FATAL) << "futex_wait(" << &impl_ << ") failed";
Brian Silverman408511d2016-09-10 16:12:02 -040027 }
28 }
Brian Silvermanf5f34902015-03-29 17:57:59 -040029}
30
Austin Schuhf2a50ba2016-12-24 16:16:26 -080031bool Event::WaitTimeout(monotonic_clock::duration timeout) {
32 ::std::chrono::seconds sec =
33 ::std::chrono::duration_cast<::std::chrono::seconds>(timeout);
34 ::std::chrono::nanoseconds nsec =
35 ::std::chrono::duration_cast<::std::chrono::nanoseconds>(timeout - sec);
36 struct timespec timeout_timespec;
37 timeout_timespec.tv_sec = sec.count();
38 timeout_timespec.tv_nsec = nsec.count();
Brian Silverman408511d2016-09-10 16:12:02 -040039 while (true) {
40 if (__atomic_load_n(&impl_, __ATOMIC_SEQ_CST) != 0) {
41 return true;
42 }
43 const int ret = futex_wait_timeout(&impl_, &timeout_timespec);
44 if (ret != 0) {
45 if (ret == 2) return false;
Alex Perrycb7da4b2019-08-28 19:35:56 -070046 CHECK_EQ(-1, ret);
47 PLOG(FATAL) << "futex_wait(" << &impl_ << ") failed";
Brian Silverman408511d2016-09-10 16:12:02 -040048 }
49 }
Brian Silverman30608942015-04-08 19:16:46 -040050}
51
Brian Silvermanf5f34902015-03-29 17:57:59 -040052// We're not going to expose the number woken because that's not easily portable
53// to condition variable-based implementations.
54void Event::Set() {
55 if (futex_set(&impl_) == -1) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070056 PLOG(FATAL) << "futex_set(" << &impl_ << ") failed";
Brian Silvermanf5f34902015-03-29 17:57:59 -040057 }
58}
59
Brian Silverman7b266d92021-02-17 21:24:02 -080060bool Event::Clear() { return !futex_unset(&impl_); }
Brian Silvermanf5f34902015-03-29 17:57:59 -040061
62} // namespace aos