Commit 58399f25 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Switch the Baton template params

Summary: [Folly] Switch the `Baton` template params for consistency with `SaturatingSemaphore`.

Reviewed By: davidtgoldblatt

Differential Revision: D6591060

fbshipit-source-id: 44d6243d3185d95364a27e497216cc02fb3bc2e8
parent a72e7903
...@@ -40,7 +40,7 @@ namespace folly { ...@@ -40,7 +40,7 @@ namespace folly {
/// This is basically a stripped-down semaphore that supports only a /// This is basically a stripped-down semaphore that supports only a
/// single call to sem_post and a single call to sem_wait. /// single call to sem_post and a single call to sem_wait.
/// ///
/// The non-blocking version (Blocking == false) provides more speed /// The non-blocking version (MayBlock == false) provides more speed
/// by using only load acquire and store release operations in the /// by using only load acquire and store release operations in the
/// critical path, at the cost of disallowing blocking and timing out. /// critical path, at the cost of disallowing blocking and timing out.
/// ///
...@@ -50,9 +50,7 @@ namespace folly { ...@@ -50,9 +50,7 @@ namespace folly {
/// DeterministicSchedule. By having a much more restrictive /// DeterministicSchedule. By having a much more restrictive
/// lifecycle we can also add a bunch of assertions that can help to /// lifecycle we can also add a bunch of assertions that can help to
/// catch race conditions ahead of time. /// catch race conditions ahead of time.
template < template <bool MayBlock = true, template <typename> class Atom = std::atomic>
template <typename> class Atom = std::atomic,
bool Blocking = true> // blocking vs spinning
struct Baton { struct Baton {
constexpr Baton() noexcept : state_(INIT) {} constexpr Baton() noexcept : state_(INIT) {}
...@@ -116,8 +114,8 @@ struct Baton { ...@@ -116,8 +114,8 @@ struct Baton {
/// destruction or reset()) there can be at most one call to post(), /// destruction or reset()) there can be at most one call to post(),
/// in the single poster version. Any thread may call post(). /// in the single poster version. Any thread may call post().
void post() noexcept { void post() noexcept {
if (!Blocking) { if (!MayBlock) {
/// Non-blocking version /// Spin-only version
/// ///
assert([&] { assert([&] {
auto state = state_.load(std::memory_order_relaxed); auto state = state_.load(std::memory_order_relaxed);
...@@ -127,7 +125,7 @@ struct Baton { ...@@ -127,7 +125,7 @@ struct Baton {
return; return;
} }
/// Blocking versions /// May-block versions
/// ///
uint32_t before = state_.load(std::memory_order_acquire); uint32_t before = state_.load(std::memory_order_acquire);
...@@ -200,7 +198,7 @@ struct Baton { ...@@ -200,7 +198,7 @@ struct Baton {
FOLLY_ALWAYS_INLINE bool try_wait_for( FOLLY_ALWAYS_INLINE bool try_wait_for(
const std::chrono::duration<Rep, Period>& timeout) noexcept { const std::chrono::duration<Rep, Period>& timeout) noexcept {
static_assert( static_assert(
Blocking, "Non-blocking Baton does not support try_wait_for."); MayBlock, "Non-blocking Baton does not support try_wait_for.");
if (try_wait()) { if (try_wait()) {
return true; return true;
...@@ -225,7 +223,7 @@ struct Baton { ...@@ -225,7 +223,7 @@ struct Baton {
FOLLY_ALWAYS_INLINE bool try_wait_until( FOLLY_ALWAYS_INLINE bool try_wait_until(
const std::chrono::time_point<Clock, Duration>& deadline) noexcept { const std::chrono::time_point<Clock, Duration>& deadline) noexcept {
static_assert( static_assert(
Blocking, "Non-blocking Baton does not support try_wait_until."); MayBlock, "Non-blocking Baton does not support try_wait_until.");
if (try_wait()) { if (try_wait()) {
return true; return true;
...@@ -305,7 +303,7 @@ struct Baton { ...@@ -305,7 +303,7 @@ struct Baton {
return; return;
} }
if (!Blocking) { if (!MayBlock) {
while (!try_wait()) { while (!try_wait()) {
std::this_thread::yield(); std::this_thread::yield();
} }
......
...@@ -33,7 +33,7 @@ namespace folly { ...@@ -33,7 +33,7 @@ namespace folly {
template < template <
template <typename> class Atom = std::atomic, template <typename> class Atom = std::atomic,
class BatonType = Baton<Atom>> class BatonType = Baton<true, Atom>>
struct LifoSemImpl; struct LifoSemImpl;
/// LifoSem is a semaphore that wakes its waiters in a manner intended to /// LifoSem is a semaphore that wakes its waiters in a manner intended to
......
...@@ -30,21 +30,21 @@ using folly::detail::EmulatedFutexAtomic; ...@@ -30,21 +30,21 @@ using folly::detail::EmulatedFutexAtomic;
typedef DeterministicSchedule DSched; typedef DeterministicSchedule DSched;
BENCHMARK(baton_pingpong_blocking, iters) { BENCHMARK(baton_pingpong_blocking, iters) {
run_pingpong_test<std::atomic, true>(iters); run_pingpong_test<true, std::atomic>(iters);
} }
BENCHMARK(baton_pingpong_nonblocking, iters) { BENCHMARK(baton_pingpong_nonblocking, iters) {
run_pingpong_test<std::atomic, false>(iters); run_pingpong_test<false, std::atomic>(iters);
} }
BENCHMARK_DRAW_LINE() BENCHMARK_DRAW_LINE()
BENCHMARK(baton_pingpong_emulated_futex_blocking, iters) { BENCHMARK(baton_pingpong_emulated_futex_blocking, iters) {
run_pingpong_test<EmulatedFutexAtomic, true>(iters); run_pingpong_test<true, EmulatedFutexAtomic>(iters);
} }
BENCHMARK(baton_pingpong_emulated_futex_nonblocking, iters) { BENCHMARK(baton_pingpong_emulated_futex_nonblocking, iters) {
run_pingpong_test<EmulatedFutexAtomic, false>(iters); run_pingpong_test<false, EmulatedFutexAtomic>(iters);
} }
BENCHMARK_DRAW_LINE() BENCHMARK_DRAW_LINE()
......
...@@ -29,15 +29,15 @@ using folly::detail::EmulatedFutexAtomic; ...@@ -29,15 +29,15 @@ using folly::detail::EmulatedFutexAtomic;
/// Basic test /// Basic test
TEST(Baton, basic_blocking) { TEST(Baton, basic_blocking) {
run_basic_test<std::atomic, true>(); run_basic_test<true, std::atomic>();
run_basic_test<EmulatedFutexAtomic, true>(); run_basic_test<true, EmulatedFutexAtomic>();
run_basic_test<DeterministicAtomic, true>(); run_basic_test<true, DeterministicAtomic>();
} }
TEST(Baton, basic_nonblocking) { TEST(Baton, basic_nonblocking) {
run_basic_test<std::atomic, false>(); run_basic_test<false, std::atomic>();
run_basic_test<EmulatedFutexAtomic, false>(); run_basic_test<false, EmulatedFutexAtomic>();
run_basic_test<DeterministicAtomic, false>(); run_basic_test<false, DeterministicAtomic>();
} }
/// Ping pong tests /// Ping pong tests
...@@ -45,13 +45,13 @@ TEST(Baton, basic_nonblocking) { ...@@ -45,13 +45,13 @@ TEST(Baton, basic_nonblocking) {
TEST(Baton, pingpong_blocking) { TEST(Baton, pingpong_blocking) {
DSched sched(DSched::uniform(0)); DSched sched(DSched::uniform(0));
run_pingpong_test<DeterministicAtomic, true>(1000); run_pingpong_test<true, DeterministicAtomic>(1000);
} }
TEST(Baton, pingpong_nonblocking) { TEST(Baton, pingpong_nonblocking) {
DSched sched(DSched::uniform(0)); DSched sched(DSched::uniform(0));
run_pingpong_test<DeterministicAtomic, false>(1000); run_pingpong_test<false, DeterministicAtomic>(1000);
} }
/// Timed wait tests - Nonblocking Baton does not support try_wait_until() /// Timed wait tests - Nonblocking Baton does not support try_wait_until()
...@@ -107,13 +107,13 @@ TEST(Baton, timed_wait_steady_clock) { ...@@ -107,13 +107,13 @@ TEST(Baton, timed_wait_steady_clock) {
/// Try wait tests /// Try wait tests
TEST(Baton, try_wait_blocking) { TEST(Baton, try_wait_blocking) {
run_try_wait_tests<std::atomic, true>(); run_try_wait_tests<true, std::atomic>();
run_try_wait_tests<EmulatedFutexAtomic, true>(); run_try_wait_tests<true, EmulatedFutexAtomic>();
run_try_wait_tests<DeterministicAtomic, true>(); run_try_wait_tests<true, DeterministicAtomic>();
} }
TEST(Baton, try_wait_nonblocking) { TEST(Baton, try_wait_nonblocking) {
run_try_wait_tests<std::atomic, false>(); run_try_wait_tests<false, std::atomic>();
run_try_wait_tests<EmulatedFutexAtomic, false>(); run_try_wait_tests<false, EmulatedFutexAtomic>();
run_try_wait_tests<DeterministicAtomic, false>(); run_try_wait_tests<false, DeterministicAtomic>();
} }
...@@ -25,16 +25,16 @@ namespace test { ...@@ -25,16 +25,16 @@ namespace test {
typedef DeterministicSchedule DSched; typedef DeterministicSchedule DSched;
template <template <typename> class Atom, bool Blocking> template <bool MayBlock, template <typename> class Atom>
void run_basic_test() { void run_basic_test() {
Baton<Atom, Blocking> b; Baton<MayBlock, Atom> b;
b.post(); b.post();
b.wait(); b.wait();
} }
template <template <typename> class Atom, bool Blocking> template <bool MayBlock, template <typename> class Atom>
void run_pingpong_test(int numRounds) { void run_pingpong_test(int numRounds) {
using B = Baton<Atom, Blocking>; using B = Baton<MayBlock, Atom>;
B batons[17]; B batons[17];
B& a = batons[0]; B& a = batons[0];
B& b = batons[16]; // to get it on a different cache line B& b = batons[16]; // to get it on a different cache line
...@@ -55,7 +55,7 @@ void run_pingpong_test(int numRounds) { ...@@ -55,7 +55,7 @@ void run_pingpong_test(int numRounds) {
template <template <typename> class Atom, typename Clock> template <template <typename> class Atom, typename Clock>
void run_basic_timed_wait_tests() { void run_basic_timed_wait_tests() {
Baton<Atom> b; Baton<true, Atom> b;
b.post(); b.post();
// tests if early delivery works fine // tests if early delivery works fine
EXPECT_TRUE(b.try_wait_until(Clock::now())); EXPECT_TRUE(b.try_wait_until(Clock::now()));
...@@ -63,7 +63,7 @@ void run_basic_timed_wait_tests() { ...@@ -63,7 +63,7 @@ void run_basic_timed_wait_tests() {
template <template <typename> class Atom, typename Clock> template <template <typename> class Atom, typename Clock>
void run_timed_wait_tmo_tests() { void run_timed_wait_tmo_tests() {
Baton<Atom> b; Baton<true, Atom> b;
auto thr = DSched::thread([&] { auto thr = DSched::thread([&] {
bool rv = b.try_wait_until(Clock::now() + std::chrono::milliseconds(1)); bool rv = b.try_wait_until(Clock::now() + std::chrono::milliseconds(1));
...@@ -75,7 +75,7 @@ void run_timed_wait_tmo_tests() { ...@@ -75,7 +75,7 @@ void run_timed_wait_tmo_tests() {
template <template <typename> class Atom, typename Clock> template <template <typename> class Atom, typename Clock>
void run_timed_wait_regular_test() { void run_timed_wait_regular_test() {
Baton<Atom> b; Baton<true, Atom> b;
auto thr = DSched::thread([&] { auto thr = DSched::thread([&] {
// To wait forever we'd like to use time_point<Clock>::max, but // To wait forever we'd like to use time_point<Clock>::max, but
...@@ -104,9 +104,9 @@ void run_timed_wait_regular_test() { ...@@ -104,9 +104,9 @@ void run_timed_wait_regular_test() {
DSched::join(thr); DSched::join(thr);
} }
template <template <typename> class Atom, bool Blocking> template <bool MayBlock, template <typename> class Atom>
void run_try_wait_tests() { void run_try_wait_tests() {
Baton<Atom, Blocking> b; Baton<MayBlock, Atom> b;
EXPECT_FALSE(b.ready()); EXPECT_FALSE(b.ready());
EXPECT_FALSE(b.try_wait()); EXPECT_FALSE(b.try_wait());
b.post(); b.post();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment