#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #include #include // -------------------------------------------------------- // Testcase: Async // -------------------------------------------------------- void async(unsigned W) { tf::Executor executor(W); std::vector> fus; std::atomic counter(0); int N = 100000; for(int i=0; i> fus; std::atomic counter(0); int N = 100000; for(int i=0; i executors(N); std::atomic counter(0); auto check_wid = [&](unsigned e){ for(size_t i=0; i counter(0); int N = 10000; for(int i=0; i counter{0}; auto A = taskflow.emplace( [&](){ counter.fetch_add(1, std::memory_order_relaxed); } ); auto B = taskflow.emplace( [&](){ counter.fetch_add(1, std::memory_order_relaxed); } ); taskflow.emplace( [&](){ counter.fetch_add(1, std::memory_order_relaxed); } ); auto S1 = taskflow.emplace([&] (tf::Subflow& sf){ for(int i=0; i<1000; i++) { sf.async([&](){ counter.fetch_add(1, std::memory_order_relaxed); }); } }); auto S2 = taskflow.emplace([&] (tf::Subflow& sf){ sf.emplace([&](){ counter.fetch_add(1, std::memory_order_relaxed); }); for(int i=0; i<1000; i++) { sf.async([&](){ counter.fetch_add(1, std::memory_order_relaxed); }); } }); taskflow.emplace([&] (tf::Subflow& sf){ sf.emplace([&](){ counter.fetch_add(1, std::memory_order_relaxed); }); for(int i=0; i<1000; i++) { sf.async([&](){ counter.fetch_add(1, std::memory_order_relaxed); }); } sf.join(); }); taskflow.emplace([&] (tf::Subflow& sf){ for(int i=0; i<1000; i++) { sf.async([&](){ counter.fetch_add(1, std::memory_order_relaxed); }); } sf.join(); }); A.precede(S1, S2); B.succeed(S1, S2); executor.run(taskflow).wait(); REQUIRE(counter == 4005); } TEST_CASE("SubflowAsync.1thread") { subflow_async(1); } TEST_CASE("SubflowAsync.3threads") { subflow_async(3); } TEST_CASE("SubflowAsync.11threads") { subflow_async(11); } // -------------------------------------------------------- // Testcase: NestedSubflowAsync // -------------------------------------------------------- void nested_subflow_async(size_t W) { tf::Taskflow taskflow; tf::Executor executor(W); std::atomic counter{0}; taskflow.emplace([&](tf::Subflow& sf1){ for(int i=0; i<100; i++) { sf1.async([&](){ counter.fetch_add(1, std::memory_order_relaxed); }); } sf1.emplace([&](tf::Subflow& sf2){ for(int i=0; i<100; i++) { sf2.async([&](){ counter.fetch_add(1, std::memory_order_relaxed); }); sf1.async( [&](){ counter.fetch_add(1, std::memory_order_relaxed); } ); } sf2.emplace([&](tf::Subflow& sf3){ for(int i=0; i<100; i++) { sf3.silent_async( [&](){ counter.fetch_add(1, std::memory_order_relaxed); } ); sf2.silent_async([&](){ counter.fetch_add(1, std::memory_order_relaxed); }); sf1.silent_async([&](){ counter.fetch_add(1, std::memory_order_relaxed); }); } }); }); sf1.join(); REQUIRE(counter == 600); }); executor.run(taskflow).wait(); REQUIRE(counter == 600); } TEST_CASE("NestedSubflowAsync.1thread") { nested_subflow_async(1); } TEST_CASE("NestedSubflowAsync.3threads") { nested_subflow_async(3); } TEST_CASE("NestedSubflowAsync.11threads") { nested_subflow_async(11); } // -------------------------------------------------------- // Testcase: RuntimeAsync // -------------------------------------------------------- void runtime_async(size_t W) { tf::Taskflow taskflow; tf::Executor executor(W); std::atomic counter{0}; auto A = taskflow.emplace( [&](){ counter.fetch_add(1, std::memory_order_relaxed); } ); auto B = taskflow.emplace( [&](){ counter.fetch_add(1, std::memory_order_relaxed); } ); taskflow.emplace( [&](){ counter.fetch_add(1, std::memory_order_relaxed); } ); auto S1 = taskflow.emplace([&] (tf::Runtime& sf){ for(int i=0; i<1000; i++) { sf.silent_async( [&](){counter.fetch_add(1, std::memory_order_relaxed);} ); } sf.corun_all(); }); auto S2 = taskflow.emplace([&] (tf::Runtime& sf){ sf.silent_async([&](){ counter.fetch_add(1, std::memory_order_relaxed); }); for(int i=0; i<1000; i++) { sf.silent_async([&](){ counter.fetch_add(1, std::memory_order_relaxed); }); } sf.corun_all(); }); taskflow.emplace([&] (tf::Runtime& sf){ sf.silent_async([&](){ counter.fetch_add(1, std::memory_order_relaxed); }); for(int i=0; i<1000; i++) { sf.async( [&](){ counter.fetch_add(1, std::memory_order_relaxed); } ); } sf.corun_all(); }); taskflow.emplace([&] (tf::Runtime& sf){ for(int i=0; i<1000; i++) { sf.async([&](){ counter.fetch_add(1, std::memory_order_relaxed); }); } sf.corun_all(); }); A.precede(S1, S2); B.succeed(S1, S2); executor.run(taskflow).wait(); REQUIRE(counter == 4005); } TEST_CASE("RuntimeAsync.1thread") { runtime_async(1); } TEST_CASE("RuntimeAsync.3threads") { runtime_async(3); } TEST_CASE("RuntimeAsync.11threads") { runtime_async(11); }