void fn1( boost::fibers::mutex & m, boost::fibers::condition_variable_any & cv) { m.lock(); BOOST_CHECK(test2 == 0); test1 = 1; cv.notify_one(); while (test2 == 0) { cv.wait(m); } BOOST_CHECK(test2 != 0); m.unlock(); }
void wait_fn( boost::fibers::mutex & mtx, boost::fibers::condition_variable_any & cond) { mtx.lock(); cond.wait( mtx); ++value; mtx.unlock(); }
void thread( unsigned int i, barrier * b) { bind_to_processor( i); boost::fibers::use_scheduling_algorithm< boost::fibers::algo::shared_work >(); b->wait(); lock_type lk( mtx); cnd.wait( lk, [](){ return done; }); BOOST_ASSERT( done); }
void thread( unsigned int idx, barrier * b) { boost::fibers::numa::pin_thread( idx); boost::fibers::use_scheduling_algorithm< boost::fibers::algo::shared_work >(); b->wait(); lock_type lk( mtx); cnd.wait( lk, [](){ return done; }); BOOST_ASSERT( done); }
void fn5( boost::fibers::mutex & m, boost::fibers::condition_variable_any & cv) { m.lock(); BOOST_CHECK(test2 == 0); test1 = 1; cv.notify_one(); std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); int count=0; cv.wait_for(m, ms(250), Pred(test2)); count++; std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); if (runs == 0) { BOOST_CHECK(t1 - t0 < ms(250+1000)); BOOST_CHECK(test2 != 0); } else { BOOST_CHECK(t1 - t0 - ms(250) < ms(count*250+2)); BOOST_CHECK(test2 == 0); } ++runs; m.unlock(); }
void fn3( boost::fibers::mutex & m, boost::fibers::condition_variable_any & cv) { m.lock(); BOOST_CHECK(test2 == 0); test1 = 1; cv.notify_one(); std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point t = t0 + ms(250); bool r = cv.wait_until(m, t, Pred(test2)); std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); if (runs == 0) { BOOST_CHECK(t1 - t0 < ms(250)); BOOST_CHECK(test2 != 0); BOOST_CHECK(r); } else { BOOST_CHECK(t1 - t0 - ms(250) < ms(250+2)); BOOST_CHECK(test2 == 0); BOOST_CHECK(!r); } ++runs; m.unlock(); }
void fn2( boost::fibers::mutex & m, boost::fibers::condition_variable_any & cv) { m.lock(); BOOST_CHECK(test2 == 0); test1 = 1; cv.notify_one(); std::chrono::system_clock::time_point t0 = std::chrono::system_clock::now(); std::chrono::system_clock::time_point t = t0 + ms(250); int count=0; while (test2 == 0 && cv.wait_until(m, t) == boost::fibers::cv_status::no_timeout) count++; std::chrono::system_clock::time_point t1 = std::chrono::system_clock::now(); if (runs == 0) { BOOST_CHECK(t1 - t0 < ms(250)); BOOST_CHECK(test2 != 0); } else { BOOST_CHECK(t1 - t0 - ms(250) < ms(count*250+5+1000)); BOOST_CHECK(test2 == 0); } ++runs; m.unlock(); }
int main() { try { boost::fibers::use_scheduling_algorithm< boost::fibers::algo::shared_work >(); unsigned int n = std::thread::hardware_concurrency(); barrier b( n); boost::fibers::numa::pin_thread( n - 1); std::size_t size{ 1000000 }; std::size_t div{ 10 }; std::vector< std::thread > threads; for ( unsigned int i = 1; i < n; ++i) { threads.emplace_back( thread, i - 1, & b); }; // Windows 10 and FreeBSD require a fiber stack of 8kb // otherwise the stack gets exhausted // stack requirements must be checked for other OS too #if BOOST_OS_WINDOWS || BOOST_OS_BSD allocator_type salloc{ 2*allocator_type::traits_type::page_size() }; #else allocator_type salloc{ allocator_type::traits_type::page_size() }; #endif std::uint64_t result{ 0 }; channel_type rc{ 2 }; b.wait(); time_point_type start{ clock_type::now() }; skynet( salloc, rc, 0, size, div); result = rc.value_pop(); if ( 499999500000 != result) { throw std::runtime_error("invalid result"); } auto duration = clock_type::now() - start; lock_type lk( mtx); done = true; lk.unlock(); cnd.notify_all(); for ( std::thread & t : threads) { t.join(); } std::cout << "duration: " << duration.count() / 1000000 << " ms" << std::endl; return EXIT_SUCCESS; } catch ( std::exception const& e) { std::cerr << "exception: " << e.what() << std::endl; } catch (...) { std::cerr << "unhandled exception" << std::endl; } return EXIT_FAILURE; }
int main() { try { boost::fibers::use_scheduling_algorithm< boost::fibers::algo::shared_work >(); unsigned int n = std::thread::hardware_concurrency(); barrier b( n); bind_to_processor( n - 1); std::size_t size{ 1000000 }; std::size_t div{ 10 }; std::vector< std::thread > threads; for ( unsigned int i = 1; i < n; ++i) { threads.push_back( std::thread( thread, i - 1, & b) ); }; allocator_type salloc{ allocator_type::traits_type::page_size() }; std::uint64_t result{ 0 }; duration_type duration{ duration_type::zero() }; channel_type rc{ 2 }; b.wait(); time_point_type start{ clock_type::now() }; skynet( salloc, rc, 0, size, div); result = rc.value_pop(); duration = clock_type::now() - start; std::cout << "Result: " << result << " in " << duration.count() / 1000000 << " ms" << std::endl; lock_type lk( mtx); done = true; lk.unlock(); cnd.notify_all(); for ( std::thread & t : threads) { t.join(); } std::cout << "done." << std::endl; return EXIT_SUCCESS; } catch ( std::exception const& e) { std::cerr << "exception: " << e.what() << std::endl; } catch (...) { std::cerr << "unhandled exception" << std::endl; } return EXIT_FAILURE; }
void notify_all_fn( boost::fibers::condition_variable_any & cond) { cond.notify_all(); }