blob: 1b60362e2702d7195fc73e73b59c7fcd70f94fb7 [file] [log] [blame]
#include "aos/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