diff --git a/lib/include/srsran/common/task_scheduler.h b/lib/include/srsran/common/task_scheduler.h index fc0b5d3c5..c1a8b0004 100644 --- a/lib/include/srsran/common/task_scheduler.h +++ b/lib/include/srsran/common/task_scheduler.h @@ -13,6 +13,7 @@ #ifndef SRSRAN_TASK_SCHEDULER_H #define SRSRAN_TASK_SCHEDULER_H +#include "block_queue.h" #include "interfaces_common.h" #include "multiqueue.h" #include "thread_pool.h" @@ -24,7 +25,7 @@ class task_scheduler { public: explicit task_scheduler(uint32_t default_extern_tasks_size = 512, uint32_t nof_timers_prealloc = 100) : - external_tasks{default_extern_tasks_size}, timers{nof_timers_prealloc} + external_tasks{default_extern_tasks_size}, timers{nof_timers_prealloc}, internal_tasks(512) { background_queue = external_tasks.add_queue(); } @@ -49,7 +50,12 @@ public: } //! Enqueues internal task to be run in next tic - void defer_task(srsran::move_task_t func) { internal_tasks.push_back(std::move(func)); } + void defer_task(srsran::move_task_t func) + { + if (not internal_tasks.try_push(std::move(func))) { + srslog::fetch_basic_logger("COMN", false).warning("Couldn't add new internal task"); + } + } //! Defer the handling of the result of a background task to next tic void notify_background_task_result(srsran::move_task_t task) @@ -90,21 +96,20 @@ public: srsran::timer_handler* get_timer_handler() { return &timers; } private: + // Perform pending stack deferred tasks void run_all_internal_tasks() { - // Perform pending stack deferred tasks - // Note: Using a deque because tasks can enqueue new tasks, which would lead to - // reference invalidation in case of vector - while (not internal_tasks.empty()) { - internal_tasks.front()(); - internal_tasks.pop_front(); + srsran::move_task_t task{}; + while (internal_tasks.try_pop(task)) { + task(); } } - srsran::task_multiqueue external_tasks; - srsran::task_queue_handle background_queue; ///< Queue for handling the outcomes of tasks run in the background - srsran::timer_handler timers; - std::deque internal_tasks; ///< enqueues stack tasks from within main thread. Avoids locking + srsran::task_multiqueue external_tasks; + srsran::task_queue_handle background_queue; ///< Queue for handling the outcomes of tasks run in the background + srsran::timer_handler timers; + srsran::dyn_blocking_queue + internal_tasks; ///< enqueues stack tasks from within main thread. Avoids locking }; //! Task scheduler handle given to classes/functions running within the main control thread