Commit 61a434e9 authored by Lewis Baker's avatar Lewis Baker Committed by Facebook GitHub Bot

Only run Futex.clock_source test on Linux platforms

Summary:
On Linux platforms the folly::futexWait() functions are implemented using the
futex() syscall, which requires passing a timeout parameter that specifies a
an expiry time either in CLOCK_REALTIME or CLOCK_MONOTONIC.

The futexWait() implementation currently assumes that the std::chrono::system_clock
and std::chrono::steady_clock implementations are thin wrappers over these
clock types and that we can directly convert the .time_since_epoch() values to
a timespec value that we can pass to the futex() syscall.

The Futex.clock_source test is checking this assumption about the implementation
of the std::chrono clocks.

Unfortunately, this assumption does not hold on recent libc++ implementations for
Apple platforms, which now uses the CLOCK_UPTIME_RAW clock for the
std::chrono::steady_clock implementation and so this test was failing on the
Mac platforms.

However, since we aren't actually relying on this assumption on platforms other than
Linux, we can just disable this test for non-Linux platforms.

Reviewed By: yfeldblum

Differential Revision: D22075639

fbshipit-source-id: 229995ba7c01b52d1949ef5942774920876d0994
parent b77dcf05
......@@ -132,6 +132,32 @@ void run_wait_until_tests<DeterministicAtomic>() {
deterministicAtomicWaitUntilTests<coarse_steady_clock>();
}
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 = FutexResult::AWOKEN == futexWait(&f, 0); });
/* sleep override */ std::this_thread::sleep_for(delay);
f.store(1);
futexWake(&f, 1);
DSched::join(thr);
LOG(INFO) << "delay=" << delay.count() << "_ms, success=" << success;
if (success) {
break;
}
}
}
// Only Linux platforms currently use the futex() syscall.
// This syscall requires timeouts to either use CLOCK_REALTIME or
// CLOCK_MONOTONIC but the API we expose takes a std::chrono::system_clock or
// steady_clock. These just happen to be thin wrappers over
// CLOCK_REALTIME/CLOCK_MONOTONIC in current implementations, and we assume that
// this is the case. Check here that this is a valid assumption.
#ifdef __linux__
uint64_t diff(uint64_t a, uint64_t b) {
return a > b ? a - b : b - a;
}
......@@ -188,24 +214,6 @@ void run_steady_clock_test() {
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 = FutexResult::AWOKEN == futexWait(&f, 0); });
/* sleep override */ std::this_thread::sleep_for(delay);
f.store(1);
futexWake(&f, 1);
DSched::join(thr);
LOG(INFO) << "delay=" << delay.count() << "_ms, success=" << success;
if (success) {
break;
}
}
}
TEST(Futex, clock_source) {
run_system_clock_test();
......@@ -216,6 +224,8 @@ TEST(Futex, clock_source) {
}
}
#endif // __linux__
TEST(Futex, basic_live) {
run_basic_tests<std::atomic>();
run_wait_until_tests<std::atomic>();
......
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