added a stack thread to the eNB and move the tti_clock() method to this thread to avoid race conditions

This commit is contained in:
Francisco Paisana 2019-11-07 11:25:59 +00:00 committed by Andre Puschmann
parent 1a7142d73f
commit ee209fc0a2
2 changed files with 76 additions and 22 deletions

View File

@ -38,11 +38,12 @@
#include "enb_stack_base.h"
#include "srsenb/hdr/enb.h"
#include "srslte/common/multiqueue.h"
#include "srslte/interfaces/enb_interfaces.h"
namespace srsenb {
class enb_stack_lte final : public enb_stack_base, public stack_interface_phy_lte
class enb_stack_lte final : public enb_stack_base, public stack_interface_phy_lte, public thread
{
public:
enb_stack_lte(srslte::logger* logger_);
@ -86,16 +87,18 @@ public:
// Radio-Link status
void rl_failure(uint16_t rnti) final { mac.rl_failure(rnti); }
void rl_ok(uint16_t rnti) final { mac.rl_ok(rnti); }
void tti_clock() final
{
timers.step_all();
mac.tti_clock();
}
void tti_clock() override;
private:
static const int STACK_MAIN_THREAD_PRIO = -1; // Use default high-priority below UHD
// thread loop
void run_thread() override;
void stop_impl();
void tti_clock_impl();
// args
stack_args_t args = {};
rrc_cfg_t rrc_cfg = {};
bool started = false;
srsenb::mac mac;
srslte::mac_pcap mac_pcap;
@ -118,6 +121,19 @@ private:
// RAT-specific interfaces
phy_interface_stack_lte* phy = nullptr;
// state
bool started = false;
// NOTE: we use this struct instead of a std::function bc lambdas can't capture by move in C++11
struct task_t {
std::function<void(task_t*)> func;
srslte::unique_byte_buffer_t pdu;
task_t() = default;
explicit task_t(std::function<void(task_t*)> f_) : func(std::move(f_)) {}
void operator()() { func(this); }
};
srslte::multiqueue_handler<task_t> pending_tasks;
int enb_queue_id = -1, sync_queue_id = -1;
};
} // namespace srsenb

View File

@ -28,7 +28,9 @@ using namespace srslte;
namespace srsenb {
enb_stack_lte::enb_stack_lte(srslte::logger* logger_) : logger(logger_), pdcp(&pdcp_log), timers(128) {}
enb_stack_lte::enb_stack_lte(srslte::logger* logger_) : logger(logger_), pdcp(&pdcp_log), timers(128), thread("STACK")
{
}
enb_stack_lte::~enb_stack_lte()
{
@ -46,6 +48,7 @@ int enb_stack_lte::init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_, ph
if (init(args_, rrc_cfg_)) {
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
@ -127,31 +130,56 @@ int enb_stack_lte::init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_)
&gtpu_log,
args.embms.enable);
enb_queue_id = pending_tasks.add_queue();
sync_queue_id = pending_tasks.add_queue();
started = true;
start(STACK_MAIN_THREAD_PRIO);
return SRSLTE_SUCCESS;
}
void enb_stack_lte::tti_clock()
{
pending_tasks.push(sync_queue_id, task_t{[this](task_t*) { tti_clock_impl(); }});
}
void enb_stack_lte::tti_clock_impl()
{
timers.step_all();
mac.tti_clock();
}
void enb_stack_lte::stop()
{
if (started) {
s1ap.stop();
gtpu.stop();
mac.stop();
usleep(50000);
rlc.stop();
pdcp.stop();
rrc.stop();
usleep(10000);
if (args.pcap.enable) {
mac_pcap.close();
}
started = false;
pending_tasks.push(enb_queue_id, task_t{[this](task_t*) { stop_impl(); }});
wait_thread_finish();
}
}
void enb_stack_lte::stop_impl()
{
// stop listening to events
pending_tasks.erase_queue(sync_queue_id);
pending_tasks.erase_queue(enb_queue_id);
s1ap.stop();
gtpu.stop();
mac.stop();
usleep(50000);
rlc.stop();
pdcp.stop();
rrc.stop();
usleep(10000);
if (args.pcap.enable) {
mac_pcap.close();
}
started = false;
}
bool enb_stack_lte::get_metrics(stack_metrics_t* metrics)
{
mac.get_metrics(metrics->mac);
@ -160,4 +188,14 @@ bool enb_stack_lte::get_metrics(stack_metrics_t* metrics)
return true;
}
void enb_stack_lte::run_thread()
{
while (started) {
task_t task{};
if (pending_tasks.wait_pop(&task) >= 0) {
task();
}
}
}
} // namespace srsenb