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(
47 pair.mutex); // Prevents the wake from occuring in the middle of wait()'s critical section
48 pair.condVar.wakeAll();
52 bool isSignaled() const {
53 return m_state.load(turf::Relaxed) & Signaled;
57 TURF_ASSERT(0); // FIXME: implement it
61 u8 state = m_state.load(turf::Acquire); // Synchronizes-with the fetchOr in signal (fast path)
62 if ((state & Signaled) == 0) {
63 ConditionPair& pair = JUNCTION_STRIPED_CONDITIONBANK_GET(this);
64 turf::LockGuard<turf::Mutex> guard(pair.mutex);
66 // FIXME: Implement reusable AdaptiveBackoff class and apply it here
67 state = m_state.load(turf::Relaxed);
70 if (state != HasWaiters) {
71 TURF_ASSERT(state == 0);
72 if (!m_state.compareExchangeWeak(state, HasWaiters, turf::Relaxed, turf::Relaxed))
75 // The lock ensures signal can't wakeAll between the load and the wait
76 pair.condVar.wait(guard);
82 } // namespace striped
83 } // namespace junction
85 #else // JUNCTION_USE_STRIPING
87 //-----------------------------------
89 //-----------------------------------
90 #include <turf/ManualResetEvent.h>
94 typedef turf::ManualResetEvent ManualResetEvent;
95 } // namespace striped
96 } // namespace junction
98 #endif // JUNCTION_USE_STRIPING
100 #endif // JUNCTION_STRIPED_MANUALRESETEVENT_H