1 /*------------------------------------------------------------------------
2 Junction: Concurrent data structures in C++
3 Copyright (c) 2016 Jeff Preshing
5 Distributed under the Simplified BSD License.
6 Original location: https://github.com/preshing/junction
8 This software is distributed WITHOUT ANY WARRANTY; without even the
9 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 See the LICENSE file for more information.
11 ------------------------------------------------------------------------*/
13 #ifndef JUNCTION_STRIPED_MANUALRESETEVENT_H
14 #define JUNCTION_STRIPED_MANUALRESETEVENT_H
16 #include <junction/Core.h>
18 #if JUNCTION_USE_STRIPING
20 //-----------------------------------
22 //-----------------------------------
23 #include <junction/striped/ConditionBank.h>
28 class ManualResetEvent {
30 JUNCTION_STRIPED_CONDITIONBANK_DEFINE_MEMBER()
31 static const u8 Signaled = 1;
32 static const u8 HasWaiters = 2;
33 turf::Atomic<u8> m_state;
36 ManualResetEvent(bool initialState = false) : m_state(initialState ? Signaled : 0) {
43 u8 prevState = m_state.fetchOr(Signaled, turf::Release); // Synchronizes-with the load in wait (fast path)
44 if (prevState & HasWaiters) {
45 ConditionPair& pair = JUNCTION_STRIPED_CONDITIONBANK_GET(this);
46 turf::LockGuard<turf::Mutex> guard(pair.mutex); // Prevents the wake from occuring in the middle of wait()'s critical section
47 pair.condVar.wakeAll();
51 bool isSignaled() const {
52 return m_state.load(turf::Relaxed) & Signaled;
56 TURF_ASSERT(0); // FIXME: implement it
60 u8 state = m_state.load(turf::Acquire); // Synchronizes-with the fetchOr in signal (fast path)
61 if ((state & Signaled) == 0) {
62 ConditionPair& pair = JUNCTION_STRIPED_CONDITIONBANK_GET(this);
63 turf::LockGuard<turf::Mutex> guard(pair.mutex);
65 // FIXME: Implement reusable AdaptiveBackoff class and apply it here
66 state = m_state.load(turf::Relaxed);
69 if (state != HasWaiters) {
70 TURF_ASSERT(state == 0);
71 if (!m_state.compareExchangeWeak(state, HasWaiters, turf::Relaxed, turf::Relaxed))
74 // The lock ensures signal can't wakeAll between the load and the wait
75 pair.condVar.wait(guard);
81 } // namespace striped
82 } // namespace junction
84 #else // JUNCTION_USE_STRIPING
86 //-----------------------------------
88 //-----------------------------------
89 #include <turf/ManualResetEvent.h>
93 typedef turf::ManualResetEvent ManualResetEvent;
94 } // namespace striped
95 } // namespace junction
97 #endif // JUNCTION_USE_STRIPING
99 #endif // JUNCTION_STRIPED_MANUALRESETEVENT_H