moved mac thread to the stack. Protect the interface of the stack with PHY and gateway via a queue of tasks

master
Francisco Paisana 6 years ago committed by Andre Puschmann
parent 46d298fd9a
commit ce29ed545d

@ -166,7 +166,6 @@ class rrc_interface_mac : public rrc_interface_mac_common
public:
virtual void ho_ra_completed(bool ra_successful) = 0;
virtual void release_pucch_srs() = 0;
virtual void run_tti(uint32_t tti) = 0;
};
// RRC interface for PHY

@ -62,7 +62,7 @@ public:
void stop();
void start_pcap(srslte::mac_pcap* pcap_);
/******** Interface from PHY (PHY -> MAC) ****************/
int sr_detected(uint32_t tti, uint16_t rnti) final;
int rach_detected(uint32_t tti, uint32_t preamble_idx, uint32_t time_adv) final;
@ -122,7 +122,7 @@ private:
// We use a rwlock in MAC to allow multiple workers to access MAC simultaneously. No conflicts will happen since access for different TTIs
pthread_rwlock_t rwlock;
// Interaction with PHY
phy_interface_stack_lte* phy_h;
rlc_interface_mac* rlc_h;

@ -46,7 +46,6 @@ class mac : public mac_interface_phy_lte,
public mac_interface_rrc,
public srslte::timer_callback,
public srslte::mac_interface_timers,
public thread,
public mac_interface_demux
{
public:
@ -110,7 +109,6 @@ public:
uint32_t timer_get_unique_id();
private:
void run_thread();
void clear_rntis();
bool is_in_window(uint32_t tti, int* start, int* len);
@ -159,10 +157,6 @@ private:
uint8_t mch_payload_buffer[mch_payload_buffer_sz];
srslte::mch_pdu mch_msg;
// MAC thread
srslte::block_queue<uint16_t> tti_sync;
bool running;
/* Functions for MAC Timers */
uint32_t timer_alignment;
void setup_timers(int time_alignment_timer);

@ -26,6 +26,7 @@
#ifndef SRSUE_UE_STACK_LTE_H
#define SRSUE_UE_STACK_LTE_H
#include <functional>
#include <pthread.h>
#include <stdarg.h>
#include <string>
@ -47,7 +48,10 @@
namespace srsue {
class ue_stack_lte final : public ue_stack_base, public stack_interface_phy_lte, public stack_interface_gw
class ue_stack_lte final : public ue_stack_base,
public stack_interface_phy_lte,
public stack_interface_gw,
public thread
{
public:
ue_stack_lte();
@ -65,8 +69,8 @@ public:
bool is_rrc_connected();
// RRC interface for PHY
void in_sync() { rrc.in_sync(); };
void out_of_sync() { rrc.out_of_sync(); };
void in_sync() final;
void out_of_sync() final;
void new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn = -1, int pci = -1)
{
rrc.new_phy_meas(rsrp, rsrq, tti, earfcn, pci);
@ -99,7 +103,7 @@ public:
void set_mbsfn_config(uint32_t nof_mbsfn_services) { mac.set_mbsfn_config(nof_mbsfn_services); }
void run_tti(const uint32_t tti) { mac.run_tti(tti); }
void run_tti(uint32_t tti) final;
// Interface for GW
void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu, bool blocking) final
@ -110,6 +114,10 @@ public:
bool is_lcid_enabled(uint32_t lcid) final { return pdcp.is_lcid_enabled(lcid); }
private:
void run_thread() final;
void run_tti_(uint32_t tti);
void stop_();
bool running;
srsue::stack_args_t args;
@ -137,6 +145,10 @@ private:
// RAT-specific interfaces
phy_interface_stack_lte* phy;
gw_interface_stack* gw;
// Thread
static const int STACK_MAIN_THREAD_PRIO = -1; // Use default high-priority below UHD
srslte::block_queue<std::function<void()> > pending_tasks;
};
} // namespace srsue

@ -37,7 +37,7 @@ using namespace asn1::rrc;
namespace srsue {
mac::mac() : timers(64), pdu_process_thread(&demux_unit), mch_msg(10), running(false), pcap(nullptr), thread("MAC")
mac::mac() : timers(64), pdu_process_thread(&demux_unit), mch_msg(10), pcap(nullptr)
{
// Create PCell HARQ entities
auto ul = ul_harq_entity_ptr(new ul_harq_entity());
@ -81,8 +81,6 @@ bool mac::init(phy_interface_mac_lte* phy, rlc_interface_mac* rlc, rrc_interface
reset();
start(MAC_MAIN_THREAD_PRIO);
return true;
}
@ -93,10 +91,7 @@ void mac::stop()
pdu_process_thread.stop();
running = false;
run_tti(0); // make sure it's not locked after last TTI
wait_thread_finish();
}
void mac::start_pcap(srslte::mac_pcap* pcap_)
@ -178,50 +173,37 @@ void mac::reset()
clear_rntis();
}
void mac::run_tti(const uint32_t tti_)
void mac::run_tti(const uint32_t tti)
{
tti_sync.push(tti_);
}
void mac::run_thread()
{
running = true;
while (running) {
// Wait for next TTI
uint32_t tti = tti_sync.wait_pop();
log_h->step(tti);
log_h->step(tti);
/* Warning: Here order of invocation of procedures is important!! */
/* Warning: Here order of invocation of procedures is important!! */
// Step all procedures
Debug("Running MAC tti=%d\n", tti);
bsr_procedure.step(tti);
phr_procedure.step(tti);
// Step all procedures
Debug("Running MAC tti=%d\n", tti);
bsr_procedure.step(tti);
phr_procedure.step(tti);
// Check if BSR procedure need to start SR
if (bsr_procedure.need_to_send_sr(tti)) {
Debug("Starting SR procedure by BSR request, PHY TTI=%d\n", tti);
sr_procedure.start();
}
if (bsr_procedure.need_to_reset_sr()) {
Debug("Resetting SR procedure by BSR request\n");
sr_procedure.reset();
}
sr_procedure.step(tti);
// Check SR if we need to start RA
if (sr_procedure.need_random_access()) {
ra_procedure.start_mac_order();
}
// Check if BSR procedure need to start SR
if (bsr_procedure.need_to_send_sr(tti)) {
Debug("Starting SR procedure by BSR request, PHY TTI=%d\n", tti);
sr_procedure.start();
}
if (bsr_procedure.need_to_reset_sr()) {
Debug("Resetting SR procedure by BSR request\n");
sr_procedure.reset();
}
sr_procedure.step(tti);
ra_procedure.step(tti);
ra_window_start = 0;
ra_procedure.is_rar_window(&ra_window_start, &ra_window_length);
timers.step_all();
rrc_h->run_tti(tti);
// Check SR if we need to start RA
if (sr_procedure.need_random_access()) {
ra_procedure.start_mac_order();
}
ra_procedure.step(tti);
ra_window_start = 0;
ra_procedure.is_rar_window(&ra_window_start, &ra_window_length);
timers.step_all();
}
void mac::bcch_start_rx(int si_window_start, int si_window_length)

@ -26,7 +26,7 @@ using namespace srslte;
namespace srsue {
ue_stack_lte::ue_stack_lte() : running(false), args(), logger(nullptr), usim(nullptr), phy(nullptr) {}
ue_stack_lte::ue_stack_lte() : running(false), args(), logger(nullptr), usim(nullptr), phy(nullptr), thread("STACK") {}
ue_stack_lte::~ue_stack_lte()
{
@ -108,11 +108,21 @@ int ue_stack_lte::init(const stack_args_t& args_, srslte::logger* logger_)
rrc.init(phy, &mac, &rlc, &pdcp, &nas, usim.get(), gw, &mac, &rrc_log, args.rrc);
running = true;
start(STACK_MAIN_THREAD_PRIO);
return SRSLTE_SUCCESS;
}
void ue_stack_lte::stop()
{
if (running) {
pending_tasks.push([this]() { stop_(); });
wait_thread_finish();
}
}
void ue_stack_lte::stop_()
{
if (running) {
usim->stop();
@ -140,7 +150,7 @@ void ue_stack_lte::stop()
bool ue_stack_lte::switch_on()
{
if (running) {
return nas.attach_request();
nas.attach_request();
}
return false;
@ -148,8 +158,10 @@ bool ue_stack_lte::switch_on()
bool ue_stack_lte::switch_off()
{
// generate detach request
nas.detach_request();
pending_tasks.push([this]() {
// generate detach request
nas.detach_request();
});
// wait for max. 5s for it to be sent (according to TS 24.301 Sec 25.5.2.2)
const uint32_t RB_ID_SRB1 = 1;
@ -184,4 +196,34 @@ bool ue_stack_lte::is_rrc_connected()
return rrc.is_connected();
}
void ue_stack_lte::run_thread()
{
while (running) {
// FIXME: For now it is a single queue
std::function<void()> func = pending_tasks.wait_pop();
func();
}
}
void ue_stack_lte::in_sync()
{
pending_tasks.push([this]() { rrc.in_sync(); });
}
void ue_stack_lte::out_of_sync()
{
pending_tasks.push([this]() { rrc.out_of_sync(); });
}
void ue_stack_lte::run_tti(uint32_t tti)
{
pending_tasks.push([this, tti]() { run_tti_(tti); });
}
void ue_stack_lte::run_tti_(uint32_t tti)
{
mac.run_tti(tti);
rrc.run_tti(tti);
}
} // namespace srsue

@ -137,17 +137,30 @@ private:
found_plmn_t plmns;
};
class stack_dummy : public stack_interface_gw
class stack_dummy : public stack_interface_gw, public thread
{
public:
stack_dummy(pdcp_interface_gw* pdcp_, srsue::nas* nas_) : pdcp(pdcp_), nas(nas_) {}
stack_dummy(pdcp_interface_gw* pdcp_, srsue::nas* nas_) : pdcp(pdcp_), nas(nas_), thread("DUMMY STACK") {}
void init() { start(-1); }
bool switch_on() final { return nas->attach_request(); }
void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu, bool blocking)
{
pdcp->write_sdu(lcid, std::move(sdu), blocking);
}
bool is_lcid_enabled(uint32_t lcid) { return pdcp->is_lcid_enabled(lcid); }
void run_thread()
{
running = true;
uint32_t counter = 0;
// while (running) {
// nas->run_tti(counter++);
// }
}
void stop()
{
running = false;
wait_thread_finish();
}
pdcp_interface_gw* pdcp = nullptr;
srsue::nas* nas = nullptr;
bool running = false;
@ -284,8 +297,10 @@ int mme_attach_request_test()
srslte::logger* logger = &def_logstdout;
gw.init(gw_args, logger, &stack);
stack.init();
// trigger test
stack.switch_on();
stack.stop();
// this will time out in the first place

Loading…
Cancel
Save