| 105 | } |
| 106 | |
| 107 | void TaskPool::ParallelFor(uint32_t count, const std::function<void(uint32_t, uint32_t)>& work) |
| 108 | { |
| 109 | if (count == 0) |
| 110 | { |
| 111 | return; |
| 112 | } |
| 113 | if (count == 1) |
| 114 | { |
| 115 | // Single-item shortcut: avoids scheduling overhead for the |
| 116 | // degenerate case landscape's nMiss==1 path already hand-coded. |
| 117 | work(0, 1); |
| 118 | return; |
| 119 | } |
| 120 | |
| 121 | std::lock_guard<std::mutex> lock(_submitMutex); |
| 122 | RangeTask task(count, work); |
| 123 | POSEIDON_TSAN_RELEASE(&task); // publish the caller's prior writes to the workers |
| 124 | _scheduler->AddTaskSetToPipe(&task); |
| 125 | _scheduler->WaitforTask(&task); |
| 126 | POSEIDON_TSAN_ACQUIRE(&task); // acquire every partition's writes before returning to the caller |
| 127 | } |
| 128 | |
| 129 | void TaskPool::Submit(std::function<void()> work) |
| 130 | { |
no outgoing calls
no test coverage detected