Move event.h into ipc_lib
Makes tab completion a lot less annoying.
Change-Id: I0c905ba112c274d23b5f0277b9a5c2a8e4e238f6
diff --git a/aos/ipc_lib/event.cc b/aos/ipc_lib/event.cc
new file mode 100644
index 0000000..940dfbd
--- /dev/null
+++ b/aos/ipc_lib/event.cc
@@ -0,0 +1,56 @@
+#include "aos/ipc_lib/event.h"
+
+#include <chrono>
+
+#include "aos/type_traits/type_traits.h"
+#include "glog/logging.h"
+
+namespace aos {
+
+Event::Event() : impl_(0) {
+ static_assert(shm_ok<Event>::value,
+ "Event is not safe for use in shared memory.");
+}
+
+void Event::Wait() {
+ while (__atomic_load_n(&impl_, __ATOMIC_SEQ_CST) == 0) {
+ const int ret = futex_wait(&impl_);
+ if (ret != 0) {
+ CHECK_EQ(-1, ret);
+ PLOG(FATAL) << "futex_wait(" << &impl_ << ") failed";
+ }
+ }
+}
+
+bool Event::WaitTimeout(monotonic_clock::duration timeout) {
+ ::std::chrono::seconds sec =
+ ::std::chrono::duration_cast<::std::chrono::seconds>(timeout);
+ ::std::chrono::nanoseconds nsec =
+ ::std::chrono::duration_cast<::std::chrono::nanoseconds>(timeout - sec);
+ struct timespec timeout_timespec;
+ timeout_timespec.tv_sec = sec.count();
+ timeout_timespec.tv_nsec = nsec.count();
+ while (true) {
+ if (__atomic_load_n(&impl_, __ATOMIC_SEQ_CST) != 0) {
+ return true;
+ }
+ const int ret = futex_wait_timeout(&impl_, &timeout_timespec);
+ if (ret != 0) {
+ if (ret == 2) return false;
+ CHECK_EQ(-1, ret);
+ PLOG(FATAL) << "futex_wait(" << &impl_ << ") failed";
+ }
+ }
+}
+
+// We're not going to expose the number woken because that's not easily portable
+// to condition variable-based implementations.
+void Event::Set() {
+ if (futex_set(&impl_) == -1) {
+ PLOG(FATAL) << "futex_set(" << &impl_ << ") failed";
+ }
+}
+
+bool Event::Clear() { return !futex_unset(&impl_); }
+
+} // namespace aos