\brief Create a thread pool and start all threads By default a thread pool will not create threads until they are actually needed. This can make it a bit difficult to reproduce certain issues. This creates a thread pool and then makes sure the threads are actually created before returning it.
| 44 | /// then makes sure the threads are actually created before |
| 45 | /// returning it. |
| 46 | Result<std::shared_ptr<ThreadPool>> MakePrimedThreadPool(int num_threads) { |
| 47 | ARROW_ASSIGN_OR_RAISE(std::shared_ptr<ThreadPool> thread_pool, |
| 48 | ThreadPool::Make(num_threads)); |
| 49 | int num_threads_running = 0; |
| 50 | std::mutex mutex; |
| 51 | std::condition_variable thread_gate; |
| 52 | std::condition_variable primer_gate; |
| 53 | for (int i = 0; i < num_threads; i++) { |
| 54 | // This shouldn't fail and, if it fails midway, we will have some threads |
| 55 | // still running if we do RETURN_NOT_OK so lets do ABORT_NOT_OK |
| 56 | ABORT_NOT_OK(thread_pool->Spawn([&] { |
| 57 | std::unique_lock<std::mutex> lk(mutex); |
| 58 | num_threads_running++; |
| 59 | primer_gate.notify_one(); |
| 60 | thread_gate.wait(lk); |
| 61 | })); |
| 62 | } |
| 63 | std::unique_lock<std::mutex> primer_lock(mutex); |
| 64 | primer_gate.wait(primer_lock, [&] { return num_threads_running == num_threads; }); |
| 65 | thread_gate.notify_all(); |
| 66 | primer_lock.unlock(); |
| 67 | thread_pool->WaitForIdle(); |
| 68 | return thread_pool; |
| 69 | } |
| 70 | |
| 71 | Status SlowTaskImpl(std::size_t, int64_t) { |
| 72 | SleepABit(); |
no test coverage detected