20 auto const helpers = workers > 0 ? workers - 1 : 0;
21 threads_.reserve(helpers);
22 for (
size_t thread = 0; thread < helpers; ++thread) {
23 threads_.emplace_back([
this] { serve(); });
30 std::lock_guard lock(mutex_);
34 for (
auto& thread : threads_) thread.join();
38 template <
typename Work>
40 if (
count == 0)
return;
41 auto run = [&](
size_t index) {
45 std::lock_guard lock(mutex_);
49 active_ = threads_.size();
54 std::unique_lock lock(mutex_);
55 done_.wait(lock, [&] {
return active_ == 0; });
61 for (
size_t index = next_++; index < count_; index = next_++) job_(index);
68 std::unique_lock lock(mutex_);
69 start_.wait(lock, [&] {
return stop_ || generation_ != seen; });
74 std::lock_guard lock(mutex_);
75 if (--active_ == 0) done_.notify_one();
79 std::vector<std::thread> threads_;
81 std::condition_variable start_, done_;
82 std::function<void(
size_t)> job_;
83 std::atomic<size_t> next_{0};
84 size_t count_ = 0, active_ = 0, generation_ = 0;