21 #include <condition_variable> 26 #include <glog/logging.h> 40 template <
template <
typename>
class Atom>
45 template <
template <
typename>
class Atom>
61 template <
template <
typename>
class Atom,
typename Clock,
typename Duration>
65 for (
int stress = 0; stress < 1000; ++stress) {
69 const auto deadline = time_point_cast<
Duration>(
70 Clock::now() + microseconds(1 << (stress % 20)));
88 const auto deadline = time_point_cast<
Duration>(
start + milliseconds(100));
90 LOG(INFO) <<
"Futex wait timed out after waiting for " 92 <<
"ms using clock with " << Duration::period::den
93 <<
" precision, should be ~100ms";
101 LOG(INFO) <<
"Futex wait with invalid deadline timed out after waiting for " 103 <<
"ms using clock with " << Duration::period::den
104 <<
" precision, should be ~0ms";
108 template <
typename Clock>
118 template <
template <
typename>
class Atom>
120 liveClockWaitUntilTests<Atom, system_clock, system_clock::duration>();
121 liveClockWaitUntilTests<Atom, steady_clock, steady_clock::duration>();
122 liveClockWaitUntilTests<Atom, steady_clock, coarse_steady_clock::duration>();
124 typedef duration<int64_t, std::ratio<1, 10000000>> decimicroseconds;
125 liveClockWaitUntilTests<Atom, system_clock, decimicroseconds>();
130 deterministicAtomicWaitUntilTests<system_clock>();
131 deterministicAtomicWaitUntilTests<steady_clock>();
132 deterministicAtomicWaitUntilTests<coarse_steady_clock>();
136 return a > b ? a - b : b -
a;
143 const int maxIters = 1000;
151 while (iter < maxIters) {
157 uint64_t b = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
163 if (
diff(a, b) <= delta &&
diff(b, c) <= delta &&
diff(a, c) <= 2 * delta) {
183 const uint64_t B = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
191 template <
template <
typename>
class Atom>
193 for (
auto delay = std::chrono::milliseconds(1);; delay *= 2) {
198 std::this_thread::sleep_for(delay);
202 LOG(INFO) <<
"delay=" << delay.count() <<
"_ms, success=" <<
success;
220 run_basic_tests<std::atomic>();
221 run_wait_until_tests<std::atomic>();
225 run_basic_tests<EmulatedFutexAtomic>();
226 run_wait_until_tests<EmulatedFutexAtomic>();
231 run_basic_tests<DeterministicAtomic>();
236 run_wake_blocked_test<std::atomic>();
240 run_wake_blocked_test<EmulatedFutexAtomic>();
int(* clock_gettime)(clockid_t, timespec *ts)
void run_wait_until_tests()
#define EXPECT_EQ(val1, val2)
std::chrono::steady_clock::time_point now()
Atom< std::uint32_t > Futex
void liveClockWaitUntilTests()
static std::thread thread(Func &&func, Args &&...args)
void deterministicAtomicWaitUntilTests()
FutexResult futexWait(const Futex *futex, uint32_t expected, uint32_t waitMask)
void run_basic_thread(Futex< Atom > &f)
static std::function< size_t(size_t)> uniform(uint64_t seed)
static const char *const value
FutexResult futexWaitUntil(const Futex *futex, uint32_t expected, std::chrono::time_point< Clock, Duration > const &deadline, uint32_t waitMask)
void run_system_clock_test()
void run_wait_until_tests< DeterministicAtomic >()
DeterministicSchedule DSched
void run_wake_blocked_test()
#define EXPECT_TRUE(condition)
uint64_t diff(uint64_t a, uint64_t b)
StatsClock::duration Duration
void run_steady_clock_test()
int bind(NetworkSocket s, const sockaddr *name, socklen_t namelen)
static void join(std::thread &child)
TEST(SequencedExecutor, CPUThreadPoolExecutor)
int futexWake(const Futex *futex, int count, uint32_t wakeMask)