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