]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | |
19 | condition_variable_any::notify_one() noexcept { | |
b32b8144 | 20 | context * active_ctx = context::active(); |
7c673cae | 21 | // get one context' from wait-queue |
b32b8144 FG |
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 | std::intptr_t 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 before timeout | |
29 | intrusive_ptr_release( ctx); | |
30 | // notify context | |
31 | active_ctx->schedule( ctx); | |
32 | break; | |
33 | } else if ( static_cast< std::intptr_t >( 0) == expected) { | |
34 | // no timed-wait op. | |
35 | // notify context | |
36 | active_ctx->schedule( ctx); | |
37 | break; | |
38 | } else { | |
39 | // timed-wait op. | |
40 | // expected == -1: notify after timeout, same timed-wait op. | |
41 | // expected == <any>: notify after timeout, another timed-wait op. was already started | |
42 | intrusive_ptr_release( ctx); | |
43 | // re-schedule next | |
44 | } | |
7c673cae | 45 | } |
7c673cae FG |
46 | } |
47 | ||
48 | void | |
49 | condition_variable_any::notify_all() noexcept { | |
b32b8144 | 50 | context * active_ctx = context::active(); |
7c673cae | 51 | // get all context' from wait-queue |
b32b8144 | 52 | detail::spinlock_lock lk{ wait_queue_splk_ }; |
7c673cae FG |
53 | // notify all context' |
54 | while ( ! wait_queue_.empty() ) { | |
55 | context * ctx = & wait_queue_.front(); | |
56 | wait_queue_.pop_front(); | |
b32b8144 FG |
57 | std::intptr_t expected = reinterpret_cast< std::intptr_t >( this); |
58 | if ( ctx->twstatus.compare_exchange_strong( expected, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel) ) { | |
59 | // notify before timeout | |
60 | intrusive_ptr_release( ctx); | |
61 | // notify context | |
62 | active_ctx->schedule( ctx); | |
63 | } else if ( static_cast< std::intptr_t >( 0) == expected) { | |
64 | // no timed-wait op. | |
65 | // notify context | |
66 | active_ctx->schedule( ctx); | |
67 | } else { | |
68 | // timed-wait op. | |
69 | // expected == -1: notify after timeout, same timed-wait op. | |
70 | // expected == <any>: notify after timeout, another timed-wait op. was already started | |
71 | intrusive_ptr_release( ctx); | |
72 | // re-schedule next | |
73 | } | |
7c673cae FG |
74 | } |
75 | } | |
76 | ||
77 | }} | |
78 | ||
79 | #ifdef BOOST_HAS_ABI_HEADERS | |
80 | # include BOOST_ABI_SUFFIX | |
81 | #endif |