diff options
Diffstat (limited to 'test/std/thread/futures/futures.async/async.pass.cpp')
-rw-r--r-- | test/std/thread/futures/futures.async/async.pass.cpp | 185 |
1 files changed, 69 insertions, 116 deletions
diff --git a/test/std/thread/futures/futures.async/async.pass.cpp b/test/std/thread/futures/futures.async/async.pass.cpp index 2c1313b7a2f0..5cb824d48224 100644 --- a/test/std/thread/futures/futures.async/async.pass.cpp +++ b/test/std/thread/futures/futures.async/async.pass.cpp @@ -21,15 +21,22 @@ // future<typename result_of<F(Args...)>::type> // async(launch policy, F&& f, Args&&... args); + #include <future> +#include <atomic> #include <memory> #include <cassert> +#include "test_macros.h" + typedef std::chrono::high_resolution_clock Clock; typedef std::chrono::milliseconds ms; +std::atomic_bool invoked = ATOMIC_VAR_INIT(false); + int f0() { + invoked = true; std::this_thread::sleep_for(ms(200)); return 3; } @@ -38,163 +45,109 @@ int i = 0; int& f1() { + invoked = true; std::this_thread::sleep_for(ms(200)); return i; } void f2() { + invoked = true; std::this_thread::sleep_for(ms(200)); } -std::unique_ptr<int> f3(int i) +std::unique_ptr<int> f3(int j) { + invoked = true; std::this_thread::sleep_for(ms(200)); - return std::unique_ptr<int>(new int(i)); + return std::unique_ptr<int>(new int(j)); } std::unique_ptr<int> f4(std::unique_ptr<int>&& p) { + invoked = true; std::this_thread::sleep_for(ms(200)); return std::move(p); } -void f5(int i) +void f5(int j) { std::this_thread::sleep_for(ms(200)); - throw i; + throw j; } -int main() -{ - { - std::future<int> f = std::async(f0); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(f.get() == 3); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<int> f = std::async(std::launch::async, f0); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(f.get() == 3); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<int> f = std::async(std::launch::any, f0); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(f.get() == 3); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<int> f = std::async(std::launch::deferred, f0); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(f.get() == 3); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 > ms(100)); - } +template <class Ret, class CheckLamdba, class ...Args> +void test(CheckLamdba&& getAndCheckFn, bool IsDeferred, Args&&... args) { + // Reset global state. + invoked = false; - { - std::future<int&> f = std::async(f1); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(&f.get() == &i); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<int&> f = std::async(std::launch::async, f1); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(&f.get() == &i); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<int&> f = std::async(std::launch::any, f1); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(&f.get() == &i); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<int&> f = std::async(std::launch::deferred, f1); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(&f.get() == &i); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 > ms(100)); - } + // Create the future and wait + std::future<Ret> f = std::async(std::forward<Args>(args)...); + std::this_thread::sleep_for(ms(300)); - { - std::future<void> f = std::async(f2); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - f.get(); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<void> f = std::async(std::launch::async, f2); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - f.get(); - Clock::time_point t1 = Clock::now(); + // Check that deferred async's have not invoked the function. + assert(invoked == !IsDeferred); + + // Time the call to f.get() and check that the returned value matches + // what is expected. + Clock::time_point t0 = Clock::now(); + assert(getAndCheckFn(f)); + Clock::time_point t1 = Clock::now(); + + // If the async is deferred it should take more than 100ms, otherwise + // it should take less than 100ms. + if (IsDeferred) { + assert(t1-t0 > ms(100)); + } else { assert(t1-t0 < ms(100)); } +} + +int main() +{ + // The default launch policy is implementation defined. libc++ defines + // it to be std::launch::async. + bool DefaultPolicyIsDeferred = false; + bool DPID = DefaultPolicyIsDeferred; + + std::launch AnyPolicy = std::launch::async | std::launch::deferred; + LIBCPP_ASSERT(AnyPolicy == std::launch::any); + { - std::future<void> f = std::async(std::launch::any, f2); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - f.get(); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); + auto checkInt = [](std::future<int>& f) { return f.get() == 3; }; + test<int>(checkInt, DPID, f0); + test<int>(checkInt, false, std::launch::async, f0); + test<int>(checkInt, true, std::launch::deferred, f0); + test<int>(checkInt, DPID, AnyPolicy, f0); } { - std::future<void> f = std::async(std::launch::deferred, f2); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - f.get(); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 > ms(100)); + auto checkIntRef = [&](std::future<int&>& f) { return &f.get() == &i; }; + test<int&>(checkIntRef, DPID, f1); + test<int&>(checkIntRef, false, std::launch::async, f1); + test<int&>(checkIntRef, true, std::launch::deferred, f1); + test<int&>(checkIntRef, DPID, AnyPolicy, f1); } - { - std::future<std::unique_ptr<int>> f = std::async(f3, 3); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(*f.get() == 3); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); + auto checkVoid = [](std::future<void>& f) { f.get(); return true; }; + test<void>(checkVoid, DPID, f2); + test<void>(checkVoid, false, std::launch::async, f2); + test<void>(checkVoid, true, std::launch::deferred, f2); + test<void>(checkVoid, DPID, AnyPolicy, f2); } - { - std::future<std::unique_ptr<int>> f = - std::async(f4, std::unique_ptr<int>(new int(3))); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(*f.get() == 3); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); + using Ret = std::unique_ptr<int>; + auto checkUPtr = [](std::future<Ret>& f) { return *f.get() == 3; }; + test<Ret>(checkUPtr, DPID, f3, 3); + test<Ret>(checkUPtr, DPID, f4, std::unique_ptr<int>(new int(3))); } - { std::future<void> f = std::async(f5, 3); std::this_thread::sleep_for(ms(300)); - try { f.get(); assert (false); } catch ( int ex ) {} + try { f.get(); assert (false); } catch ( int ) {} } - { std::future<void> f = std::async(std::launch::deferred, f5, 3); std::this_thread::sleep_for(ms(300)); - try { f.get(); assert (false); } catch ( int ex ) {} + try { f.get(); assert (false); } catch ( int ) {} } - } |