1 2 // Copyright Oliver Kowalke 2013. 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 7 #include "boost/fiber/condition_variable.hpp" 8 9 #include "boost/fiber/context.hpp" 10 11 #ifdef BOOST_HAS_ABI_HEADERS 12 # include BOOST_ABI_PREFIX 13 #endif 14 15 namespace boost { 16 namespace fibers { 17 18 void notify_one()19condition_variable_any::notify_one() noexcept { 20 context * active_ctx = context::active(); 21 // get one context' from wait-queue 22 detail::spinlock_lock lk{ wait_queue_splk_ }; 23 while ( ! wait_queue_.empty() ) { 24 context * ctx = & wait_queue_.front(); 25 wait_queue_.pop_front(); 26 auto expected = reinterpret_cast< std::intptr_t >( this); 27 if ( ctx->twstatus.compare_exchange_strong( expected, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel) ) { 28 // notify context 29 active_ctx->schedule( ctx); 30 break; 31 } 32 if ( static_cast< std::intptr_t >( 0) == expected) { 33 // no timed-wait op. 34 // notify context 35 active_ctx->schedule( ctx); 36 break; 37 } 38 } 39 } 40 41 void notify_all()42condition_variable_any::notify_all() noexcept { 43 context * active_ctx = context::active(); 44 // get all context' from wait-queue 45 detail::spinlock_lock lk{ wait_queue_splk_ }; 46 // notify all context' 47 while ( ! wait_queue_.empty() ) { 48 context * ctx = & wait_queue_.front(); 49 wait_queue_.pop_front(); 50 auto expected = reinterpret_cast< std::intptr_t >( this); 51 if ( ctx->twstatus.compare_exchange_strong( expected, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel) ) { 52 // notify context 53 active_ctx->schedule( ctx); 54 } else if ( static_cast< std::intptr_t >( 0) == expected) { 55 // no timed-wait op. 56 // notify context 57 active_ctx->schedule( ctx); 58 } 59 } 60 } 61 62 }} 63 64 #ifdef BOOST_HAS_ABI_HEADERS 65 # include BOOST_ABI_SUFFIX 66 #endif 67