Schedule a task on the thread pool
| 400 | |
| 401 | // Schedule a task on the thread pool |
| 402 | void threadpool_scheduler::schedule(task_run_handle t) |
| 403 | { |
| 404 | detail::threadpool_data_wrapper wrapper = detail::get_threadpool_data_wrapper(); |
| 405 | |
| 406 | // Check if we are in the thread pool |
| 407 | if (wrapper.owning_threadpool == impl.get()) { |
| 408 | // Push the task onto our task queue |
| 409 | impl->thread_data[wrapper.thread_id].queue.push(std::move(t)); |
| 410 | |
| 411 | // If there are no sleeping threads, just return. We check outside the |
| 412 | // lock to avoid locking overhead in the fast path. |
| 413 | if (impl->num_waiters.load(std::memory_order_relaxed) == 0) |
| 414 | return; |
| 415 | |
| 416 | // Get a thread to wake up from the list |
| 417 | std::lock_guard<std::mutex> locked(impl->lock); |
| 418 | |
| 419 | // Check again if there are waiters |
| 420 | size_t num_waiters_val = impl->num_waiters.load(std::memory_order_relaxed); |
| 421 | if (num_waiters_val == 0) |
| 422 | return; |
| 423 | |
| 424 | // Pop a thread from the list and wake it up |
| 425 | impl->waiters[num_waiters_val - 1]->signal(detail::wait_type::task_available); |
| 426 | impl->num_waiters.store(num_waiters_val - 1, std::memory_order_relaxed); |
| 427 | } else { |
| 428 | std::lock_guard<std::mutex> locked(impl->lock); |
| 429 | |
| 430 | // Push task onto the public queue |
| 431 | impl->public_queue.push(std::move(t)); |
| 432 | |
| 433 | // Wake up a sleeping thread |
| 434 | size_t num_waiters_val = impl->num_waiters.load(std::memory_order_relaxed); |
| 435 | if (num_waiters_val == 0) |
| 436 | return; |
| 437 | impl->waiters[num_waiters_val - 1]->signal(detail::wait_type::task_available); |
| 438 | impl->num_waiters.store(num_waiters_val - 1, std::memory_order_relaxed); |
| 439 | } |
| 440 | } |
| 441 | |
| 442 | } // namespace async |
| 443 |
nothing calls this directly
no test coverage detected