| 459 | |
| 460 | #ifndef DOXYGEN_SKIP_THIS |
| 461 | void CPPScheduler::run_workloads(std::vector<IScheduler::Workload> &workloads) |
| 462 | { |
| 463 | // Mutex to ensure other threads won't interfere with the setup of the current thread's workloads |
| 464 | // Other thread's workloads will be scheduled after the current thread's workloads have finished |
| 465 | // This is not great because different threads workloads won't run in parallel but at least they |
| 466 | // won't interfere each other and deadlock. |
| 467 | arm_compute::lock_guard<std::mutex> lock(_impl->_run_workloads_mutex); |
| 468 | const unsigned int num_threads_to_use = std::min(_impl->num_threads(), static_cast<unsigned int>(workloads.size())); |
| 469 | if (num_threads_to_use < 1) |
| 470 | { |
| 471 | return; |
| 472 | } |
| 473 | // Re-adjust the mode if the actual number of threads to use is different from the number of threads created |
| 474 | _impl->auto_switch_mode(num_threads_to_use); |
| 475 | int num_threads_to_start = 0; |
| 476 | switch (_impl->mode()) |
| 477 | { |
| 478 | case CPPScheduler::Impl::Mode::Fanout: |
| 479 | { |
| 480 | num_threads_to_start = static_cast<int>(_impl->wake_fanout()) - 1; |
| 481 | break; |
| 482 | } |
| 483 | case CPPScheduler::Impl::Mode::Linear: |
| 484 | default: |
| 485 | { |
| 486 | num_threads_to_start = static_cast<int>(num_threads_to_use) - 1; |
| 487 | break; |
| 488 | } |
| 489 | } |
| 490 | ThreadFeeder feeder(num_threads_to_use, workloads.size()); |
| 491 | ThreadInfo info; |
| 492 | info.cpu_info = &cpu_info(); |
| 493 | info.num_threads = num_threads_to_use; |
| 494 | unsigned int t = 0; |
| 495 | auto thread_it = _impl->_threads.begin(); |
| 496 | // Set num_threads_to_use - 1 workloads to the threads as the remaining 1 is left to the main thread |
| 497 | for (; t < num_threads_to_use - 1; ++t, ++thread_it) |
| 498 | { |
| 499 | info.thread_id = t; |
| 500 | thread_it->set_workload(&workloads, feeder, info); |
| 501 | } |
| 502 | thread_it = _impl->_threads.begin(); |
| 503 | for (int i = 0; i < num_threads_to_start; ++i, ++thread_it) |
| 504 | { |
| 505 | thread_it->start(); |
| 506 | } |
| 507 | info.thread_id = t; // Set main thread's thread_id |
| 508 | std::exception_ptr last_exception = nullptr; |
| 509 | #ifndef ARM_COMPUTE_EXCEPTIONS_DISABLED |
| 510 | try |
| 511 | { |
| 512 | #endif /* ARM_COMPUTE_EXCEPTIONS_DISABLED */ |
| 513 | process_workloads(workloads, feeder, info); // Main thread processes workloads |
| 514 | #ifndef ARM_COMPUTE_EXCEPTIONS_DISABLED |
| 515 | } |
| 516 | catch (...) |
| 517 | { |
| 518 | last_exception = std::current_exception(); |
nothing calls this directly
no test coverage detected