@@ -215,7 +215,7 @@ namespace timestudy {
215215 void asyncWork (
216216 edm::StreamID id, edm::WaitingTaskWithArenaHolder iTask, long initTime, long workTime, long finishTime) {
217217 waitTimesPerStream_[id.value ()] = {{initTime, workTime, finishTime}};
218- waitingTaskPerStream_[ id.value ()] = std::move (iTask);
218+ waitingTaskPerStream_. at ( id.value ()) = std::move (iTask);
219219 {
220220 std::lock_guard<std::mutex> lk{mutex_};
221221 waitingStreams_.push_back (id.value ());
@@ -231,13 +231,15 @@ namespace timestudy {
231231 if (waitingStreams_.size () >= nWaitingEvents_) {
232232 return true ;
233233 }
234- // every running stream is now waiting
235- return waitingStreams_.size () == activeStreams_;
234+ // every running stream is now waiting but guard against spurious wakeups
235+ return !waitingStreams_. empty () and waitingStreams_.size () == activeStreams_;
236236 }
237237
238238 void threadWork () {
239239 while (not stopProcessing_.load ()) {
240240 std::vector<int > streamsToProcess;
241+ // preallocate to fixed size so there are no resizes
242+ streamsToProcess.reserve (waitTimesPerStream_.size ());
241243 {
242244 std::unique_lock<std::mutex> lk (mutex_);
243245 condition_.wait (lk, [this ]() { return readyToDoSomething (); });
@@ -266,6 +268,7 @@ namespace timestudy {
266268 }
267269 }
268270 waitingTaskPerStream_.clear ();
271+ waitingTaskPerStream_.resize (waitingTaskPerStream_.capacity ());
269272 }
270273 const unsigned int nWaitingEvents_;
271274 std::unique_ptr<std::thread> serverThread_;
0 commit comments