12
12
#include < algorithm>
13
13
#include < vector>
14
14
15
- #include < boost/thread/condition_variable.hpp>
16
- #include < boost/thread/mutex.hpp>
17
-
18
15
template <typename T>
19
16
class CCheckQueueControl ;
20
17
@@ -33,58 +30,58 @@ class CCheckQueue
33
30
{
34
31
private:
35
32
// ! Mutex to protect the inner state
36
- boost::mutex mutex ;
33
+ Mutex m_mutex ;
37
34
38
35
// ! Worker threads block on this when out of work
39
- boost ::condition_variable condWorker ;
36
+ std ::condition_variable m_worker_cv ;
40
37
41
38
// ! Master thread blocks on this when out of work
42
- boost ::condition_variable condMaster ;
39
+ std ::condition_variable m_master_cv ;
43
40
44
41
// ! The queue of elements to be processed.
45
42
// ! As the order of booleans doesn't matter, it is used as a LIFO (stack)
46
- std::vector<T> queue;
43
+ std::vector<T> queue GUARDED_BY (m_mutex) ;
47
44
48
45
// ! The number of workers (including the master) that are idle.
49
- int nIdle{0 };
46
+ int nIdle GUARDED_BY (m_mutex) {0 };
50
47
51
48
// ! The total number of workers (including the master).
52
- int nTotal{0 };
49
+ int nTotal GUARDED_BY (m_mutex) {0 };
53
50
54
51
// ! The temporary evaluation result.
55
- bool fAllOk {true };
52
+ bool fAllOk GUARDED_BY (m_mutex) {true };
56
53
57
54
/* *
58
55
* Number of verifications that haven't completed yet.
59
56
* This includes elements that are no longer queued, but still in the
60
57
* worker's own batches.
61
58
*/
62
- unsigned int nTodo{0 };
59
+ unsigned int nTodo GUARDED_BY (m_mutex) {0 };
63
60
64
61
// ! The maximum number of elements to be processed in one batch
65
62
const unsigned int nBatchSize;
66
63
67
64
std::vector<std::thread> m_worker_threads;
68
- bool m_request_stop{false };
65
+ bool m_request_stop GUARDED_BY (m_mutex) {false };
69
66
70
67
/* * Internal function that does bulk of the verification work. */
71
68
bool Loop (bool fMaster )
72
69
{
73
- boost ::condition_variable& cond = fMaster ? condMaster : condWorker ;
70
+ std ::condition_variable& cond = fMaster ? m_master_cv : m_worker_cv ;
74
71
std::vector<T> vChecks;
75
72
vChecks.reserve (nBatchSize);
76
73
unsigned int nNow = 0 ;
77
74
bool fOk = true ;
78
75
do {
79
76
{
80
- boost::unique_lock<boost::mutex> lock (mutex );
77
+ WAIT_LOCK (m_mutex, lock);
81
78
// first do the clean-up of the previous loop run (allowing us to do it in the same critsect)
82
79
if (nNow) {
83
80
fAllOk &= fOk ;
84
81
nTodo -= nNow;
85
82
if (nTodo == 0 && !fMaster )
86
83
// We processed the last element; inform the master it can exit and return the result
87
- condMaster .notify_one ();
84
+ m_master_cv .notify_one ();
88
85
} else {
89
86
// first iteration
90
87
nTotal++;
@@ -115,7 +112,7 @@ class CCheckQueue
115
112
nNow = std::max (1U , std::min (nBatchSize, (unsigned int )queue.size () / (nTotal + nIdle + 1 )));
116
113
vChecks.resize (nNow);
117
114
for (unsigned int i = 0 ; i < nNow; i++) {
118
- // We want the lock on the mutex to be as short as possible, so swap jobs from the global
115
+ // We want the lock on the m_mutex to be as short as possible, so swap jobs from the global
119
116
// queue to the local batch vector instead of copying.
120
117
vChecks[i].swap (queue.back ());
121
118
queue.pop_back ();
@@ -133,7 +130,7 @@ class CCheckQueue
133
130
134
131
public:
135
132
// ! Mutex to ensure only one concurrent CCheckQueueControl
136
- boost::mutex ControlMutex ;
133
+ Mutex m_control_mutex ;
137
134
138
135
// ! Create a new check queue
139
136
explicit CCheckQueue (unsigned int nBatchSizeIn)
@@ -145,7 +142,7 @@ class CCheckQueue
145
142
void StartWorkerThreads (const int threads_num)
146
143
{
147
144
{
148
- boost::unique_lock<boost::mutex> lock (mutex );
145
+ LOCK (m_mutex );
149
146
nIdle = 0 ;
150
147
nTotal = 0 ;
151
148
fAllOk = true ;
@@ -168,32 +165,28 @@ class CCheckQueue
168
165
// ! Add a batch of checks to the queue
169
166
void Add (std::vector<T>& vChecks)
170
167
{
171
- boost::unique_lock<boost::mutex> lock (mutex );
168
+ LOCK (m_mutex );
172
169
for (T& check : vChecks) {
173
170
queue.push_back (T ());
174
171
check.swap (queue.back ());
175
172
}
176
173
nTodo += vChecks.size ();
177
174
if (vChecks.size () == 1 )
178
- condWorker .notify_one ();
175
+ m_worker_cv .notify_one ();
179
176
else if (vChecks.size () > 1 )
180
- condWorker .notify_all ();
177
+ m_worker_cv .notify_all ();
181
178
}
182
179
183
180
// ! Stop all of the worker threads.
184
181
void StopWorkerThreads ()
185
182
{
186
- {
187
- boost::unique_lock<boost::mutex> lock (mutex);
188
- m_request_stop = true ;
189
- }
190
- condWorker.notify_all ();
183
+ WITH_LOCK (m_mutex, m_request_stop = true );
184
+ m_worker_cv.notify_all ();
191
185
for (std::thread& t : m_worker_threads) {
192
186
t.join ();
193
187
}
194
188
m_worker_threads.clear ();
195
- boost::unique_lock<boost::mutex> lock (mutex);
196
- m_request_stop = false ;
189
+ WITH_LOCK (m_mutex, m_request_stop = false );
197
190
}
198
191
199
192
~CCheckQueue ()
@@ -222,7 +215,7 @@ class CCheckQueueControl
222
215
{
223
216
// passed queue is supposed to be unused, or nullptr
224
217
if (pqueue != nullptr ) {
225
- ENTER_CRITICAL_SECTION (pqueue->ControlMutex );
218
+ ENTER_CRITICAL_SECTION (pqueue->m_control_mutex );
226
219
}
227
220
}
228
221
@@ -246,7 +239,7 @@ class CCheckQueueControl
246
239
if (!fDone )
247
240
Wait ();
248
241
if (pqueue != nullptr ) {
249
- LEAVE_CRITICAL_SECTION (pqueue->ControlMutex );
242
+ LEAVE_CRITICAL_SECTION (pqueue->m_control_mutex );
250
243
}
251
244
}
252
245
};
0 commit comments