[libcxx-commits] [libcxx] 1858953 - [libcxx testing] Remove ALLOW_RETRIES from two futures tests

David Zarzycki via libcxx-commits libcxx-commits at lists.llvm.org
Thu May 14 03:18:57 PDT 2020


Author: David Zarzycki
Date: 2020-05-14T06:18:23-04:00
New Revision: 1858953395d2e2d13f6e2e5642b45849c3c388aa

URL: https://github.com/llvm/llvm-project/commit/1858953395d2e2d13f6e2e5642b45849c3c388aa
DIFF: https://github.com/llvm/llvm-project/commit/1858953395d2e2d13f6e2e5642b45849c3c388aa.diff

LOG: [libcxx testing] Remove ALLOW_RETRIES from two futures tests

These two tests do not use the "thread sleeps X milliseconds" pattern
that other libcxx tests use, so all we can do in order to remove
ALLOW_RETRIES workaround is remove the assumption that measuring the
"quick" return of `wait()` is possible (it is not). Let the test harness
verify overall that `wait()` does not hang.

As a bonus, have the spin-waiting threads `yield()`, which is what well
behaved code should do.

Added: 
    

Modified: 
    libcxx/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp
    libcxx/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp b/libcxx/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp
index 9d4200e9f2f1..a2a4d80b39c3 100644
--- a/libcxx/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp
+++ b/libcxx/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp
@@ -9,8 +9,6 @@
 // UNSUPPORTED: libcpp-has-no-threads
 // UNSUPPORTED: c++98, c++03
 
-// ALLOW_RETRIES: 2
-
 // <future>
 
 // class shared_future<R>
@@ -32,104 +30,97 @@ std::atomic<WorkerThreadState> thread_state(WorkerThreadState::Uninitialized);
 
 void set_worker_thread_state(WorkerThreadState state)
 {
-    thread_state.store(state, std::memory_order_relaxed);
+  thread_state.store(state, std::memory_order_relaxed);
 }
 
 void wait_for_worker_thread_state(WorkerThreadState state)
 {
-    while (thread_state.load(std::memory_order_relaxed) != state);
+  while (thread_state.load(std::memory_order_relaxed) != state)
+    std::this_thread::yield();
 }
 
 void func1(std::promise<int> p)
 {
-    wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
-    p.set_value(3);
-    set_worker_thread_state(WorkerThreadState::Exiting);
+  wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+  p.set_value(3);
+  set_worker_thread_state(WorkerThreadState::Exiting);
 }
 
 int j = 0;
 
 void func3(std::promise<int&> p)
 {
-    wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
-    j = 5;
-    p.set_value(j);
-    set_worker_thread_state(WorkerThreadState::Exiting);
+  wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+  j = 5;
+  p.set_value(j);
+  set_worker_thread_state(WorkerThreadState::Exiting);
 }
 
 void func5(std::promise<void> p)
 {
-    wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
-    p.set_value();
-    set_worker_thread_state(WorkerThreadState::Exiting);
+  wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+  p.set_value();
+  set_worker_thread_state(WorkerThreadState::Exiting);
 }
 
 int main(int, char**)
 {
-    typedef std::chrono::high_resolution_clock Clock;
-    {
-        typedef int T;
-        std::promise<T> p;
-        std::shared_future<T> f = p.get_future();
-        std::thread(func1, std::move(p)).detach();
-        assert(f.valid());
-        assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
-        assert(f.valid());
-
-        // allow the worker thread to produce the result and wait until the worker is done
-        set_worker_thread_state(WorkerThreadState::AllowedToRun);
-        wait_for_worker_thread_state(WorkerThreadState::Exiting);
-
-        assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
-        assert(f.valid());
-        Clock::time_point t0 = Clock::now();
-        f.wait();
-        Clock::time_point t1 = Clock::now();
-        assert(f.valid());
-        assert(t1-t0 < ms(5));
-    }
-    {
-        typedef int& T;
-        std::promise<T> p;
-        std::shared_future<T> f = p.get_future();
-        std::thread(func3, std::move(p)).detach();
-        assert(f.valid());
-        assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
-        assert(f.valid());
-
-        // allow the worker thread to produce the result and wait until the worker is done
-        set_worker_thread_state(WorkerThreadState::AllowedToRun);
-        wait_for_worker_thread_state(WorkerThreadState::Exiting);
-
-        assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
-        assert(f.valid());
-        Clock::time_point t0 = Clock::now();
-        f.wait();
-        Clock::time_point t1 = Clock::now();
-        assert(f.valid());
-        assert(t1-t0 < ms(5));
-    }
-    {
-        typedef void T;
-        std::promise<T> p;
-        std::shared_future<T> f = p.get_future();
-        std::thread(func5, std::move(p)).detach();
-        assert(f.valid());
-        assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
-        assert(f.valid());
-
-        // allow the worker thread to produce the result and wait until the worker is done
-        set_worker_thread_state(WorkerThreadState::AllowedToRun);
-        wait_for_worker_thread_state(WorkerThreadState::Exiting);
-
-        assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
-        assert(f.valid());
-        Clock::time_point t0 = Clock::now();
-        f.wait();
-        Clock::time_point t1 = Clock::now();
-        assert(f.valid());
-        assert(t1-t0 < ms(5));
-    }
+  typedef std::chrono::high_resolution_clock Clock;
+
+  {
+    typedef int T;
+    std::promise<T> p;
+    std::shared_future<T> f = p.get_future();
+    std::thread(func1, std::move(p)).detach();
+    assert(f.valid());
+    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+    assert(f.valid());
+
+    // allow the worker thread to produce the result and wait until the worker is done
+    set_worker_thread_state(WorkerThreadState::AllowedToRun);
+    wait_for_worker_thread_state(WorkerThreadState::Exiting);
+
+    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+    assert(f.valid());
+    f.wait();
+    assert(f.valid());
+  }
+  {
+    typedef int& T;
+    std::promise<T> p;
+    std::shared_future<T> f = p.get_future();
+    std::thread(func3, std::move(p)).detach();
+    assert(f.valid());
+    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+    assert(f.valid());
+
+    // allow the worker thread to produce the result and wait until the worker is done
+    set_worker_thread_state(WorkerThreadState::AllowedToRun);
+    wait_for_worker_thread_state(WorkerThreadState::Exiting);
+
+    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+    assert(f.valid());
+    f.wait();
+    assert(f.valid());
+  }
+  {
+    typedef void T;
+    std::promise<T> p;
+    std::shared_future<T> f = p.get_future();
+    std::thread(func5, std::move(p)).detach();
+    assert(f.valid());
+    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+    assert(f.valid());
+
+    // allow the worker thread to produce the result and wait until the worker is done
+    set_worker_thread_state(WorkerThreadState::AllowedToRun);
+    wait_for_worker_thread_state(WorkerThreadState::Exiting);
+
+    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+    assert(f.valid());
+    f.wait();
+    assert(f.valid());
+  }
 
   return 0;
 }

diff  --git a/libcxx/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp b/libcxx/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp
index b91261cd27ee..e7c7a676b2e7 100644
--- a/libcxx/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp
+++ b/libcxx/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp
@@ -8,7 +8,6 @@
 //
 // UNSUPPORTED: libcpp-has-no-threads
 // UNSUPPORTED: c++98, c++03
-// ALLOW_RETRIES: 2
 
 // <future>
 
@@ -31,104 +30,96 @@ std::atomic<WorkerThreadState> thread_state(WorkerThreadState::Uninitialized);
 
 void set_worker_thread_state(WorkerThreadState state)
 {
-    thread_state.store(state, std::memory_order_relaxed);
+  thread_state.store(state, std::memory_order_relaxed);
 }
 
 void wait_for_worker_thread_state(WorkerThreadState state)
 {
-    while (thread_state.load(std::memory_order_relaxed) != state);
+  while (thread_state.load(std::memory_order_relaxed) != state)
+    std::this_thread::yield();
 }
 
 void func1(std::promise<int> p)
 {
-    wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
-    p.set_value(3);
-    set_worker_thread_state(WorkerThreadState::Exiting);
+  wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+  p.set_value(3);
+  set_worker_thread_state(WorkerThreadState::Exiting);
 }
 
 int j = 0;
 
 void func3(std::promise<int&> p)
 {
-    wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
-    j = 5;
-    p.set_value(j);
-    set_worker_thread_state(WorkerThreadState::Exiting);
+  wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+  j = 5;
+  p.set_value(j);
+  set_worker_thread_state(WorkerThreadState::Exiting);
 }
 
 void func5(std::promise<void> p)
 {
-    wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
-    p.set_value();
-    set_worker_thread_state(WorkerThreadState::Exiting);
+  wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+  p.set_value();
+  set_worker_thread_state(WorkerThreadState::Exiting);
 }
 
 int main(int, char**)
 {
-    typedef std::chrono::high_resolution_clock Clock;
-    {
-        typedef int T;
-        std::promise<T> p;
-        std::future<T> f = p.get_future();
-        std::thread(func1, std::move(p)).detach();
-        assert(f.valid());
-        assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
-        assert(f.valid());
-
-        // allow the worker thread to produce the result and wait until the worker is done
-        set_worker_thread_state(WorkerThreadState::AllowedToRun);
-        wait_for_worker_thread_state(WorkerThreadState::Exiting);
-
-        assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
-        assert(f.valid());
-        Clock::time_point t0 = Clock::now();
-        f.wait();
-        Clock::time_point t1 = Clock::now();
-        assert(f.valid());
-        assert(t1-t0 < ms(5));
-    }
-    {
-        typedef int& T;
-        std::promise<T> p;
-        std::future<T> f = p.get_future();
-        std::thread(func3, std::move(p)).detach();
-        assert(f.valid());
-        assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
-        assert(f.valid());
-
-        // allow the worker thread to produce the result and wait until the worker is done
-        set_worker_thread_state(WorkerThreadState::AllowedToRun);
-        wait_for_worker_thread_state(WorkerThreadState::Exiting);
-
-        assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
-        assert(f.valid());
-        Clock::time_point t0 = Clock::now();
-        f.wait();
-        Clock::time_point t1 = Clock::now();
-        assert(f.valid());
-        assert(t1-t0 < ms(5));
-    }
-    {
-        typedef void T;
-        std::promise<T> p;
-        std::future<T> f = p.get_future();
-        std::thread(func5, std::move(p)).detach();
-        assert(f.valid());
-        assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
-        assert(f.valid());
-
-        // allow the worker thread to produce the result and wait until the worker is done
-        set_worker_thread_state(WorkerThreadState::AllowedToRun);
-        wait_for_worker_thread_state(WorkerThreadState::Exiting);
-
-        assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
-        assert(f.valid());
-        Clock::time_point t0 = Clock::now();
-        f.wait();
-        Clock::time_point t1 = Clock::now();
-        assert(f.valid());
-        assert(t1-t0 < ms(5));
-    }
+  typedef std::chrono::high_resolution_clock Clock;
+  {
+    typedef int T;
+    std::promise<T> p;
+    std::future<T> f = p.get_future();
+    std::thread(func1, std::move(p)).detach();
+    assert(f.valid());
+    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+    assert(f.valid());
+
+    // allow the worker thread to produce the result and wait until the worker is done
+    set_worker_thread_state(WorkerThreadState::AllowedToRun);
+    wait_for_worker_thread_state(WorkerThreadState::Exiting);
+
+    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+    assert(f.valid());
+    f.wait();
+    assert(f.valid());
+  }
+  {
+    typedef int& T;
+    std::promise<T> p;
+    std::future<T> f = p.get_future();
+    std::thread(func3, std::move(p)).detach();
+    assert(f.valid());
+    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+    assert(f.valid());
+
+    // allow the worker thread to produce the result and wait until the worker is done
+    set_worker_thread_state(WorkerThreadState::AllowedToRun);
+    wait_for_worker_thread_state(WorkerThreadState::Exiting);
+
+    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+    assert(f.valid());
+    f.wait();
+    assert(f.valid());
+  }
+  {
+    typedef void T;
+    std::promise<T> p;
+    std::future<T> f = p.get_future();
+    std::thread(func5, std::move(p)).detach();
+    assert(f.valid());
+    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+    assert(f.valid());
+
+    // allow the worker thread to produce the result and wait until the worker is done
+    set_worker_thread_state(WorkerThreadState::AllowedToRun);
+    wait_for_worker_thread_state(WorkerThreadState::Exiting);
+
+    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+    assert(f.valid());
+    f.wait();
+    assert(f.valid());
+  }
 
   return 0;
 }


        


More information about the libcxx-commits mailing list