X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=folly%2Fexperimental%2FEventCount.h;h=ee5717d051ab013196082b81593ce7ad8cd4b768;hb=bd0686484d15d1f36b04c23c2624bac49059220a;hp=a0c289dadcfec8785b97a44307c8c0a5a1cd04f5;hpb=275ca94d04e44f28cfa411668eb1c1dd8db90b80;p=folly.git diff --git a/folly/experimental/EventCount.h b/folly/experimental/EventCount.h index a0c289da..ee5717d0 100644 --- a/folly/experimental/EventCount.h +++ b/folly/experimental/EventCount.h @@ -1,5 +1,5 @@ /* - * Copyright 2015 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,33 +14,23 @@ * limitations under the License. */ -#ifndef FOLLY_EXPERIMENTAL_EVENTCOUNT_H_ -#define FOLLY_EXPERIMENTAL_EVENTCOUNT_H_ +#pragma once -#include -#include -#include -#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. * @@ -126,14 +116,10 @@ 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"); -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - static constexpr size_t kEpochOffset = 1; -#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - static constexpr size_t kEpochOffset = 0; // in units of sizeof(int) -#else -# error Your machine uses a weird endianness! -#endif + static constexpr size_t kEpochOffset = kIsLittleEndian ? 1 : 0; // val_ stores the epoch in the most significant 32 bits and the // waiter count in the least significant 32 bits. @@ -157,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); } } @@ -172,19 +158,19 @@ inline void EventCount::cancelWait() noexcept { // #waiters gets to 0, the less likely it is that we'll do spurious wakeups // (and thus system calls). uint64_t prev = val_.fetch_add(kSubWaiter, std::memory_order_seq_cst); - assert((prev & kWaiterMask) != 0); + DCHECK_NE((prev & kWaiterMask), 0); } 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 // (and thus system calls) uint64_t prev = val_.fetch_add(kSubWaiter, std::memory_order_seq_cst); - assert((prev & kWaiterMask) != 0); + DCHECK_NE((prev & kWaiterMask), 0); } template @@ -210,5 +196,3 @@ void EventCount::await(Condition condition) { } } // namespace folly - -#endif /* FOLLY_EXPERIMENTAL_EVENTCOUNT_H_ */