blob: fd5bcaf7337eed32a23f735ecac6dbc053bff97d [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
Alex Perrycb7da4b2019-08-28 19:35:56 -07009#include "glog/logging.h"
Brian Silvermanf5f34902015-03-29 17:57:59 -040010
Philipp Schrader790cb542023-07-05 21:06:52 -070011#include "aos/type_traits/type_traits.h"
12
Brian Silvermanf5f34902015-03-29 17:57:59 -040013namespace aos {
14
15Event::Event() : impl_(0) {
16 static_assert(shm_ok<Event>::value,
17 "Event is not safe for use in shared memory.");
18}
19
20void Event::Wait() {
Brian Silverman408511d2016-09-10 16:12:02 -040021 while (__atomic_load_n(&impl_, __ATOMIC_SEQ_CST) == 0) {
22 const int ret = futex_wait(&impl_);
23 if (ret != 0) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070024 CHECK_EQ(-1, ret);
25 PLOG(FATAL) << "futex_wait(" << &impl_ << ") failed";
Brian Silverman408511d2016-09-10 16:12:02 -040026 }
27 }
Brian Silvermanf5f34902015-03-29 17:57:59 -040028}
29
Austin Schuhf2a50ba2016-12-24 16:16:26 -080030bool Event::WaitTimeout(monotonic_clock::duration timeout) {
31 ::std::chrono::seconds sec =
32 ::std::chrono::duration_cast<::std::chrono::seconds>(timeout);
33 ::std::chrono::nanoseconds nsec =
34 ::std::chrono::duration_cast<::std::chrono::nanoseconds>(timeout - sec);
35 struct timespec timeout_timespec;
36 timeout_timespec.tv_sec = sec.count();
37 timeout_timespec.tv_nsec = nsec.count();
Brian Silverman408511d2016-09-10 16:12:02 -040038 while (true) {
39 if (__atomic_load_n(&impl_, __ATOMIC_SEQ_CST) != 0) {
40 return true;
41 }
42 const int ret = futex_wait_timeout(&impl_, &timeout_timespec);
43 if (ret != 0) {
44 if (ret == 2) return false;
Alex Perrycb7da4b2019-08-28 19:35:56 -070045 CHECK_EQ(-1, ret);
46 PLOG(FATAL) << "futex_wait(" << &impl_ << ") failed";
Brian Silverman408511d2016-09-10 16:12:02 -040047 }
48 }
Brian Silverman30608942015-04-08 19:16:46 -040049}
50
Brian Silvermanf5f34902015-03-29 17:57:59 -040051// We're not going to expose the number woken because that's not easily portable
52// to condition variable-based implementations.
53void Event::Set() {
54 if (futex_set(&impl_) == -1) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070055 PLOG(FATAL) << "futex_set(" << &impl_ << ") failed";
Brian Silvermanf5f34902015-03-29 17:57:59 -040056 }
57}
58
Brian Silverman7b266d92021-02-17 21:24:02 -080059bool Event::Clear() { return !futex_unset(&impl_); }
Brian Silvermanf5f34902015-03-29 17:57:59 -040060
61} // namespace aos