diff --git a/lib/include/srslte/common/task_scheduler.h b/lib/include/srslte/common/task_scheduler.h index a6b61df23..6ec40f505 100644 --- a/lib/include/srslte/common/task_scheduler.h +++ b/lib/include/srslte/common/task_scheduler.h @@ -46,7 +46,11 @@ public: } } - void stop() { background_tasks.stop(); } + void stop() + { + background_tasks.stop(); + external_tasks.reset(); + } srslte::timer_handler::unique_timer get_unique_timer() final { return timers.get_unique_timer(); } diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index 3c7e1d9fa..00f9692d7 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -24,6 +24,7 @@ #include "srslte/common/common.h" #include "srslte/common/log.h" +#include "srslte/common/task_scheduler.h" #include "srslte/interfaces/ue_interfaces.h" #include "srslte/upper/pdcp_entity_lte.h" @@ -32,7 +33,7 @@ namespace srslte { class pdcp : public srsue::pdcp_interface_rlc, public srsue::pdcp_interface_rrc { public: - pdcp(srslte::task_handler_interface* task_executor_, const char* logname); + pdcp(srslte::task_sched_handle task_sched_, const char* logname); virtual ~pdcp(); void init(srsue::rlc_interface_pdcp* rlc_, srsue::rrc_interface_pdcp* rrc_, srsue::gw_interface_pdcp* gw_); void stop(); @@ -66,11 +67,11 @@ public: void write_pdu_pcch(unique_byte_buffer_t sdu) override; private: - srsue::rlc_interface_pdcp* rlc = nullptr; - srsue::rrc_interface_pdcp* rrc = nullptr; - srsue::gw_interface_pdcp* gw = nullptr; - srslte::task_handler_interface* task_executor = nullptr; - srslte::log_ref pdcp_log; + srsue::rlc_interface_pdcp* rlc = nullptr; + srsue::rrc_interface_pdcp* rrc = nullptr; + srsue::gw_interface_pdcp* gw = nullptr; + srslte::task_sched_handle task_sched; + srslte::log_ref pdcp_log; std::map > pdcp_array, pdcp_array_mrb; diff --git a/lib/include/srslte/upper/pdcp_entity_base.h b/lib/include/srslte/upper/pdcp_entity_base.h index 476a51b2d..8140efca0 100644 --- a/lib/include/srslte/upper/pdcp_entity_base.h +++ b/lib/include/srslte/upper/pdcp_entity_base.h @@ -27,6 +27,7 @@ #include "srslte/common/interfaces_common.h" #include "srslte/common/logmap.h" #include "srslte/common/security.h" +#include "srslte/common/task_scheduler.h" #include "srslte/common/threads.h" #include "srslte/common/timers.h" #include "srslte/interfaces/pdcp_interface_types.h" @@ -59,7 +60,7 @@ static const char pdcp_d_c_text[PDCP_D_C_N_ITEMS][20] = {"Control PDU", "Data PD class pdcp_entity_base { public: - pdcp_entity_base(srslte::task_handler_interface* task_executor_, srslte::log_ref log_); + pdcp_entity_base(task_sched_handle task_sched_, srslte::log_ref log_); pdcp_entity_base(pdcp_entity_base&&) = default; virtual ~pdcp_entity_base(); virtual void reset() = 0; @@ -119,7 +120,7 @@ public: // RLC interface virtual void write_pdu(unique_byte_buffer_t pdu) = 0; - virtual void get_bearer_state(pdcp_lte_state_t* state) = 0; + virtual void get_bearer_state(pdcp_lte_state_t* state) = 0; virtual void set_bearer_state(const pdcp_lte_state_t& state) = 0; // COUNT, HFN and SN helpers @@ -128,8 +129,8 @@ public: uint32_t COUNT(uint32_t hfn, uint32_t sn); protected: - srslte::log_ref log; - srslte::task_handler_interface* task_executor = nullptr; + srslte::log_ref log; + srslte::task_sched_handle task_sched; bool active = false; uint32_t lcid = 0; diff --git a/lib/include/srslte/upper/pdcp_entity_lte.h b/lib/include/srslte/upper/pdcp_entity_lte.h index e7079d7f0..a332904bc 100644 --- a/lib/include/srslte/upper/pdcp_entity_lte.h +++ b/lib/include/srslte/upper/pdcp_entity_lte.h @@ -46,13 +46,13 @@ namespace srslte { class pdcp_entity_lte final : public pdcp_entity_base { public: - pdcp_entity_lte(srsue::rlc_interface_pdcp* rlc_, - srsue::rrc_interface_pdcp* rrc_, - srsue::gw_interface_pdcp* gw_, - srslte::task_handler_interface* task_executor_, - srslte::log_ref log_, - uint32_t lcid_, - pdcp_config_t cfg_); + pdcp_entity_lte(srsue::rlc_interface_pdcp* rlc_, + srsue::rrc_interface_pdcp* rrc_, + srsue::gw_interface_pdcp* gw_, + srslte::task_sched_handle task_sched_, + srslte::log_ref log_, + uint32_t lcid_, + pdcp_config_t cfg_); ~pdcp_entity_lte() override; void reset() override; void reestablish() override; diff --git a/lib/include/srslte/upper/pdcp_entity_nr.h b/lib/include/srslte/upper/pdcp_entity_nr.h index f98a00ac3..18478295e 100644 --- a/lib/include/srslte/upper/pdcp_entity_nr.h +++ b/lib/include/srslte/upper/pdcp_entity_nr.h @@ -28,6 +28,7 @@ #include "srslte/common/interfaces_common.h" #include "srslte/common/log.h" #include "srslte/common/security.h" +#include "srslte/common/task_scheduler.h" #include "srslte/common/threads.h" #include "srslte/interfaces/ue_interfaces.h" #include @@ -41,13 +42,13 @@ namespace srslte { class pdcp_entity_nr final : public pdcp_entity_base { public: - pdcp_entity_nr(srsue::rlc_interface_pdcp* rlc_, - srsue::rrc_interface_pdcp* rrc_, - srsue::gw_interface_pdcp* gw_, - srslte::task_handler_interface* task_executor_, - srslte::log_ref log_, - uint32_t lcid, - pdcp_config_t cfg_); + pdcp_entity_nr(srsue::rlc_interface_pdcp* rlc_, + srsue::rrc_interface_pdcp* rrc_, + srsue::gw_interface_pdcp* gw_, + srslte::task_sched_handle task_sched_, + srslte::log_ref log_, + uint32_t lcid, + pdcp_config_t cfg_); ~pdcp_entity_nr() final; void reset() final; void reestablish() final; diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index a253a7324..8c8bf652b 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -26,10 +26,7 @@ namespace srslte { -pdcp::pdcp(srslte::task_handler_interface* task_executor_, const char* logname) : - task_executor(task_executor_), - pdcp_log(logname) -{} +pdcp::pdcp(srslte::task_sched_handle task_sched_, const char* logname) : task_sched(task_sched_), pdcp_log(logname) {} pdcp::~pdcp() { @@ -110,13 +107,13 @@ void pdcp::add_bearer(uint32_t lcid, pdcp_config_t cfg) // create NR entity for 18bit SN length #ifdef HAVE_5GNR - entity.reset(new pdcp_entity_nr{rlc, rrc, gw, task_executor, pdcp_log, lcid, cfg}); + entity.reset(new pdcp_entity_nr{rlc, rrc, gw, task_sched, pdcp_log, lcid, cfg}); #else pdcp_log->error("Invalid PDCP configuration.\n"); return; #endif } else { - entity.reset(new pdcp_entity_lte{rlc, rrc, gw, task_executor, pdcp_log, lcid, cfg}); + entity.reset(new pdcp_entity_lte{rlc, rrc, gw, task_sched, pdcp_log, lcid, cfg}); } if (not pdcp_array.insert(std::make_pair(lcid, std::move(entity))).second) { pdcp_log->error("Error inserting PDCP entity in to array.\n"); @@ -142,7 +139,7 @@ void pdcp::add_bearer_mrb(uint32_t lcid, pdcp_config_t cfg) if (not pdcp_array_mrb .insert(std::make_pair(lcid, std::unique_ptr( - new pdcp_entity_lte(rlc, rrc, gw, task_executor, pdcp_log, lcid, cfg)))) + new pdcp_entity_lte(rlc, rrc, gw, task_sched, pdcp_log, lcid, cfg)))) .second) { pdcp_log->error("Error inserting PDCP entity in to array\n."); return; diff --git a/lib/src/upper/pdcp_entity_base.cc b/lib/src/upper/pdcp_entity_base.cc index 5a910c340..fd6745922 100644 --- a/lib/src/upper/pdcp_entity_base.cc +++ b/lib/src/upper/pdcp_entity_base.cc @@ -26,11 +26,10 @@ namespace srslte { -pdcp_entity_base::pdcp_entity_base(srslte::task_handler_interface* task_executor_, srslte::log_ref log_) : +pdcp_entity_base::pdcp_entity_base(task_sched_handle task_sched_, srslte::log_ref log_) : log(log_), - task_executor(task_executor_) -{ -} + task_sched(task_sched_) +{} pdcp_entity_base::~pdcp_entity_base() {} diff --git a/lib/src/upper/pdcp_entity_lte.cc b/lib/src/upper/pdcp_entity_lte.cc index e26367020..99ce9c2f0 100644 --- a/lib/src/upper/pdcp_entity_lte.cc +++ b/lib/src/upper/pdcp_entity_lte.cc @@ -24,14 +24,14 @@ namespace srslte { -pdcp_entity_lte::pdcp_entity_lte(srsue::rlc_interface_pdcp* rlc_, - srsue::rrc_interface_pdcp* rrc_, - srsue::gw_interface_pdcp* gw_, - srslte::task_handler_interface* task_executor_, - srslte::log_ref log_, - uint32_t lcid_, - pdcp_config_t cfg_) : - pdcp_entity_base(task_executor_, log_), +pdcp_entity_lte::pdcp_entity_lte(srsue::rlc_interface_pdcp* rlc_, + srsue::rrc_interface_pdcp* rrc_, + srsue::gw_interface_pdcp* gw_, + srslte::task_sched_handle task_sched_, + srslte::log_ref log_, + uint32_t lcid_, + pdcp_config_t cfg_) : + pdcp_entity_base(task_sched_, log_), rlc(rlc_), rrc(rrc_), gw(gw_) diff --git a/lib/src/upper/pdcp_entity_nr.cc b/lib/src/upper/pdcp_entity_nr.cc index bb72e8689..a9f559dc1 100644 --- a/lib/src/upper/pdcp_entity_nr.cc +++ b/lib/src/upper/pdcp_entity_nr.cc @@ -24,14 +24,14 @@ namespace srslte { -pdcp_entity_nr::pdcp_entity_nr(srsue::rlc_interface_pdcp* rlc_, - srsue::rrc_interface_pdcp* rrc_, - srsue::gw_interface_pdcp* gw_, - srslte::task_handler_interface* task_executor_, - srslte::log_ref log_, - uint32_t lcid_, - pdcp_config_t cfg_) : - pdcp_entity_base(task_executor_, log_), +pdcp_entity_nr::pdcp_entity_nr(srsue::rlc_interface_pdcp* rlc_, + srsue::rrc_interface_pdcp* rrc_, + srsue::gw_interface_pdcp* gw_, + srslte::task_sched_handle task_sched_, + srslte::log_ref log_, + uint32_t lcid_, + pdcp_config_t cfg_) : + pdcp_entity_base(task_sched_, log_), rlc(rlc_), rrc(rrc_), gw(gw_), @@ -46,7 +46,7 @@ pdcp_entity_nr::pdcp_entity_nr(srsue::rlc_interface_pdcp* rlc_, window_size = 1 << (cfg.sn_len - 1); // Timers - reordering_timer = task_executor->get_unique_timer(); + reordering_timer = task_sched.get_unique_timer(); // configure timer if (static_cast(cfg.t_reordering) > 0) { @@ -92,7 +92,7 @@ void pdcp_entity_nr::write_sdu(unique_byte_buffer_t sdu, bool blocking) // Start discard timer if (cfg.discard_timer != pdcp_discard_timer_t::infinity) { - timer_handler::unique_timer discard_timer = task_executor->get_unique_timer(); + timer_handler::unique_timer discard_timer = task_sched.get_unique_timer(); discard_callback discard_fnc(this, tx_next); discard_timer.set(static_cast(cfg.discard_timer), discard_fnc); discard_timer.run(); diff --git a/lib/test/upper/pdcp_lte_test.h b/lib/test/upper/pdcp_lte_test.h index e015428f2..e920350bd 100644 --- a/lib/test/upper/pdcp_lte_test.h +++ b/lib/test/upper/pdcp_lte_test.h @@ -72,7 +72,7 @@ public: rlc(log), rrc(log), gw(log), - pdcp(&rlc, &rrc, &gw, &stack, log, 0, cfg) + pdcp(&rlc, &rrc, &gw, &stack.task_sched, log, 0, cfg) { pdcp.config_security(sec_cfg_); pdcp.enable_integrity(srslte::DIRECTION_TXRX); diff --git a/lib/test/upper/pdcp_nr_test.h b/lib/test/upper/pdcp_nr_test.h index 36f2ba9b6..06f272476 100644 --- a/lib/test/upper/pdcp_nr_test.h +++ b/lib/test/upper/pdcp_nr_test.h @@ -100,7 +100,7 @@ public: rlc(log), rrc(log), gw(log), - pdcp(&rlc, &rrc, &gw, &stack, log, 0, cfg) + pdcp(&rlc, &rrc, &gw, &stack.task_sched, log, 0, cfg) { pdcp.config_security(sec_cfg_); pdcp.enable_integrity(srslte::DIRECTION_TXRX); diff --git a/srsenb/hdr/stack/enb_stack_lte.h b/srsenb/hdr/stack/enb_stack_lte.h index 4572cda7f..aa1d8aeb4 100644 --- a/srsenb/hdr/stack/enb_stack_lte.h +++ b/srsenb/hdr/stack/enb_stack_lte.h @@ -133,6 +133,10 @@ private: stack_args_t args = {}; rrc_cfg_t rrc_cfg = {}; + // task handling + srslte::task_scheduler task_sched; + srslte::task_multiqueue::queue_handler enb_task_queue, gtpu_task_queue, mme_task_queue, sync_task_queue; + // components that layers depend on (need to be destroyed after layers) std::unique_ptr rx_sockets; @@ -163,10 +167,6 @@ private: // state bool started = false; - // task handling - srslte::task_scheduler task_sched; - srslte::task_multiqueue::queue_handler enb_task_queue, gtpu_task_queue, mme_task_queue, sync_task_queue; - srslte::block_queue pending_stack_metrics; }; diff --git a/srsenb/hdr/stack/gnb_stack_nr.h b/srsenb/hdr/stack/gnb_stack_nr.h index 34ba19f66..9ed70de67 100644 --- a/srsenb/hdr/stack/gnb_stack_nr.h +++ b/srsenb/hdr/stack/gnb_stack_nr.h @@ -80,11 +80,11 @@ public: void process_pdus() final; // Task Handling interface - srslte::timer_handler::unique_timer get_unique_timer() final { return timers.get_unique_timer(); } - srslte::task_multiqueue::queue_handler make_task_queue() final { return pending_tasks.get_queue_handler(); } + srslte::timer_handler::unique_timer get_unique_timer() final { return task_sched.get_unique_timer(); } + srslte::task_multiqueue::queue_handler make_task_queue() final { return task_sched.make_task_queue(); } srslte::task_multiqueue::queue_handler make_task_queue(uint32_t qsize) final { - return pending_tasks.get_queue_handler(qsize); + return task_sched.make_task_queue(qsize); } void enqueue_background_task(std::function f) final; void notify_background_task_result(srslte::move_task_t task) final; @@ -100,8 +100,10 @@ private: srslte::logger* logger = nullptr; phy_interface_stack_nr* phy = nullptr; - /* Functions for MAC Timers */ - srslte::timer_handler timers; + // task scheduling + static const int STACK_MAIN_THREAD_PRIO = 4; + srslte::task_scheduler task_sched; + srslte::task_multiqueue::queue_handler sync_task_queue, ue_task_queue, gw_task_queue, mac_task_queue; // derived std::unique_ptr m_mac; @@ -116,13 +118,6 @@ private: // state bool running = false; uint32_t current_tti = 10240; - - // Thread - static const int STACK_MAIN_THREAD_PRIO = 4; - srslte::task_multiqueue pending_tasks; - std::vector deferred_stack_tasks; ///< enqueues stack tasks from within. Avoids locking - srslte::task_thread_pool background_tasks; ///< Thread pool used for long, low-priority tasks - int sync_queue_id = -1, ue_queue_id = -1, gw_queue_id = -1, mac_queue_id = -1, background_queue_id = -1; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/upper/pdcp.h b/srsenb/hdr/stack/upper/pdcp.h index 074864ca8..4e40ab9fe 100644 --- a/srsenb/hdr/stack/upper/pdcp.h +++ b/srsenb/hdr/stack/upper/pdcp.h @@ -33,7 +33,7 @@ namespace srsenb { class pdcp : public pdcp_interface_rlc, public pdcp_interface_gtpu, public pdcp_interface_rrc { public: - pdcp(srslte::task_handler_interface* task_executor_, const char* logname); + pdcp(srslte::task_sched_handle task_sched_, const char* logname); virtual ~pdcp() {} void init(rlc_interface_pdcp* rlc_, rrc_interface_pdcp* rrc_, gtpu_interface_pdcp* gtpu_); void stop(); @@ -104,12 +104,12 @@ private: std::map users; - rlc_interface_pdcp* rlc; - rrc_interface_pdcp* rrc; - gtpu_interface_pdcp* gtpu; - srslte::task_handler_interface* task_executor; - srslte::log_ref log_h; - srslte::byte_buffer_pool* pool; + rlc_interface_pdcp* rlc; + rrc_interface_pdcp* rrc; + gtpu_interface_pdcp* gtpu; + srslte::task_sched_handle task_sched; + srslte::log_ref log_h; + srslte::byte_buffer_pool* pool; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/upper/pdcp_nr.h b/srsenb/hdr/stack/upper/pdcp_nr.h index dd6a92ed7..565c2c070 100644 --- a/srsenb/hdr/stack/upper/pdcp_nr.h +++ b/srsenb/hdr/stack/upper/pdcp_nr.h @@ -39,7 +39,7 @@ struct pdcp_nr_args_t { class pdcp_nr : public pdcp_interface_rlc_nr, public pdcp_interface_sdap_nr, public pdcp_interface_rrc_nr { public: - explicit pdcp_nr(srslte::task_handler_interface* task_executor_, const char* logname); + explicit pdcp_nr(srslte::task_sched_handle task_sched_, const char* logname); virtual ~pdcp_nr() = default; void init(const pdcp_nr_args_t& args_, rlc_interface_pdcp_nr* rlc_, @@ -116,7 +116,7 @@ private: std::map users; - srslte::task_handler_interface* task_executor; + srslte::task_sched_handle task_sched; }; } // namespace srsenb diff --git a/srsenb/src/stack/enb_stack_lte.cc b/srsenb/src/stack/enb_stack_lte.cc index 22ea1a4af..3d6868e9f 100644 --- a/srsenb/src/stack/enb_stack_lte.cc +++ b/srsenb/src/stack/enb_stack_lte.cc @@ -32,7 +32,7 @@ namespace srsenb { enb_stack_lte::enb_stack_lte(srslte::logger* logger_) : task_sched(512, 0, 128), logger(logger_), - pdcp(this, "PDCP"), + pdcp(&task_sched, "PDCP"), thread("STACK") { enb_task_queue = task_sched.make_task_queue(); diff --git a/srsenb/src/stack/gnb_stack_nr.cc b/srsenb/src/stack/gnb_stack_nr.cc index aa1e79645..c9a0197a4 100644 --- a/srsenb/src/stack/gnb_stack_nr.cc +++ b/srsenb/src/stack/gnb_stack_nr.cc @@ -25,23 +25,20 @@ namespace srsenb { -gnb_stack_nr::gnb_stack_nr(srslte::logger* logger_) : logger(logger_), timers(128), thread("gNB"), background_tasks(1) +gnb_stack_nr::gnb_stack_nr(srslte::logger* logger_) : logger(logger_), task_sched{512, 1, 128}, thread("gNB") { m_mac.reset(new mac_nr()); m_rlc.reset(new rlc_nr("RLC")); - m_pdcp.reset(new pdcp_nr(this, "PDCP")); - m_rrc.reset(new rrc_nr(&timers)); + m_pdcp.reset(new pdcp_nr(&task_sched, "PDCP")); + m_rrc.reset(new rrc_nr(task_sched.get_timer_handler())); m_sdap.reset(new sdap()); m_gw.reset(new srsue::gw()); // m_gtpu.reset(new srsenb::gtpu()); - ue_queue_id = pending_tasks.add_queue(); - sync_queue_id = pending_tasks.add_queue(); - gw_queue_id = pending_tasks.add_queue(); - mac_queue_id = pending_tasks.add_queue(); - background_queue_id = pending_tasks.add_queue(); - - background_tasks.start(); + ue_task_queue = task_sched.make_task_queue(); + sync_task_queue = task_sched.make_task_queue(); + gw_task_queue = task_sched.make_task_queue(); + mac_task_queue = task_sched.make_task_queue(); } gnb_stack_nr::~gnb_stack_nr() @@ -85,7 +82,7 @@ int gnb_stack_nr::init(const srsenb::stack_args_t& args_, const rrc_nr_cfg_t& rr srslte::logmap::get("RLC")->set_level(args.log.rlc_level); srslte::logmap::get("RLC")->set_hex_limit(args.log.rlc_hex_limit); - m_rlc->init(m_pdcp.get(), m_rrc.get(), m_mac.get(), &timers); + m_rlc->init(m_pdcp.get(), m_rrc.get(), m_mac.get(), task_sched.get_timer_handler()); pdcp_nr_args_t pdcp_args = {}; pdcp_args.log_level = args.log.pdcp_level; @@ -140,29 +137,25 @@ bool gnb_stack_nr::switch_on() void gnb_stack_nr::run_thread() { while (running) { - srslte::move_task_t task{}; - pending_tasks.wait_pop(&task); - if (running) { - task(); - } + task_sched.run_next_external_task(); } } void gnb_stack_nr::run_tti(uint32_t tti) { current_tti = tti; - pending_tasks.push(sync_queue_id, [this, tti]() { run_tti_impl(tti); }); + sync_task_queue.push([this, tti]() { run_tti_impl(tti); }); } void gnb_stack_nr::run_tti_impl(uint32_t tti) { // m_ngap->run_tti(); - timers.step_all(); + task_sched.tic(); } void gnb_stack_nr::process_pdus() { - pending_tasks.push(mac_queue_id, [this]() { m_mac->process_pdus(); }); + mac_task_queue.push([this]() { m_mac->process_pdus(); }); } /******************************************************** @@ -205,23 +198,23 @@ bool gnb_stack_nr::is_lcid_enabled(uint32_t lcid) void gnb_stack_nr::enqueue_background_task(std::function f) { - background_tasks.push_task(std::move(f)); + task_sched.enqueue_background_task(std::move(f)); } void gnb_stack_nr::notify_background_task_result(srslte::move_task_t task) { // run the notification in the stack thread - pending_tasks.push(background_queue_id, std::move(task)); + task_sched.notify_background_task_result(std::move(task)); } void gnb_stack_nr::defer_callback(uint32_t duration_ms, std::function func) { - timers.defer_callback(duration_ms, func); + task_sched.defer_callback(duration_ms, func); } void gnb_stack_nr::defer_task(srslte::move_task_t task) { - deferred_stack_tasks.push_back(std::move(task)); + task_sched.defer_task(std::move(task)); } } // namespace srsenb diff --git a/srsenb/src/stack/upper/pdcp.cc b/srsenb/src/stack/upper/pdcp.cc index 3356c85ce..6244c4b9e 100644 --- a/srsenb/src/stack/upper/pdcp.cc +++ b/srsenb/src/stack/upper/pdcp.cc @@ -24,8 +24,10 @@ namespace srsenb { -pdcp::pdcp(srslte::task_handler_interface* task_executor_, const char* logname) : - task_executor(task_executor_), log_h(logname), pool(srslte::byte_buffer_pool::get_instance()) +pdcp::pdcp(srslte::task_sched_handle task_sched_, const char* logname) : + task_sched(task_sched_), + log_h(logname), + pool(srslte::byte_buffer_pool::get_instance()) {} void pdcp::init(rlc_interface_pdcp* rlc_, rrc_interface_pdcp* rrc_, gtpu_interface_pdcp* gtpu_) @@ -46,7 +48,7 @@ void pdcp::stop() void pdcp::add_user(uint16_t rnti) { if (users.count(rnti) == 0) { - srslte::pdcp* obj = new srslte::pdcp(task_executor, log_h->get_service_name().c_str()); + srslte::pdcp* obj = new srslte::pdcp(task_sched, log_h->get_service_name().c_str()); obj->init(&users[rnti].rlc_itf, &users[rnti].rrc_itf, &users[rnti].gtpu_itf); users[rnti].rlc_itf.rnti = rnti; users[rnti].gtpu_itf.rnti = rnti; diff --git a/srsenb/src/stack/upper/pdcp_nr.cc b/srsenb/src/stack/upper/pdcp_nr.cc index 93851f486..1f46f16de 100644 --- a/srsenb/src/stack/upper/pdcp_nr.cc +++ b/srsenb/src/stack/upper/pdcp_nr.cc @@ -24,8 +24,8 @@ namespace srsenb { -pdcp_nr::pdcp_nr(srslte::task_handler_interface* task_executor_, const char* logname) : - task_executor(task_executor_), +pdcp_nr::pdcp_nr(srslte::task_sched_handle task_sched_, const char* logname) : + task_sched(task_sched_), m_log(logname), pool(srslte::byte_buffer_pool::get_instance()) {} @@ -55,7 +55,7 @@ void pdcp_nr::stop() void pdcp_nr::add_user(uint16_t rnti) { if (users.count(rnti) == 0) { - users[rnti].pdcp.reset(new srslte::pdcp(task_executor, "PDCP")); + users[rnti].pdcp.reset(new srslte::pdcp(task_sched, "PDCP")); users[rnti].rlc_itf.rnti = rnti; users[rnti].sdap_itf.rnti = rnti; users[rnti].rrc_itf.rnti = rnti; diff --git a/srsue/hdr/stack/ue_stack_nr.h b/srsue/hdr/stack/ue_stack_nr.h index e1a871591..8b64591eb 100644 --- a/srsue/hdr/stack/ue_stack_nr.h +++ b/srsue/hdr/stack/ue_stack_nr.h @@ -97,11 +97,11 @@ public: srslte::tti_point get_current_tti() { return srslte::tti_point{0}; }; // Task Handling interface - srslte::timer_handler::unique_timer get_unique_timer() final { return timers.get_unique_timer(); } - srslte::task_multiqueue::queue_handler make_task_queue() final { return pending_tasks.get_queue_handler(); } + srslte::timer_handler::unique_timer get_unique_timer() final { return task_sched.get_unique_timer(); } + srslte::task_multiqueue::queue_handler make_task_queue() final { return task_sched.make_task_queue(); } srslte::task_multiqueue::queue_handler make_task_queue(uint32_t qsize) final { - return pending_tasks.get_queue_handler(qsize); + return task_sched.make_task_queue(qsize); } void enqueue_background_task(std::function f) final; void notify_background_task_result(srslte::move_task_t task) final; @@ -116,8 +116,9 @@ private: bool running = false; srsue::stack_args_t args = {}; - // timers - srslte::timer_handler timers; + // task scheduler + srslte::task_scheduler task_sched; + srslte::task_multiqueue::queue_handler sync_task_queue, ue_task_queue, gw_task_queue; // UE stack logging srslte::logger* logger = nullptr; @@ -139,11 +140,6 @@ private: // Thread static const int STACK_MAIN_THREAD_PRIO = 4; - - srslte::task_multiqueue pending_tasks; - int sync_queue_id = -1, ue_queue_id = -1, gw_queue_id = -1, mac_queue_id = -1, background_queue_id = -1; - srslte::task_thread_pool background_tasks; ///< Thread pool used for long, low-priority tasks - std::vector deferred_stack_tasks; ///< enqueues stack tasks from within. Avoids locking }; } // namespace srsue diff --git a/srsue/hdr/stack/upper/nas.h b/srsue/hdr/stack/upper/nas.h index 8675c2139..deafbca5a 100644 --- a/srsue/hdr/stack/upper/nas.h +++ b/srsue/hdr/stack/upper/nas.h @@ -29,6 +29,7 @@ #include "srslte/common/nas_pcap.h" #include "srslte/common/security.h" #include "srslte/common/stack_procedure.h" +#include "srslte/common/task_scheduler.h" #include "srslte/interfaces/ue_interfaces.h" #include "srsue/hdr/stack/upper/nas_common.h" #include "srsue/hdr/stack/upper/nas_metrics.h" @@ -40,7 +41,7 @@ namespace srsue { class nas : public nas_interface_rrc, public nas_interface_ue, public srslte::timer_callback { public: - explicit nas(srslte::task_handler_interface* task_handler_); + explicit nas(srslte::task_sched_handle task_sched_); virtual ~nas() = default; void init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_nas* gw_, const nas_args_t& args_); void stop(); @@ -134,7 +135,7 @@ private: uint8_t transaction_id = 0; // timers - srslte::task_handler_interface* task_handler = nullptr; + srslte::task_sched_handle task_sched; srslte::timer_handler::unique_timer t3402; // started when attach attempt counter reached 5 srslte::timer_handler::unique_timer t3410; // started when attach request is sent, on expiry, start t3411 srslte::timer_handler::unique_timer t3411; // started when attach failed diff --git a/srsue/src/stack/ue_stack_lte.cc b/srsue/src/stack/ue_stack_lte.cc index 2cb937256..f18716864 100644 --- a/srsue/src/stack/ue_stack_lte.cc +++ b/srsue/src/stack/ue_stack_lte.cc @@ -40,8 +40,8 @@ ue_stack_lte::ue_stack_lte() : rlc("RLC"), mac("MAC "), rrc(this), - pdcp(this, "PDCP"), - nas(this), + pdcp(&task_sched, "PDCP"), + nas(&task_sched), thread("STACK"), task_sched(512, 2, 64), tti_tprof("tti_tprof", "STCK", TTI_STAT_PERIOD) diff --git a/srsue/src/stack/ue_stack_nr.cc b/srsue/src/stack/ue_stack_nr.cc index 332a312f2..c290dcc2d 100644 --- a/srsue/src/stack/ue_stack_nr.cc +++ b/srsue/src/stack/ue_stack_nr.cc @@ -28,16 +28,14 @@ namespace srsue { ue_stack_nr::ue_stack_nr(srslte::logger* logger_) : logger(logger_), - timers(64), thread("STACK"), - pending_tasks(64), - background_tasks(2), + task_sched(64, 2, 64), rlc_log("RLC"), pdcp_log("PDCP"), pool_log("POOL") { mac.reset(new mac_nr()); - pdcp.reset(new srslte::pdcp(this, "PDCP")); + pdcp.reset(new srslte::pdcp(&task_sched, "PDCP")); rlc.reset(new srslte::rlc("RLC")); rrc.reset(new rrc_nr()); @@ -45,13 +43,9 @@ ue_stack_nr::ue_stack_nr(srslte::logger* logger_) : pool_log->set_level(srslte::LOG_LEVEL_ERROR); byte_buffer_pool::get_instance()->set_log(pool_log.get()); - ue_queue_id = pending_tasks.add_queue(); - sync_queue_id = pending_tasks.add_queue(); - gw_queue_id = pending_tasks.add_queue(); - mac_queue_id = pending_tasks.add_queue(); - background_queue_id = pending_tasks.add_queue(); - - background_tasks.start(); + ue_task_queue = task_sched.make_task_queue(); + sync_task_queue = task_sched.make_task_queue(); + gw_task_queue = task_sched.make_task_queue(); } ue_stack_nr::~ue_stack_nr() @@ -88,8 +82,8 @@ int ue_stack_nr::init(const stack_args_t& args_) mac_nr_args_t mac_args = {}; mac_args.pcap = args.pcap; mac_args.drb_lcid = 4; - mac->init(mac_args, phy, rlc.get(), &timers, this); - rlc->init(pdcp.get(), rrc.get(), &timers, 0 /* RB_ID_SRB0 */); + mac->init(mac_args, phy, rlc.get(), task_sched.get_timer_handler(), this); + rlc->init(pdcp.get(), rrc.get(), task_sched.get_timer_handler(), 0 /* RB_ID_SRB0 */); pdcp->init(rlc.get(), rrc.get(), gw); // TODO: where to put RRC args? @@ -98,7 +92,7 @@ int ue_stack_nr::init(const stack_args_t& args_) rrc_args.log_hex_limit = args.log.rrc_hex_limit; rrc_args.coreless.drb_lcid = 4; rrc_args.coreless.ip_addr = "192.168.1.3"; - rrc->init(phy, mac.get(), rlc.get(), pdcp.get(), gw, &timers, this, rrc_args); + rrc->init(phy, mac.get(), rlc.get(), pdcp.get(), gw, task_sched.get_timer_handler(), this, rrc_args); running = true; start(STACK_MAIN_THREAD_PRIO); @@ -109,7 +103,7 @@ int ue_stack_nr::init(const stack_args_t& args_) void ue_stack_nr::stop() { if (running) { - pending_tasks.try_push(ue_queue_id, [this]() { stop_impl(); }); + ue_task_queue.try_push([this]() { stop_impl(); }); wait_thread_finish(); } } @@ -155,10 +149,7 @@ bool ue_stack_nr::get_metrics(stack_metrics_t* metrics) void ue_stack_nr::run_thread() { while (running) { - srslte::move_task_t task{}; - if (pending_tasks.wait_pop(&task) >= 0) { - task(); - } + task_sched.run_next_external_task(); } } @@ -179,11 +170,9 @@ void ue_stack_nr::run_thread() void ue_stack_nr::write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu, bool blocking) { if (pdcp != nullptr) { - std::pair ret = pending_tasks.try_push( - gw_queue_id, - std::bind([this, lcid, blocking]( - srslte::unique_byte_buffer_t& sdu) { pdcp->write_sdu(lcid, std::move(sdu), blocking); }, - std::move(sdu))); + std::pair ret = gw_task_queue.try_push(std::bind( + [this, lcid, blocking](srslte::unique_byte_buffer_t& sdu) { pdcp->write_sdu(lcid, std::move(sdu), blocking); }, + std::move(sdu))); if (not ret.first) { pdcp_log->warning("GW SDU with lcid=%d was discarded.\n", lcid); } @@ -209,14 +198,14 @@ void ue_stack_nr::out_of_sync() void ue_stack_nr::run_tti(uint32_t tti) { - pending_tasks.push(sync_queue_id, [this, tti]() { run_tti_impl(tti); }); + sync_task_queue.push([this, tti]() { run_tti_impl(tti); }); } void ue_stack_nr::run_tti_impl(uint32_t tti) { mac->run_tti(tti); rrc->run_tti(tti); - timers.step_all(); + task_sched.tic(); } /******************** @@ -239,23 +228,23 @@ void ue_stack_nr::start_cell_select(const phy_interface_rrc_lte::phy_cell_t* cel void ue_stack_nr::enqueue_background_task(std::function f) { - background_tasks.push_task(std::move(f)); + task_sched.enqueue_background_task(std::move(f)); } void ue_stack_nr::notify_background_task_result(srslte::move_task_t task) { // run the notification in the stack thread - pending_tasks.push(background_queue_id, std::move(task)); + task_sched.notify_background_task_result(std::move(task)); } void ue_stack_nr::defer_callback(uint32_t duration_ms, std::function func) { - timers.defer_callback(duration_ms, func); + task_sched.defer_callback(duration_ms, std::move(func)); } void ue_stack_nr::defer_task(srslte::move_task_t task) { - deferred_stack_tasks.push_back(std::move(task)); + task_sched.defer_task(std::move(task)); } } // namespace srsue diff --git a/srsue/src/stack/upper/nas.cc b/srsue/src/stack/upper/nas.cc index 07f7c007d..6c5a9f694 100644 --- a/srsue/src/stack/upper/nas.cc +++ b/srsue/src/stack/upper/nas.cc @@ -136,7 +136,7 @@ proc_outcome_t nas::plmn_search_proc::react(const plmn_search_complete_t& t) nas::rrc_connect_proc::rrc_connect_proc(nas* nas_ptr_) : nas_ptr(nas_ptr_) { - timeout_timer = nas_ptr->task_handler->get_unique_timer(); + timeout_timer = nas_ptr->task_sched.get_unique_timer(); timeout_timer.set(attach_timeout_ms, [this](uint32_t tid) { nas_ptr->rrc_connector.trigger(nas::rrc_connect_proc::attach_timeout{}); }); } @@ -235,16 +235,16 @@ proc_outcome_t nas::rrc_connect_proc::react(nas::rrc_connect_proc::connection_re * NAS ********************************************************************/ -nas::nas(srslte::task_handler_interface* task_handler_) : +nas::nas(srslte::task_sched_handle task_sched_) : pool(byte_buffer_pool::get_instance()), plmn_searcher(this), rrc_connector(this), - task_handler(task_handler_), - t3402(task_handler_->get_unique_timer()), - t3410(task_handler_->get_unique_timer()), - t3411(task_handler_->get_unique_timer()), - t3421(task_handler_->get_unique_timer()), - reattach_timer(task_handler_->get_unique_timer()), + task_sched(task_sched_), + t3402(task_sched_.get_unique_timer()), + t3410(task_sched_.get_unique_timer()), + t3411(task_sched_.get_unique_timer()), + t3421(task_sched_.get_unique_timer()), + reattach_timer(task_sched_.get_unique_timer()), nas_log{"NAS"} {} @@ -406,7 +406,7 @@ void nas::start_attach_proc(srslte::proc_state_t* result, srslte::establishment_ } if (!res.is_success()) { // try again .. - task_handler->defer_callback(reattach_timer_duration_ms, [&]() { start_attach_proc(nullptr, cause_); }); + task_sched.defer_callback(reattach_timer_duration_ms, [&]() { start_attach_proc(nullptr, cause_); }); } }); } else { @@ -2499,7 +2499,7 @@ void nas::handle_airplane_mode_sim() // check if we're already attached, if so, schedule airplane mode command if (state == EMM_STATE_REGISTERED) { // NAS is attached - task_handler->defer_callback(cfg.sim.airplane_t_on_ms, [&]() { + task_sched.defer_callback(cfg.sim.airplane_t_on_ms, [&]() { // Enabling air-plane mode send_detach_request(true); airplane_mode_state = ENABLED; @@ -2509,7 +2509,7 @@ void nas::handle_airplane_mode_sim() // check if we are already deregistered, if so, schedule command to turn off airplone mode again if (state == EMM_STATE_DEREGISTERED) { // NAS is deregistered - task_handler->defer_callback(cfg.sim.airplane_t_off_ms, [&]() { + task_sched.defer_callback(cfg.sim.airplane_t_off_ms, [&]() { // Disabling airplane mode again start_attach_proc(nullptr, srslte::establishment_cause_t::mo_sig); airplane_mode_state = DISABLED; @@ -2519,7 +2519,7 @@ void nas::handle_airplane_mode_sim() // schedule another call if (cfg.sim.airplane_t_on_ms > 0 || cfg.sim.airplane_t_off_ms > 0) { - task_handler->defer_callback(1000, [&]() { handle_airplane_mode_sim(); }); + task_sched.defer_callback(1000, [&]() { handle_airplane_mode_sim(); }); } } diff --git a/srsue/test/ttcn3/src/ttcn3_syssim.cc b/srsue/test/ttcn3/src/ttcn3_syssim.cc index b365857dd..63471a659 100644 --- a/srsue/test/ttcn3/src/ttcn3_syssim.cc +++ b/srsue/test/ttcn3/src/ttcn3_syssim.cc @@ -47,7 +47,7 @@ ttcn3_syssim::ttcn3_syssim(srslte::logger_file* logger_file_, ttcn3_ue* ue_) : rlc(ss_rlc_log->get_service_name().c_str()), signal_handler(&running), timer_handler(create_tti_timer(), [&](uint64_t res) { new_tti_indication(res); }), - pdcp(&stack, ss_pdcp_log->get_service_name().c_str()) + pdcp(&stack.task_sched, ss_pdcp_log->get_service_name().c_str()) { if (ue->init(all_args_t{}, logger, this, "INIT_TEST") != SRSLTE_SUCCESS) { ue->stop(); diff --git a/srsue/test/upper/nas_test.cc b/srsue/test/upper/nas_test.cc index 6ab748678..88bc855c0 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -231,7 +231,7 @@ int security_command_test() usim.init(&args); { - srsue::nas nas(&stack); + srsue::nas nas(&stack.task_sched); nas_args_t cfg; cfg.eia = "1,2,3"; cfg.eea = "0,1,2,3"; @@ -298,7 +298,7 @@ int mme_attach_request_test() nas_cfg.force_imsi_attach = true; nas_cfg.apn_name = "test123"; test_stack_dummy stack(&pdcp_dummy); - srsue::nas nas(&stack); + srsue::nas nas(&stack.task_sched); srsue::gw gw; nas.init(&usim, &rrc_dummy, &gw, nas_cfg); @@ -377,7 +377,7 @@ int esm_info_request_test() pool = byte_buffer_pool::get_instance(); { - srsue::nas nas(&stack); + srsue::nas nas(&stack.task_sched); nas_args_t cfg; cfg.apn_name = "srslte"; cfg.apn_user = "srsuser"; @@ -429,7 +429,7 @@ int dedicated_eps_bearer_test() srslte::byte_buffer_pool* pool = byte_buffer_pool::get_instance(); - srsue::nas nas(&stack); + srsue::nas nas(&stack.task_sched); nas_args_t cfg = {}; cfg.force_imsi_attach = true; // make sure we get a fresh security context nas.init(&usim, &rrc_dummy, &gw, cfg); diff --git a/srsue/test/upper/rrc_meas_test.cc b/srsue/test/upper/rrc_meas_test.cc index d0519265e..6b81d63f9 100644 --- a/srsue/test/upper/rrc_meas_test.cc +++ b/srsue/test/upper/rrc_meas_test.cc @@ -115,14 +115,14 @@ public: class nas_test : public srsue::nas { public: - nas_test(srslte::task_handler_interface* t) : srsue::nas(t) {} + nas_test(srslte::task_sched_handle t) : srsue::nas(t) {} bool is_attached() override { return false; } }; class pdcp_test : public srslte::pdcp { public: - pdcp_test(const char* logname, srslte::task_handler_interface* t) : srslte::pdcp(t, logname) {} + pdcp_test(const char* logname, srslte::task_sched_handle t) : srslte::pdcp(t, logname) {} void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu, bool blocking = false) override { ul_dcch_msg_s ul_dcch_msg; @@ -180,8 +180,8 @@ public: rrc_test(srslte::log_ref log_, stack_test_dummy* stack_) : rrc(stack_), stack(stack_) { pool = srslte::byte_buffer_pool::get_instance(); - nastest = std::unique_ptr(new nas_test(stack)); - pdcptest = std::unique_ptr(new pdcp_test(log_->get_service_name().c_str(), stack)); + nastest = std::unique_ptr(new nas_test(&stack->task_sched)); + pdcptest = std::unique_ptr(new pdcp_test(log_->get_service_name().c_str(), &stack->task_sched)); }; void init() { rrc::init(&phytest, nullptr, nullptr, pdcptest.get(), nastest.get(), nullptr, nullptr, {}); }