| 21 | struct RunThread |
| 22 | { |
| 23 | void operator()(exec::tbb::tbb_thread_pool& pool, |
| 24 | std::size_t total_scheds, |
| 25 | std::size_t tid, |
| 26 | std::barrier<>& barrier, |
| 27 | #ifndef STDEXEC_NO_MONOTONIC_BUFFER_RESOURCE |
| 28 | std::span<char> buffer, |
| 29 | #endif |
| 30 | std::atomic<bool>& stop, |
| 31 | exec::numa_policy numa) |
| 32 | { |
| 33 | int numa_node = numa.thread_index_to_node(tid); |
| 34 | numa.bind_to_node(numa_node); |
| 35 | auto scheduler = pool.get_scheduler(); |
| 36 | std::mutex mut; |
| 37 | std::condition_variable cv; |
| 38 | while (true) |
| 39 | { |
| 40 | barrier.arrive_and_wait(); |
| 41 | if (stop.load()) |
| 42 | { |
| 43 | break; |
| 44 | } |
| 45 | #ifndef STDEXEC_NO_MONOTONIC_BUFFER_RESOURCE |
| 46 | pmr::monotonic_buffer_resource resource{buffer.data(), |
| 47 | buffer.size(), |
| 48 | pmr::null_memory_resource()}; |
| 49 | pmr::polymorphic_allocator<char> alloc(&resource); |
| 50 | auto [start, end] = exec::_pool_::even_share(total_scheds, tid, pool.available_parallelism()); |
| 51 | std::size_t scheds = end - start; |
| 52 | std::atomic<std::size_t> counter{scheds}; |
| 53 | auto env = stdexec::prop{stdexec::get_allocator, alloc}; |
| 54 | while (scheds) |
| 55 | { |
| 56 | exec::start_detached(stdexec::schedule(scheduler) |
| 57 | | stdexec::then( |
| 58 | [&] |
| 59 | { |
| 60 | auto prev = counter.fetch_sub(1); |
| 61 | if (prev == 1) |
| 62 | { |
| 63 | std::lock_guard lock{mut}; |
| 64 | cv.notify_one(); |
| 65 | } |
| 66 | }), |
| 67 | env); |
| 68 | --scheds; |
| 69 | } |
| 70 | #else |
| 71 | auto [start, end] = exec::_pool_::even_share(total_scheds, tid, pool.available_parallelism()); |
| 72 | std::size_t scheds = end - start; |
| 73 | std::atomic<std::size_t> counter{scheds}; |
| 74 | while (scheds) |
| 75 | { |
| 76 | exec::start_detached(stdexec::schedule(scheduler) |
| 77 | | stdexec::then( |
| 78 | [&] |
| 79 | { |
| 80 | auto prev = counter.fetch_sub(1); |
nothing calls this directly
no test coverage detected