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_QSBR_H
14 #define JUNCTION_QSBR_H
16 #include <junction/Core.h>
17 #include <turf/Mutex.h>
18 #include <turf/RaceDetector.h>
28 uptr param[4]; // Size limit found experimentally. Verified by assert below.
30 Action(void (*f)(void*), void* p, ureg paramSize) : func(f) {
31 TURF_ASSERT(paramSize <= sizeof(param)); // Verify size limit.
32 memcpy(¶m, p, paramSize);
44 Status() : inUse(1), wasIdle(0), nextFree(0) {
49 TURF_DEFINE_RACE_DETECTOR(m_flushRaceDetector)
50 std::vector<Status> m_status;
54 std::vector<Action> m_deferredActions;
55 std::vector<Action> m_pendingActions;
57 void onAllQuiescentStatesPassed(std::vector<Action>& callbacks);
62 QSBR() : m_freeIndex(-1), m_numContexts(0), m_remaining(0) {
64 Context createContext();
65 void destroyContext(Context context);
68 void enqueue(void (T::*pmf)(), T* target) {
72 static void thunk(void* param) {
73 Closure* self = (Closure*) param;
74 TURF_CALL_MEMBER (*self->target, self->pmf)();
77 Closure closure = {pmf, target};
78 turf::LockGuard<turf::Mutex> guard(m_mutex);
79 TURF_RACE_DETECT_GUARD(m_flushRaceDetector);
80 m_deferredActions.push_back(Action(Closure::thunk, &closure, sizeof(closure)));
83 void update(Context context);
87 extern QSBR DefaultQSBR;
91 #endif // JUNCTION_QSBR_H