creation of task scheduler interface for classes/functions running outside the main control thread

master
Francisco Paisana 4 years ago
parent 039977aeb5
commit 7c364070ee

@ -74,7 +74,7 @@ public:
background_tasks.push_task(std::move(f));
} else {
external_tasks.push(background_queue_id,
std::bind([](const std::function<void(uint32_t)>& task) { task(-1); }, std::move(f)));
std::bind([](const std::function<void(uint32_t)>& task) { task(0); }, std::move(f)));
}
}
@ -87,33 +87,31 @@ public:
//! Updates timers, and run any pending internal tasks.
// CAUTION: Should be called in main thread
void tic()
{
timers.step_all();
run_all_internal_tasks();
}
void tic() { timers.step_all(); }
//! Processes the next task in the multiqueue.
// CAUTION: This is a blocking call
bool run_next_external_task()
bool run_next_task()
{
srslte::move_task_t task{};
if (external_tasks.wait_pop(&task) >= 0) {
task();
run_all_internal_tasks();
return true;
}
run_all_internal_tasks();
return false;
}
//! Processes the next task in the multiqueue if it exists.
bool try_run_next_external_task()
void run_pending_tasks()
{
run_all_internal_tasks();
srslte::move_task_t task{};
if (external_tasks.try_pop(&task) >= 0) {
while (external_tasks.try_pop(&task) >= 0) {
task();
return true;
run_all_internal_tasks();
}
return false;
}
srslte::timer_handler* get_timer_handler() { return &timers; }
@ -159,6 +157,24 @@ private:
task_scheduler* sched;
};
//! Task scheduler handle given to classes/functions running outside of main control thread
class ext_task_sched_handle
{
public:
ext_task_sched_handle(task_scheduler* sched_) : sched(sched_) {}
srslte::unique_timer get_unique_timer() { return sched->get_unique_timer(); }
void enqueue_background_task(std::function<void(uint32_t)> f) { sched->enqueue_background_task(std::move(f)); }
void notify_background_task_result(srslte::move_task_t task)
{
sched->notify_background_task_result(std::move(task));
}
srslte::task_queue_handle make_task_queue() { return sched->make_task_queue(); }
private:
task_scheduler* sched;
};
} // namespace srslte
#endif // SRSLTE_TASK_SCHEDULER_H

@ -40,9 +40,12 @@ public:
return srslte::tti_point{task_sched.get_timer_handler()->get_cur_time() % 10240};
}
srslte::task_multiqueue::queue_handle make_task_queue() final { return task_sched.make_task_queue(); }
void enqueue_background_task(std::function<void(uint32_t)> f) override { f(0); }
void notify_background_task_result(srslte::move_task_t task) override { task(); }
void defer_callback(uint32_t duration_ms, std::function<void()> func) final
void enqueue_background_task(std::function<void(uint32_t)> f) override
{
task_sched.enqueue_background_task(std::move(f));
}
void notify_background_task_result(srslte::move_task_t task) override { task(); }
void defer_callback(uint32_t duration_ms, std::function<void()> func) final
{
task_sched.defer_callback(duration_ms, std::move(func));
}
@ -54,11 +57,12 @@ public:
// update clock and run internal tasks
task_sched.tic();
// Runs all pending external tasks
while (task_sched.try_run_next_external_task()) {
}
task_sched.run_pending_tasks();
}
// run pending tasks without updating timers
void run_pending_tasks() { task_sched.run_pending_tasks(); }
srslte::task_scheduler task_sched{512, 0, 100};
};

@ -32,7 +32,7 @@ int test_task_scheduler_no_pool()
// TEST: deferring task does not run the task until the next tic
task_sched.defer_task([&state]() { state = task_result::internal; });
TESTASSERT(state == task_result::null);
task_sched.tic();
task_sched.run_pending_tasks();
TESTASSERT(state == task_result::internal);
// TEST: check delaying of task
@ -42,6 +42,7 @@ int test_task_scheduler_no_pool()
for (int i = 0; i < dur; ++i) {
TESTASSERT(state == task_result::null);
task_sched.tic();
task_sched.run_pending_tasks();
}
TESTASSERT(state == task_result::timer);
@ -51,11 +52,9 @@ int test_task_scheduler_no_pool()
task_sched.notify_background_task_result([&state]() { state = task_result::external; });
});
TESTASSERT(state == task_result::null);
task_sched.tic();
task_sched.run_next_task(); // runs background task
TESTASSERT(state == task_result::null);
task_sched.run_next_external_task(); // runs background task
TESTASSERT(state == task_result::null);
task_sched.run_next_external_task(); // runs notification
task_sched.run_next_task(); // runs notification
TESTASSERT(state == task_result::external);
return SRSLTE_SUCCESS;
@ -70,9 +69,9 @@ int test_task_scheduler_with_pool()
task_sched.notify_background_task_result([&state]() { state = task_result::external; });
});
TESTASSERT(state == task_result::null);
task_sched.tic();
task_sched.run_pending_tasks();
TESTASSERT(state == task_result::null);
task_sched.run_next_external_task(); // waits and runs notification
task_sched.run_next_task(); // waits and runs notification
TESTASSERT(state == task_result::external);
return SRSLTE_SUCCESS;

@ -194,7 +194,7 @@ bool enb_stack_lte::get_metrics(stack_metrics_t* metrics)
void enb_stack_lte::run_thread()
{
while (started) {
task_sched.run_next_external_task();
task_sched.run_next_task();
}
}

@ -137,7 +137,7 @@ bool gnb_stack_nr::switch_on()
void gnb_stack_nr::run_thread()
{
while (running) {
task_sched.run_next_external_task();
task_sched.run_next_task();
}
}

@ -48,12 +48,9 @@ class mac : public mac_interface_phy_lte,
public mac_interface_demux
{
public:
mac(const char* logname);
mac(const char* logname, ext_task_sched_handle task_sched_);
~mac();
bool init(phy_interface_mac_lte* phy,
rlc_interface_mac* rlc,
rrc_interface_mac* rrc,
srslte::task_handler_interface* stack_);
bool init(phy_interface_mac_lte* phy, rlc_interface_mac* rlc, rrc_interface_mac* rrc);
void stop();
void get_metrics(mac_metrics_t m[SRSLTE_MAX_CARRIERS]);
@ -116,10 +113,10 @@ private:
bool is_in_window(uint32_t tti, int* start, int* len);
// Interaction with PHY
phy_interface_mac_lte* phy_h = nullptr;
rlc_interface_mac* rlc_h = nullptr;
rrc_interface_mac* rrc_h = nullptr;
srslte::task_handler_interface* stack_h = nullptr;
phy_interface_mac_lte* phy_h = nullptr;
rlc_interface_mac* rlc_h = nullptr;
rrc_interface_mac* rrc_h = nullptr;
srslte::ext_task_sched_handle task_sched;
srslte::log_ref log_h;
mac_interface_phy_lte::mac_phy_cfg_mbsfn_t phy_mbsfn_cfg = {};

@ -57,7 +57,7 @@ class bsr_proc : public srslte::timer_callback, public bsr_interface_mux
public:
bsr_proc();
void
init(sr_proc* sr_proc, rlc_interface_mac* rlc, srslte::log_ref log_h, srslte::task_handler_interface* task_handler_);
init(sr_proc* sr_proc, rlc_interface_mac* rlc, srslte::log_ref log_h, srslte::ext_task_sched_handle* task_sched_);
void step(uint32_t tti);
void reset();
void set_config(srslte::bsr_cfg_t& bsr_cfg);
@ -73,10 +73,10 @@ private:
std::mutex mutex;
srslte::task_handler_interface* task_handler;
srslte::log_ref log_h;
rlc_interface_mac* rlc;
sr_proc* sr;
srslte::ext_task_sched_handle* task_sched;
srslte::log_ref log_h;
rlc_interface_mac* rlc;
sr_proc* sr;
srslte::bsr_cfg_t bsr_cfg;

@ -35,7 +35,7 @@ class phr_proc : public srslte::timer_callback
{
public:
phr_proc();
void init(phy_interface_mac_lte* phy_h, srslte::log_ref log_h_, srslte::task_handler_interface* task_handler_);
void init(phy_interface_mac_lte* phy_h, srslte::log_ref log_h_, srslte::ext_task_sched_handle* task_sched_);
void set_config(srslte::phr_cfg_t& cfg);
void step();
void reset();
@ -49,13 +49,13 @@ public:
private:
bool pathloss_changed();
srslte::log_ref log_h;
phy_interface_mac_lte* phy_h;
srslte::task_handler_interface* task_handler;
srslte::phr_cfg_t phr_cfg;
bool initiated;
int last_pathloss_db;
bool phr_is_triggered;
srslte::log_ref log_h;
phy_interface_mac_lte* phy_h;
srslte::ext_task_sched_handle* task_sched;
srslte::phr_cfg_t phr_cfg;
bool initiated;
int last_pathloss_db;
bool phr_is_triggered;
srslte::timer_handler::unique_timer timer_periodic;
srslte::timer_handler::unique_timer timer_prohibit;

@ -72,7 +72,7 @@ public:
mac_interface_rrc::ue_rnti_t* rntis,
srslte::timer_handler::unique_timer* time_alignment_timer_,
mux* mux_unit,
srslte::task_handler_interface* stack_);
srslte::ext_task_sched_handle* task_sched_);
void reset();
@ -164,12 +164,12 @@ private:
void read_params();
phy_interface_mac_lte* phy_h;
srslte::log_ref log_h;
mux* mux_unit;
srslte::mac_pcap* pcap;
rrc_interface_mac* rrc;
srslte::task_handler_interface* stack = nullptr;
phy_interface_mac_lte* phy_h;
srslte::log_ref log_h;
mux* mux_unit;
srslte::mac_pcap* pcap;
rrc_interface_mac* rrc;
srslte::ext_task_sched_handle* task_sched = nullptr;
srslte::timer_handler::unique_timer* time_alignment_timer = nullptr;
srslte::timer_handler::unique_timer contention_resolution_timer;

@ -35,12 +35,13 @@
namespace srsue {
mac::mac(const char* logname) :
mac::mac(const char* logname, ext_task_sched_handle task_sched_) :
log_h(srslte::logmap::get(logname)),
mch_msg(10, log_h),
mux_unit(log_h),
demux_unit(log_h),
pcap(nullptr)
pcap(nullptr),
task_sched(task_sched_)
{
// Create PCell HARQ entities
auto ul = ul_harq_entity_ptr(new ul_harq_entity(PCELL_CC_IDX));
@ -70,26 +71,22 @@ mac::~mac()
srslte_softbuffer_rx_free(&mch_softbuffer);
}
bool mac::init(phy_interface_mac_lte* phy,
rlc_interface_mac* rlc,
rrc_interface_mac* rrc,
task_handler_interface* stack_)
bool mac::init(phy_interface_mac_lte* phy, rlc_interface_mac* rlc, rrc_interface_mac* rrc)
{
phy_h = phy;
rlc_h = rlc;
rrc_h = rrc;
stack_h = stack_;
phy_h = phy;
rlc_h = rlc;
rrc_h = rrc;
timer_alignment = stack_h->get_unique_timer();
timer_alignment = task_sched.get_unique_timer();
// Create Stack task dispatch queue
stack_task_dispatch_queue = stack_h->make_task_queue();
stack_task_dispatch_queue = task_sched.make_task_queue();
bsr_procedure.init(&sr_procedure, rlc_h, log_h, stack_h);
phr_procedure.init(phy_h, log_h, stack_h);
bsr_procedure.init(&sr_procedure, rlc_h, log_h, &task_sched);
phr_procedure.init(phy_h, log_h, &task_sched);
mux_unit.init(rlc_h, &bsr_procedure, &phr_procedure);
demux_unit.init(phy_h, rlc_h, this, &timer_alignment);
ra_procedure.init(phy_h, rrc, log_h, &uernti, &timer_alignment, &mux_unit, stack_h);
ra_procedure.init(phy_h, rrc, log_h, &uernti, &timer_alignment, &mux_unit, &task_sched);
sr_procedure.init(&ra_procedure, phy_h, rrc, log_h);
// Create UL/DL unique HARQ pointers

@ -33,19 +33,19 @@ bsr_proc::bsr_proc()
triggered_bsr_type = NONE;
}
void bsr_proc::init(sr_proc* sr_,
rlc_interface_mac* rlc_,
srslte::log_ref log_h_,
srslte::task_handler_interface* task_handler_)
void bsr_proc::init(sr_proc* sr_,
rlc_interface_mac* rlc_,
srslte::log_ref log_h_,
srslte::ext_task_sched_handle* task_sched_)
{
log_h = log_h_;
rlc = rlc_;
sr = sr_;
task_handler = task_handler_;
timer_periodic = task_handler->get_unique_timer();
timer_retx = task_handler->get_unique_timer();
timer_queue_status_print = task_handler->get_unique_timer();
log_h = log_h_;
rlc = rlc_;
sr = sr_;
task_sched = task_sched_;
timer_periodic = task_sched->get_unique_timer();
timer_retx = task_sched->get_unique_timer();
timer_queue_status_print = task_sched->get_unique_timer();
reset();

@ -38,17 +38,15 @@ phr_proc::phr_proc()
phr_cfg = {};
}
void phr_proc::init(phy_interface_mac_lte* phy_h_,
srslte::log_ref log_h_,
srslte::task_handler_interface* task_handler_)
void phr_proc::init(phy_interface_mac_lte* phy_h_, srslte::log_ref log_h_, srslte::ext_task_sched_handle* task_sched_)
{
phy_h = phy_h_;
log_h = log_h_;
task_handler = task_handler_;
initiated = true;
phy_h = phy_h_;
log_h = log_h_;
task_sched = task_sched_;
initiated = true;
timer_periodic = task_handler->get_unique_timer();
timer_prohibit = task_handler->get_unique_timer();
timer_periodic = task_sched->get_unique_timer();
timer_prohibit = task_sched->get_unique_timer();
reset();
}

@ -56,17 +56,17 @@ void ra_proc::init(phy_interface_mac_lte* phy_h_,
mac_interface_rrc::ue_rnti_t* rntis_,
srslte::timer_handler::unique_timer* time_alignment_timer_,
mux* mux_unit_,
srslte::task_handler_interface* stack_)
srslte::ext_task_sched_handle* task_sched_)
{
phy_h = phy_h_;
log_h = log_h_;
rntis = rntis_;
mux_unit = mux_unit_;
rrc = rrc_;
stack = stack_;
phy_h = phy_h_;
log_h = log_h_;
rntis = rntis_;
mux_unit = mux_unit_;
rrc = rrc_;
task_sched = task_sched_;
time_alignment_timer = time_alignment_timer_;
contention_resolution_timer = stack->get_unique_timer();
contention_resolution_timer = task_sched->get_unique_timer();
srslte_softbuffer_rx_init(&softbuffer_rar, 10);
@ -232,7 +232,7 @@ void ra_proc::state_completition()
state = WAITING_COMPLETION;
uint16_t rnti = rntis->crnti;
uint32_t task_id = current_task_id;
stack->enqueue_background_task([this, rnti, task_id](uint32_t worker_id) {
task_sched->enqueue_background_task([this, rnti, task_id](uint32_t worker_id) {
phy_h->set_crnti(rnti);
// signal MAC RA proc to go back to idle
notify_ra_completed(task_id);
@ -285,10 +285,10 @@ void ra_proc::initialization()
// Instruct phy to configure PRACH
state = WAITING_PHY_CONFIG;
uint32_t task_id = current_task_id;
stack->enqueue_background_task([this, task_id](uint32_t worker_id) {
task_sched->enqueue_background_task([this, task_id](uint32_t worker_id) {
phy_h->configure_prach_params();
// notify back MAC
stack->notify_background_task_result([this, task_id]() { notify_phy_config_completed(task_id); });
task_sched->notify_background_task_result([this, task_id]() { notify_phy_config_completed(task_id); });
});
}

@ -38,7 +38,7 @@ ue_stack_lte::ue_stack_lte() :
usim(nullptr),
phy(nullptr),
rlc("RLC"),
mac("MAC "),
mac("MAC", &task_sched),
rrc(this),
pdcp(&task_sched, "PDCP"),
nas(&task_sched),
@ -122,7 +122,7 @@ int ue_stack_lte::init(const stack_args_t& args_, srslte::logger* logger_)
// add sync queue
sync_task_queue = task_sched.make_task_queue(args.sync_queue_size);
mac.init(phy, &rlc, &rrc, this);
mac.init(phy, &rlc, &rrc);
rlc.init(&pdcp, &rrc, task_sched.get_timer_handler(), 0 /* RB_ID_SRB0 */);
pdcp.init(&rlc, &rrc, gw);
nas.init(usim.get(), &rrc, gw, args.nas);
@ -223,7 +223,7 @@ bool ue_stack_lte::get_metrics(stack_metrics_t* metrics)
void ue_stack_lte::run_thread()
{
while (running) {
task_sched.run_next_external_task();
task_sched.run_next_task();
}
}

@ -149,7 +149,7 @@ bool ue_stack_nr::get_metrics(stack_metrics_t* metrics)
void ue_stack_nr::run_thread()
{
while (running) {
task_sched.run_next_external_task();
task_sched.run_next_task();
}
}

@ -388,9 +388,9 @@ int mac_unpack_test()
stack_dummy stack;
// the actual MAC
mac mac("MAC");
mac mac("MAC", &stack.task_sched);
stack.init(&mac, &phy);
mac.init(&phy, &rlc, &rrc, &stack);
mac.init(&phy, &rlc, &rrc);
// create dummy DL action and grant and push MAC PDU
mac_interface_phy_lte::tb_action_dl_t dl_action;
@ -439,9 +439,9 @@ int mac_ul_sch_pdu_test1()
stack_dummy stack;
// the actual MAC
mac mac("MAC");
mac mac("MAC", &stack.task_sched);
stack.init(&mac, &phy);
mac.init(&phy, &rlc, &rrc, &stack);
mac.init(&phy, &rlc, &rrc);
const uint16_t crnti = 0x1001;
mac.set_ho_rnti(crnti, 0);
@ -502,9 +502,9 @@ int mac_ul_logical_channel_prioritization_test1()
stack_dummy stack;
// the actual MAC
mac mac("MAC");
mac mac("MAC", &stack.task_sched);
stack.init(&mac, &phy);
mac.init(&phy, &rlc, &rrc, &stack);
mac.init(&phy, &rlc, &rrc);
const uint16_t crnti = 0x1001;
mac.set_ho_rnti(crnti, 0);
@ -610,9 +610,9 @@ int mac_ul_logical_channel_prioritization_test2()
stack_dummy stack;
// the actual MAC
mac mac("MAC");
mac mac("MAC", &stack.task_sched);
stack.init(&mac, &phy);
mac.init(&phy, &rlc, &rrc, &stack);
mac.init(&phy, &rlc, &rrc);
const uint16_t crnti = 0x1001;
mac.set_ho_rnti(crnti, 0);
@ -705,9 +705,9 @@ int mac_ul_logical_channel_prioritization_test3()
stack_dummy stack;
// the actual MAC
mac mac("MAC");
mac mac("MAC", &stack.task_sched);
stack.init(&mac, &phy);
mac.init(&phy, &rlc, &rrc, &stack);
mac.init(&phy, &rlc, &rrc);
const uint16_t crnti = 0x1001;
mac.set_ho_rnti(crnti, 0);
@ -787,9 +787,9 @@ int mac_ul_sch_pdu_with_short_bsr_test()
stack_dummy stack;
// the actual MAC
mac mac("MAC");
mac mac("MAC", &stack.task_sched);
stack.init(&mac, &phy);
mac.init(&phy, &rlc, &rrc, &stack);
mac.init(&phy, &rlc, &rrc);
const uint16_t crnti = 0x1001;
mac.set_ho_rnti(crnti, 0);
@ -868,9 +868,9 @@ int mac_ul_sch_pdu_with_padding_bsr_test()
stack_dummy stack;
// the actual MAC
mac mac("MAC");
mac mac("MAC", &stack.task_sched);
stack.init(&mac, &phy);
mac.init(&phy, &rlc, &rrc, &stack);
mac.init(&phy, &rlc, &rrc);
const uint16_t crnti = 0x1001;
mac.set_ho_rnti(crnti, 0);
@ -958,9 +958,9 @@ int mac_ul_sch_pdu_one_byte_test()
stack_dummy stack;
// the actual MAC
mac mac("MAC");
mac mac("MAC", &stack.task_sched);
stack.init(&mac, &phy);
mac.init(&phy, &rlc, &rrc, &stack);
mac.init(&phy, &rlc, &rrc);
const uint16_t crnti = 0x1001;
mac.set_ho_rnti(crnti, 0);
@ -1013,9 +1013,9 @@ int mac_ul_sch_pdu_two_byte_test()
stack_dummy stack;
// the actual MAC
mac mac("MAC");
mac mac("MAC", &stack.task_sched);
stack.init(&mac, &phy);
mac.init(&phy, &rlc, &rrc, &stack);
mac.init(&phy, &rlc, &rrc);
const uint16_t crnti = 0x1001;
mac.set_ho_rnti(crnti, 0);
@ -1068,9 +1068,9 @@ int mac_ul_sch_pdu_three_byte_test()
stack_dummy stack;
// the actual MAC
mac mac("MAC");
mac mac("MAC", &stack.task_sched);
stack.init(&mac, &phy);
mac.init(&phy, &rlc, &rrc, &stack);
mac.init(&phy, &rlc, &rrc);
const uint16_t crnti = 0x1001;
mac.set_ho_rnti(crnti, 0);
@ -1309,9 +1309,9 @@ int mac_random_access_test()
asn1::rrc::rach_cfg_common_s::ra_supervision_info_s_::mac_contention_resolution_timer_opts::sf8;
// Configure MAC
mac mac("MAC");
mac mac("MAC", &stack.task_sched);
stack.init(&mac, &phy);
mac.init(&phy, &rlc, &rrc, &stack);
mac.init(&phy, &rlc, &rrc);
srslte::mac_cfg_t mac_cfg;
set_mac_cfg_t_rach_cfg_common(&mac_cfg, rach_cfg);
mac.set_config(mac_cfg);
@ -1449,6 +1449,7 @@ int mac_random_access_test()
rrc.ho_finish = false;
my_test.preamble_idx = 3;
mac.start_noncont_ho(my_test.preamble_idx, 0);
stack.run_pending_tasks();
my_test.nof_prachs = rach_cfg.ra_supervision_info.preamb_trans_max.to_number();
my_test.rar_nof_invalid_rapid = rach_cfg.ra_supervision_info.ra_resp_win_size.to_number();
my_test.temp_rnti++; // Temporal C-RNTI has to change to avoid duplicate
@ -1465,6 +1466,7 @@ int mac_random_access_test()
rrc.ho_finish = false;
my_test.preamble_idx = 3;
mac.start_noncont_ho(my_test.preamble_idx, 0);
stack.run_pending_tasks();
my_test.nof_prachs = 1;
my_test.rar_nof_invalid_rapid = 0;
my_test.check_ra_successful = true;

@ -169,8 +169,7 @@ public:
running = true;
while (running) {
task_sched.tic();
while (task_sched.try_run_next_external_task()) {
}
task_sched.run_pending_tasks();
nas->run_tti();
}
}

@ -188,8 +188,7 @@ public:
void run_tti(uint32_t tti_)
{
stack->task_sched.tic();
while (stack->task_sched.try_run_next_external_task()) {
}
stack->task_sched.run_pending_tasks();
rrc::run_tti();
}

Loading…
Cancel
Save