DSPatch v.10.2.4
Loading...
Searching...
No Matches
ParallelCircuitThread.h
1/******************************************************************************
2DSPatch - The Refreshingly Simple C++ Dataflow Framework
3Copyright (c) 2024, Marcus Tomlinson
4
5BSD 2-Clause License
6
7Redistribution and use in source and binary forms, with or without
8modification, are permitted provided that the following conditions are met:
9
101. Redistributions of source code must retain the above copyright notice, this
11 list of conditions and the following disclaimer.
12
132. Redistributions in binary form must reproduce the above copyright notice,
14 this list of conditions and the following disclaimer in the documentation
15 and/or other materials provided with the distribution.
16
17THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27******************************************************************************/
28
29#pragma once
30
31#include <dspatch/Component.h>
32
33#ifdef _WIN32
34#define WIN32_LEAN_AND_MEAN
35#include <windows.h>
36#undef WIN32_LEAN_AND_MEAN
37#endif
38
39#include <condition_variable>
40#include <thread>
41
42namespace DSPatch
43{
44namespace internal
45{
46
48
66{
67public:
68 NONCOPYABLE( ParallelCircuitThread );
69
70 inline ParallelCircuitThread() = default;
71
72 // cppcheck-suppress missingMemberCopy
74 {
75 }
76
78 {
79 Stop();
80 }
81
82 inline void Start( std::vector<DSPatch::Component*>* components, int bufferNo, int threadNo, int threadCount )
83 {
84 _components = components;
85 _bufferNo = bufferNo;
86 _threadNo = threadNo;
87 _threadCount = threadCount;
88
89 _stop = false;
90 _gotSync = false;
91
92 _thread = std::thread( &ParallelCircuitThread::_Run, this );
93 }
94
95 inline void Stop()
96 {
97 _stop = true;
98
99 Resume();
100
101 if ( _thread.joinable() )
102 {
103 _thread.join();
104 }
105 }
106
107 inline void Sync()
108 {
109 std::unique_lock<std::mutex> lock( _syncMutex );
110
111 if ( !_gotSync ) // if haven't already got sync
112 {
113 _syncCondt.wait( lock ); // wait for sync
114 }
115 }
116
117 inline void Resume()
118 {
119 _gotSync = false; // reset the sync flag
120 _resumeCondt.notify_all();
121 }
122
123private:
124 inline void _Run()
125 {
126#ifdef _WIN32
127 SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_HIGHEST );
128#else
129 sched_param sch_params;
130 sch_params.sched_priority = sched_get_priority_max( SCHED_RR );
131 pthread_setschedparam( pthread_self(), SCHED_RR, &sch_params );
132#endif
133
134 if ( _components )
135 {
136 while ( !_stop )
137 {
138 {
139 std::unique_lock<std::mutex> lock( _syncMutex );
140
141 _gotSync = true; // set the sync flag
142 _syncCondt.notify_all();
143 _resumeCondt.wait( lock ); // wait for resume
144 }
145
146 // cppcheck-suppress knownConditionTrueFalse
147 if ( !_stop )
148 {
149 for ( auto it = _components->begin() + _threadNo; it < _components->end(); it += _threadCount )
150 {
151 ( *it )->TickParallel( _bufferNo );
152 }
153 }
154 }
155 }
156 }
157
158 std::thread _thread;
159 std::vector<DSPatch::Component*>* _components = nullptr;
160 int _bufferNo = 0;
161 int _threadNo = 0;
162 int _threadCount = 0;
163 bool _stop = false;
164 bool _gotSync = false;
165 std::mutex _syncMutex;
166 std::condition_variable _resumeCondt, _syncCondt;
167};
168
169} // namespace internal
170} // namespace DSPatch
Thread class for asynchronously ticking parallel circuit components.