/*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2013-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <thread>
#include <glog/logging.h>
-#include <gtest/gtest.h>
-#include <time.h>
+
+#include <folly/portability/GTest.h>
+#include <folly/portability/Time.h>
using namespace folly::detail;
using namespace folly::test;
typedef DeterministicSchedule DSched;
-template <template<typename> class Atom>
+template <template <typename> class Atom>
void run_basic_thread(
Futex<Atom>& f) {
EXPECT_TRUE(f.futexWait(0));
}
-template <template<typename> class Atom>
+template <template <typename> class Atom>
void run_basic_tests() {
Futex<Atom> f(0);
DSched::join(thr);
}
-template <template<typename> class Atom, typename Clock, typename Duration>
+template <template <typename> class Atom, typename Clock, typename Duration>
void liveClockWaitUntilTests() {
Futex<Atom> f(0);
EXPECT_TRUE(res == FutexResult::TIMEDOUT || res == FutexResult::INTERRUPTED);
}
-template<template<typename> class Atom>
+template <template <typename> class Atom>
void run_wait_until_tests() {
liveClockWaitUntilTests<Atom, system_clock, system_clock::duration>();
liveClockWaitUntilTests<Atom, steady_clock, steady_clock::duration>();
EXPECT_TRUE(A <= B && B <= C);
}
+template <template <typename> class Atom>
+void run_wake_blocked_test() {
+ for (auto delay = std::chrono::milliseconds(1);; delay *= 2) {
+ bool success = false;
+ Futex<Atom> f(0);
+ auto thr = DSched::thread([&] { success = f.futexWait(0); });
+ /* sleep override */ std::this_thread::sleep_for(delay);
+ f.store(1);
+ f.futexWake(1);
+ DSched::join(thr);
+ LOG(INFO) << "delay=" << delay.count() << "_ms, success=" << success;
+ if (success) {
+ break;
+ }
+ }
+}
+
TEST(Futex, clock_source) {
run_system_clock_test();
run_basic_tests<DeterministicAtomic>();
run_wait_until_tests<DeterministicAtomic>();
}
+
+TEST(Futex, wake_blocked_live) {
+ run_wake_blocked_test<std::atomic>();
+}
+
+TEST(Futex, wake_blocked_emulated) {
+ run_wake_blocked_test<EmulatedFutexAtomic>();
+}