projects
/
folly.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
atomic_shared_ptr
[folly.git]
/
folly
/
experimental
/
EventCount.h
diff --git
a/folly/experimental/EventCount.h
b/folly/experimental/EventCount.h
index a0c289dadcfec8785b97a44307c8c0a5a1cd04f5..ee5717d051ab013196082b81593ce7ad8cd4b768 100644
(file)
--- a/
folly/experimental/EventCount.h
+++ b/
folly/experimental/EventCount.h
@@
-1,5
+1,5
@@
/*
/*
- * Copyright 201
5
Facebook, Inc.
+ * Copyright 201
7
Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* 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.
*/
* limitations under the License.
*/
-#ifndef FOLLY_EXPERIMENTAL_EVENTCOUNT_H_
-#define FOLLY_EXPERIMENTAL_EVENTCOUNT_H_
+#pragma once
-#include <unistd.h>
-#include <syscall.h>
-#include <linux/futex.h>
-#include <sys/time.h>
-#include <cassert>
-#include <climits>
#include <atomic>
#include <atomic>
+#include <climits>
#include <thread>
#include <thread>
+#include <glog/logging.h>
+
#include <folly/Bits.h>
#include <folly/Likely.h>
#include <folly/Bits.h>
#include <folly/Likely.h>
+#include <folly/detail/Futex.h>
+#include <folly/portability/SysTime.h>
+#include <folly/portability/Unistd.h>
namespace folly {
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.
*
/**
* 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(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<uint64_t>) == 8, "bad platform");
+ static_assert(sizeof(detail::Futex<std::atomic>) == 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.
// 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)) {
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<int*>(&val_) + kEpochOffset,
-
FUTEX_WAKE, n, nullptr, nullptr, 0
);
+ (reinterpret_cast<detail::Futex<std::atomic>*>(&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);
// #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_) {
}
inline void EventCount::wait(Key key) noexcept {
while ((val_.load(std::memory_order_acquire) >> kEpochShift) == key.epoch_) {
- detail::futex(reinterpret_cast<int*>(&val_) + kEpochOffset,
-
FUTEX_WAIT, key.epoch_, nullptr, nullptr, 0
);
+ (reinterpret_cast<detail::Futex<std::atomic>*>(&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);
}
// 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 <class Condition>
}
template <class Condition>
@@
-210,5
+196,3
@@
void EventCount::await(Condition condition) {
}
} // namespace folly
}
} // namespace folly
-
-#endif /* FOLLY_EXPERIMENTAL_EVENTCOUNT_H_ */