| 126 | } |
| 127 | |
| 128 | void TaskQueue::barrier(const DispatchFunction& function) { |
| 129 | auto executeTime = std::chrono::steady_clock::now(); |
| 130 | |
| 131 | std::unique_lock<Mutex> lockGuard(_mutex); |
| 132 | auto id = insertTask(DispatchFunction(), executeTime, true); |
| 133 | |
| 134 | while (!_tasks.empty()) { |
| 135 | // Wait until we have no currently running tasks, and that the task at the front is our barrier task |
| 136 | if (_currentRunningTasks != 0 || _tasks.front().id != id) { |
| 137 | _condition.wait(lockGuard); |
| 138 | continue; |
| 139 | } |
| 140 | |
| 141 | // We have no running tasks, and our barrier task is at the front. |
| 142 | // We can now execute our barrier |
| 143 | _currentRunningTasks++; |
| 144 | lockGuard.unlock(); |
| 145 | function(); |
| 146 | lockGuard.lock(); |
| 147 | auto toDelete = lockFreeRemoveTask(id); |
| 148 | _currentRunningTasks--; |
| 149 | lockGuard.unlock(); |
| 150 | _condition.notifyAll(); |
| 151 | return; |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | DispatchFunction TaskQueue::nextTask(std::chrono::steady_clock::time_point maxTime, bool* shouldRun) { |
| 156 | std::unique_lock<Mutex> lockGuard(_mutex); |