From: Christopher Dykes Date: Fri, 25 Nov 2016 23:04:03 +0000 (-0800) Subject: Allow the use of an emulated futex for EventCount X-Git-Tag: v2016.11.28.00~2 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=46e466274cf56a9cfefd2f7fbe55e4006638e8d2;p=folly.git Allow the use of an emulated futex for EventCount Summary: Otherwise it won't work under MSVC where we don't have Futexes. This is achieved by using the Futex API already used elsewhere in Folly. Reviewed By: yfeldblum Differential Revision: D4233517 fbshipit-source-id: d6ae6a34b2287cf485f8e4a316445a2ba746d1a7 --- diff --git a/folly/experimental/EventCount.h b/folly/experimental/EventCount.h index a9feddfd..b78e628f 100644 --- a/folly/experimental/EventCount.h +++ b/folly/experimental/EventCount.h @@ -16,30 +16,21 @@ #pragma once -#include -#include -#include #include +#include #include + #include #include #include +#include #include #include namespace folly { -namespace detail { - -inline int futex(int* uaddr, int op, int val, const timespec* timeout, - int* uaddr2, int val3) noexcept { - return syscall(SYS_futex, uaddr, op, val, timeout, uaddr2, val3); -} - -} // namespace detail - /** * Event count: a condition variable for lock free algorithms. * @@ -125,6 +116,8 @@ class EventCount { static_assert(sizeof(int) == 4, "bad platform"); static_assert(sizeof(uint32_t) == 4, "bad platform"); static_assert(sizeof(uint64_t) == 8, "bad platform"); + static_assert(sizeof(std::atomic) == 8, "bad platform"); + static_assert(sizeof(detail::Futex) == 4, "bad platform"); static constexpr size_t kEpochOffset = kIsLittleEndian ? 1 : 0; @@ -150,8 +143,8 @@ inline void EventCount::notifyAll() noexcept { inline void EventCount::doNotify(int n) noexcept { uint64_t prev = val_.fetch_add(kAddEpoch, std::memory_order_acq_rel); if (UNLIKELY(prev & kWaiterMask)) { - detail::futex(reinterpret_cast(&val_) + kEpochOffset, - FUTEX_WAKE, n, nullptr, nullptr, 0); + (reinterpret_cast*>(&val_) + kEpochOffset) + ->futexWake(n); } } @@ -170,8 +163,8 @@ inline void EventCount::cancelWait() noexcept { inline void EventCount::wait(Key key) noexcept { while ((val_.load(std::memory_order_acquire) >> kEpochShift) == key.epoch_) { - detail::futex(reinterpret_cast(&val_) + kEpochOffset, - FUTEX_WAIT, key.epoch_, nullptr, nullptr, 0); + (reinterpret_cast*>(&val_) + kEpochOffset) + ->futexWait(key.epoch_); } // memory_order_relaxed would suffice for correctness, but the faster // #waiters gets to 0, the less likely it is that we'll do spurious wakeups