Message ID | 20180107205532.13138-2-mac@mcrowe.com |
---|---|
State | New |
Headers | show |
Series | Make std::future::wait_* use std::chrono::steady_clock when required | expand |
On 07/01/18 20:55 +0000, Mike Crowe wrote: >Add tests for waiting for the future using both std::chrono::steady_clock >and std::chrono::system_clock in preparation for dealing with those clocks >properly in futex.cc. >--- > libstdc++-v3/testsuite/30_threads/async/async.cc | 36 ++++++++++++++++++++++++ > 1 file changed, 36 insertions(+) > >diff --git a/libstdc++-v3/testsuite/30_threads/async/async.cc b/libstdc++-v3/testsuite/30_threads/async/async.cc >index 8071cb133fc..7326c5f7cd6 100644 >--- a/libstdc++-v3/testsuite/30_threads/async/async.cc >+++ b/libstdc++-v3/testsuite/30_threads/async/async.cc >@@ -52,17 +52,53 @@ void test02() > VERIFY( status == std::future_status::timeout ); > status = f1.wait_until(std::chrono::system_clock::now()); > VERIFY( status == std::future_status::timeout ); >+ status = f1.wait_until(std::chrono::steady_clock::now()); >+ VERIFY( status == std::future_status::timeout ); > l.unlock(); // allow async thread to proceed > f1.wait(); // wait for it to finish > status = f1.wait_for(std::chrono::milliseconds(0)); > VERIFY( status == std::future_status::ready ); > status = f1.wait_until(std::chrono::system_clock::now()); > VERIFY( status == std::future_status::ready ); >+ status = f1.wait_until(std::chrono::steady_clock::now()); >+ VERIFY( status == std::future_status::ready ); >+} >+ >+void work03() >+{ >+ std::this_thread::sleep_for(std::chrono::seconds(15)); I don't think we want 15s - 20s pauses in the testsuite. Could the sleep_for be 5s, with waits of 500ms, 1s, and then 10s, so the expected wait is only 5s? I don't think it's the end of the world if the test occasionally fails on very loaded machines. >+} >+ >+// This test is slow in order to try and avoid failing on a loaded >+// machine. Nevertheless, it could still fail if the kernel decides >+// not to schedule us for several seconds. It also assumes that no-one >+// will change CLOCK_REALTIME whilst the test is running. >+template<typename CLOCK> >+void test03() >+{ >+ auto const start = CLOCK::now(); >+ future<void> f1 = async(launch::async, &work03); >+ std::future_status status; >+ >+ status = f1.wait_for(std::chrono::seconds(5)); >+ VERIFY( status == std::future_status::timeout ); >+ >+ status = f1.wait_until(start + std::chrono::seconds(10)); >+ VERIFY( status == std::future_status::timeout ); >+ >+ status = f1.wait_until(start + std::chrono::seconds(25)); >+ VERIFY( status == std::future_status::ready ); >+ >+ auto const elapsed = CLOCK::now() - start; >+ VERIFY( elapsed >= std::chrono::seconds(15) ); >+ VERIFY( elapsed < std::chrono::seconds(20) ); > } > > int main() > { > test01(); > test02(); >+ test03<std::chrono::system_clock>(); >+ test03<std::chrono::steady_clock>(); > return 0; > } >-- >2.11.0 > >
diff --git a/libstdc++-v3/testsuite/30_threads/async/async.cc b/libstdc++-v3/testsuite/30_threads/async/async.cc index 8071cb133fc..7326c5f7cd6 100644 --- a/libstdc++-v3/testsuite/30_threads/async/async.cc +++ b/libstdc++-v3/testsuite/30_threads/async/async.cc @@ -52,17 +52,53 @@ void test02() VERIFY( status == std::future_status::timeout ); status = f1.wait_until(std::chrono::system_clock::now()); VERIFY( status == std::future_status::timeout ); + status = f1.wait_until(std::chrono::steady_clock::now()); + VERIFY( status == std::future_status::timeout ); l.unlock(); // allow async thread to proceed f1.wait(); // wait for it to finish status = f1.wait_for(std::chrono::milliseconds(0)); VERIFY( status == std::future_status::ready ); status = f1.wait_until(std::chrono::system_clock::now()); VERIFY( status == std::future_status::ready ); + status = f1.wait_until(std::chrono::steady_clock::now()); + VERIFY( status == std::future_status::ready ); +} + +void work03() +{ + std::this_thread::sleep_for(std::chrono::seconds(15)); +} + +// This test is slow in order to try and avoid failing on a loaded +// machine. Nevertheless, it could still fail if the kernel decides +// not to schedule us for several seconds. It also assumes that no-one +// will change CLOCK_REALTIME whilst the test is running. +template<typename CLOCK> +void test03() +{ + auto const start = CLOCK::now(); + future<void> f1 = async(launch::async, &work03); + std::future_status status; + + status = f1.wait_for(std::chrono::seconds(5)); + VERIFY( status == std::future_status::timeout ); + + status = f1.wait_until(start + std::chrono::seconds(10)); + VERIFY( status == std::future_status::timeout ); + + status = f1.wait_until(start + std::chrono::seconds(25)); + VERIFY( status == std::future_status::ready ); + + auto const elapsed = CLOCK::now() - start; + VERIFY( elapsed >= std::chrono::seconds(15) ); + VERIFY( elapsed < std::chrono::seconds(20) ); } int main() { test01(); test02(); + test03<std::chrono::system_clock>(); + test03<std::chrono::steady_clock>(); return 0; }