SRSENB: cleanup and mutex rearange

This commit is contained in:
Xavier Arteaga 2019-10-17 16:44:45 +02:00 committed by Andre Puschmann
parent 8e92baf401
commit f9a795e985
11 changed files with 124 additions and 152 deletions

View File

@ -35,8 +35,8 @@ class cc_worker
{
public:
cc_worker();
~cc_worker();
void init(phy_common* phy, srslte::log* log_h, uint32_t cc_idx);
void stop();
void reset();
cf_t* get_buffer_rx(uint32_t antenna_idx);
@ -133,6 +133,7 @@ private:
// Each worker keeps a local copy of the user database. Uses more memory but more efficient to manage concurrency
std::map<uint16_t, ue*> ue_db;
std::mutex mutex;
};
} // namespace srsenb

View File

@ -60,9 +60,9 @@ public:
std::string get_type() { return "lte"; };
/* MAC->PHY interface */
int add_rnti(uint16_t rnti, bool is_temporal = false);
void rem_rnti(uint16_t rnti);
void set_mch_period_stop(uint32_t stop);
int add_rnti(uint16_t rnti, bool is_temporal = false) final;
void rem_rnti(uint16_t rnti) final;
void set_mch_period_stop(uint32_t stop) final;
/*RRC-PHY interface*/
void configure_mbsfn(asn1::rrc::sib_type2_s* sib2, asn1::rrc::sib_type13_r9_s* sib13, asn1::rrc::mcch_msg_s mcch);

View File

@ -68,21 +68,21 @@ public:
void worker_end(uint32_t tx_mutex_cnt, cf_t *buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, srslte_timestamp_t tx_time);
// Common objects
srslte_cell_t cell;
phy_args_t params;
srslte_cell_t cell = {};
phy_args_t params = {};
// Physical Uplink Config common
srslte_ul_cfg_t ul_cfg_com;
srslte_ul_cfg_t ul_cfg_com = {};
// Physical Downlink Config common
srslte_dl_cfg_t dl_cfg_com;
srslte_dl_cfg_t dl_cfg_com = {};
srslte::radio_interface_phy* radio;
stack_interface_phy_lte* stack;
srslte::radio_interface_phy* radio = nullptr;
stack_interface_phy_lte* stack = nullptr;
// Common objects for schedulign grants
stack_interface_phy_lte::ul_sched_t ul_grants[TTIMOD_SZ];
stack_interface_phy_lte::dl_sched_t dl_grants[TTIMOD_SZ];
stack_interface_phy_lte::ul_sched_t ul_grants[TTIMOD_SZ] = {};
stack_interface_phy_lte::dl_sched_t dl_grants[TTIMOD_SZ] = {};
// Map of pending ACKs for each user
typedef struct {
@ -92,19 +92,19 @@ public:
class common_ue {
public:
pending_ack_t pending_ack;
uint8_t ri;
srslte_ra_tb_t last_tb[SRSLTE_MAX_HARQ_PROC];
pending_ack_t pending_ack = {};
uint8_t ri = 0;
srslte_ra_tb_t last_tb[SRSLTE_MAX_HARQ_PROC] = {};
};
std::map<uint16_t, common_ue> common_ue_db;
void ue_db_add_rnti(uint16_t rnti);
void ue_db_rem_rnti(uint16_t rnti);
void ue_db_add_rnti(uint16_t rnti);
void ue_db_rem_rnti(uint16_t rnti);
void ue_db_clear(uint32_t tti);
void ue_db_set_ack_pending(uint32_t tti, uint16_t rnti, uint32_t tb_idx, uint32_t n_pdcch);
bool ue_db_is_ack_pending(uint32_t tti, uint16_t rnti, uint32_t tb_idx, uint32_t* last_n_pdcch = NULL);
void ue_db_set_ri(uint16_t rnti, uint8_t ri);
bool ue_db_is_ack_pending(uint32_t tti, uint16_t rnti, uint32_t tb_idx, uint32_t* last_n_pdcch = nullptr);
void ue_db_set_ri(uint16_t rnti, uint8_t ri);
uint8_t ue_db_get_ri(uint16_t rnti);
void ue_db_set_last_ul_tb(uint16_t rnti, uint32_t pid, srslte_ra_tb_t tb);
@ -118,23 +118,22 @@ public:
private:
std::vector<sem_t> tx_sem;
bool is_first_tx;
bool is_first_of_burst;
bool is_first_tx = false;
uint32_t nof_workers;
uint32_t max_workers;
uint32_t nof_workers = 0;
uint32_t max_workers = 0;
pthread_mutex_t user_mutex;
pthread_mutex_t user_mutex = {};
bool have_mtch_stop;
pthread_mutex_t mtch_mutex;
pthread_cond_t mtch_cvar;
bool have_mtch_stop = false;
pthread_mutex_t mtch_mutex = {};
pthread_cond_t mtch_cvar = {};
phy_interface_stack_lte::phy_cfg_mbsfn_t mbsfn;
bool sib13_configured;
bool mcch_configured;
bool sib13_configured = false;
bool mcch_configured = false;
uint8_t mch_table[40] = {};
uint8_t mcch_table[10] = {};
uint32_t mch_period_stop;
uint32_t mch_period_stop = 0;
uint8_t mch_sf_idx_lut[10] = {};
bool is_mch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti);
bool is_mcch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti);

View File

@ -43,8 +43,8 @@ public:
sf_cnt(0),
thread("PRACH_WORKER")
{
log_h = NULL;
stack = NULL;
log_h = nullptr;
stack = nullptr;
bzero(&prach, sizeof(srslte_prach_t));
bzero(&prach_indices, sizeof(prach_indices));
bzero(&prach_offsets, sizeof(prach_offsets));
@ -75,36 +75,32 @@ private:
const static int sf_buffer_sz = 128*1024;
class sf_buffer {
public:
sf_buffer()
{
nof_samples = 0;
tti = 0;
}
sf_buffer() = default;
void reset()
{
nof_samples = 0;
tti = 0;
}
cf_t samples[sf_buffer_sz];
uint32_t nof_samples;
uint32_t tti;
cf_t samples[sf_buffer_sz] = {};
uint32_t nof_samples = 0;
uint32_t tti = 0;
#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED
char debug_name[SRSLTE_BUFFER_POOL_LOG_NAME_LEN];
#endif /* SRSLTE_BUFFER_POOL_LOG_ENABLED */
};
srslte::buffer_pool<sf_buffer> buffer_pool;
srslte::block_queue<sf_buffer*> pending_buffers;
sf_buffer* current_buffer;
srslte::log* log_h;
stack_interface_phy_lte* stack;
float max_prach_offset_us;
bool initiated;
bool running;
uint32_t nof_sf;
uint32_t sf_cnt;
sf_buffer* current_buffer = nullptr;
srslte::log* log_h = nullptr;
stack_interface_phy_lte* stack = nullptr;
float max_prach_offset_us = 0.0f;
bool initiated = 0;
bool running = false;
uint32_t nof_sf = 0;
uint32_t sf_cnt = 0;
void run_thread();
void run_thread() final;
int run_tti(sf_buffer *b);

View File

@ -35,7 +35,7 @@ class sf_worker : public srslte::thread_pool::worker
{
public:
sf_worker() = default;
~sf_worker() = default;
~sf_worker();
void init(phy_common* phy, srslte::log* log_h);
void stop() final;
@ -65,7 +65,7 @@ private:
phy_common* phy = nullptr;
bool initiated = false;
bool running = false;
bool is_worker_running = false;
std::mutex work_mutex;
uint32_t tti_rx = 0, tti_tx_dl = 0, tti_tx_ul = 0;
uint32_t t_rx = 0, t_tx_dl = 0, t_tx_ul = 0;
@ -74,13 +74,7 @@ private:
std::vector<std::unique_ptr<cc_worker> > cc_workers;
srslte_dl_sf_cfg_t dl_sf = {};
srslte_ul_sf_cfg_t ul_sf = {};
srslte_softbuffer_tx_t temp_mbsfn_softbuffer = {};
// mutex to protect worker_imp() from configuration interface
std::mutex mutex;
};
} // namespace srsenb

View File

@ -46,21 +46,20 @@ public:
void stop();
private:
void run_thread();
void run_thread() final;
srslte::radio_interface_phy* radio_h;
srslte::log *log_h;
srslte::thread_pool *workers_pool;
prach_worker* prach;
phy_common* worker_com;
srslte::radio_interface_phy* radio_h = nullptr;
srslte::log* log_h = nullptr;
srslte::thread_pool* workers_pool = nullptr;
prach_worker* prach = nullptr;
phy_common* worker_com = nullptr;
// Main system TTI counter
uint32_t tti;
uint32_t tti = 0;
uint32_t tx_worker_cnt;
uint32_t nof_workers;
bool running;
uint32_t tx_worker_cnt = 0;
uint32_t nof_workers = 0;
bool running = false;
};
} // namespace srsenb

View File

@ -59,6 +59,27 @@ cc_worker::cc_worker()
reset();
}
cc_worker::~cc_worker()
{
srslte_softbuffer_tx_free(&temp_mbsfn_softbuffer);
srslte_enb_dl_free(&enb_dl);
srslte_enb_ul_free(&enb_ul);
for (int p = 0; p < SRSLTE_MAX_PORTS; p++) {
if (signal_buffer_rx[p]) {
free(signal_buffer_rx[p]);
}
if (signal_buffer_tx[p]) {
free(signal_buffer_tx[p]);
}
}
// Delete all users
for (auto& it : ue_db) {
delete it.second;
}
}
#ifdef DEBUG_WRITE_FILE
FILE* f;
#endif
@ -132,25 +153,6 @@ void cc_worker::init(phy_common* phy_, srslte::log* log_h_, uint32_t cc_idx_)
#endif
}
void cc_worker::stop()
{
srslte_softbuffer_tx_free(&temp_mbsfn_softbuffer);
srslte_enb_dl_free(&enb_dl);
srslte_enb_ul_free(&enb_ul);
for (int p = 0; p < SRSLTE_MAX_PORTS; p++) {
if (signal_buffer_rx[p]) {
free(signal_buffer_rx[p]);
}
if (signal_buffer_tx[p]) {
free(signal_buffer_tx[p]);
}
}
// Delete all users
for (auto& it : ue_db) {
delete it.second;
}
}
void cc_worker::reset()
{
initiated = false;
@ -190,16 +192,19 @@ int cc_worker::add_rnti(uint16_t rnti, bool is_temporal)
}
}
mutex.lock();
// Create user unless already exists
if (!ue_db.count(rnti)) {
ue_db[rnti] = new ue(rnti, phy);
}
mutex.unlock();
return SRSLTE_SUCCESS;
}
void cc_worker::rem_rnti(uint16_t rnti)
{
std::lock_guard<std::mutex> lock(mutex);
if (ue_db.count(rnti)) {
delete ue_db[rnti];
@ -228,11 +233,14 @@ void cc_worker::rem_rnti(uint16_t rnti)
uint32_t cc_worker::get_nof_rnti()
{
std::lock_guard<std::mutex> lock(mutex);
return ue_db.size();
}
void cc_worker::set_config_dedicated(uint16_t rnti, asn1::rrc::phys_cfg_ded_s* dedicated)
{
std::lock_guard<std::mutex> lock(mutex);
if (ue_db.count(rnti)) {
if (dedicated->pusch_cfg_ded_present && dedicated->sched_request_cfg_present) {
@ -311,6 +319,7 @@ void cc_worker::set_config_dedicated(uint16_t rnti, asn1::rrc::phys_cfg_ded_s* d
void cc_worker::work_ul(srslte_ul_sf_cfg_t* ul_sf_cfg, stack_interface_phy_lte::ul_sched_t* ul_grants)
{
std::lock_guard<std::mutex> lock(mutex);
ul_sf = *ul_sf_cfg;
log_h->step(ul_sf.tti);
@ -334,6 +343,7 @@ void cc_worker::work_dl(srslte_dl_sf_cfg_t* dl_sf_cfg,
stack_interface_phy_lte::ul_sched_t* ul_grants,
srslte_mbsfn_cfg_t* mbsfn_cfg)
{
std::lock_guard<std::mutex> lock(mutex);
dl_sf = *dl_sf_cfg;
// Put base signals (references, PBCH, PCFICH and PSS/SSS) into the resource grid
@ -711,6 +721,7 @@ int cc_worker::encode_pdsch(stack_interface_phy_lte::dl_sched_grant_t* grants, u
/************ METRICS interface ********************/
uint32_t cc_worker::get_metrics(phy_metrics_t metrics[ENB_METRICS_MAX_USERS])
{
std::lock_guard<std::mutex> lock(mutex);
uint32_t cnt = 0;
for (auto& iter : ue_db) {
ue* u = iter.second;

View File

@ -37,20 +37,12 @@ using namespace asn1::rrc;
namespace srsenb {
phy_common::phy_common(uint32_t max_workers) : tx_sem(max_workers)
phy_common::phy_common(uint32_t max_workers_) : tx_sem(max_workers_)
{
this->nof_workers = nof_workers;
nof_workers = max_workers_;
params.max_prach_offset_us = 20;
radio = NULL;
stack = NULL;
is_first_tx = false;
is_first_of_burst = false;
have_mtch_stop = false;
this->max_workers = max_workers;
ZERO_OBJECT(ul_cfg_com);
ZERO_OBJECT(dl_cfg_com);
ZERO_OBJECT(ul_grants);
max_workers = max_workers_;
for (uint32_t i = 0; i < max_workers; i++) {
sem_init(&tx_sem[i], 0, 0); // All semaphores start blocked
@ -64,9 +56,9 @@ phy_common::~phy_common()
}
}
void phy_common::set_nof_workers(uint32_t nof_workers)
void phy_common::set_nof_workers(uint32_t nof_workers_)
{
this->nof_workers = nof_workers;
nof_workers = nof_workers_;
}
void phy_common::reset()
@ -83,11 +75,10 @@ bool phy_common::init(const srslte_cell_t& cell_,
stack = stack_;
cell = cell_;
pthread_mutex_init(&user_mutex, NULL);
pthread_mutex_init(&mtch_mutex, NULL);
pthread_cond_init(&mtch_cvar, NULL);
pthread_mutex_init(&user_mutex, nullptr);
pthread_mutex_init(&mtch_mutex, nullptr);
pthread_cond_init(&mtch_cvar, nullptr);
is_first_of_burst = true;
is_first_tx = true;
reset();
return true;
@ -136,7 +127,7 @@ void phy_common::worker_end(uint32_t tti,
void phy_common::ue_db_clear(uint32_t tti)
{
for(std::map<uint16_t,common_ue>::iterator iter=common_ue_db.begin(); iter!=common_ue_db.end(); ++iter) {
for (auto iter = common_ue_db.begin(); iter != common_ue_db.end(); ++iter) {
pending_ack_t *p = &((common_ue*)&iter->second)->pending_ack;
for (uint32_t tb_idx = 0; tb_idx < SRSLTE_MAX_TB; tb_idx++) {
p->is_pending[TTIMOD(tti)][tb_idx] = false;

View File

@ -62,7 +62,7 @@ void prach_worker::stop()
srslte_prach_free(&prach);
running = false;
sf_buffer *s = NULL;
sf_buffer* s = nullptr;
pending_buffers.push(s);
wait_thread_finish();
}

View File

@ -108,20 +108,9 @@ void sf_worker::init(phy_common* phy_, srslte::log* log_h_)
void sf_worker::stop()
{
std::lock_guard<std::mutex> lock(work_mutex);
running = false;
std::lock_guard<std::mutex> lg(mutex);
int cnt = 0;
while (is_worker_running && cnt < 100) {
usleep(1000);
cnt++;
}
if (!is_worker_running) {
srslte_softbuffer_tx_free(&temp_mbsfn_softbuffer);
} else {
log_h->console("Warning could not stop properly PHY\n");
}
srslte::thread_pool::worker::stop();
}
cf_t* sf_worker::get_buffer_rx(uint32_t cc_idx, uint32_t antenna_idx)
@ -140,7 +129,7 @@ void sf_worker::set_time(uint32_t tti_, uint32_t tx_worker_cnt_, srslte_timestam
t_tx_ul = TTIMOD(tti_tx_ul);
tx_worker_cnt = tx_worker_cnt_;
memcpy(&tx_time, &tx_time_, sizeof(srslte_timestamp_t));
srslte_timestamp_copy(&tx_time, &tx_time_);
for (auto& w : cc_workers) {
w->set_tti(tti_);
@ -149,7 +138,6 @@ void sf_worker::set_time(uint32_t tti_, uint32_t tx_worker_cnt_, srslte_timestam
int sf_worker::add_rnti(uint16_t rnti, bool is_temporal)
{
std::lock_guard<std::mutex> lg(mutex);
for (auto& w : cc_workers) {
w->add_rnti(rnti, is_temporal);
}
@ -158,7 +146,6 @@ int sf_worker::add_rnti(uint16_t rnti, bool is_temporal)
void sf_worker::rem_rnti(uint16_t rnti)
{
std::lock_guard<std::mutex> lg(mutex);
for (auto& w : cc_workers) {
w->rem_rnti(rnti);
}
@ -171,7 +158,6 @@ uint32_t sf_worker::get_nof_rnti()
void sf_worker::set_config_dedicated(uint16_t rnti, asn1::rrc::phys_cfg_ded_s* dedicated)
{
std::lock_guard<std::mutex> lg(mutex);
for (auto& w : cc_workers) {
w->set_config_dedicated(rnti, dedicated);
}
@ -179,13 +165,15 @@ void sf_worker::set_config_dedicated(uint16_t rnti, asn1::rrc::phys_cfg_ded_s* d
void sf_worker::work_imp()
{
std::lock_guard<std::mutex> lg(mutex);
std::lock_guard<std::mutex> lock(work_mutex);
cf_t* signal_buffer_tx[SRSLTE_MAX_PORTS * SRSLTE_MAX_CARRIERS];
srslte_ul_sf_cfg_t ul_sf = {};
srslte_dl_sf_cfg_t dl_sf = {};
if (!running) {
return;
}
is_worker_running = true;
srslte_mbsfn_cfg_t mbsfn_cfg;
srslte_sf_t sf_type = phy->is_mbsfn_sf(&mbsfn_cfg, tti_tx_dl) ? SRSLTE_SF_MBSFN : SRSLTE_SF_NORM;
@ -199,7 +187,6 @@ void sf_worker::work_imp()
Debug("Worker %d running\n", get_id());
// Configure UL subframe
ZERO_OBJECT(ul_sf);
ul_sf.tti = tti_rx;
// Process UL
@ -212,29 +199,28 @@ void sf_worker::work_imp()
if (sf_type == SRSLTE_SF_NORM) {
if (stack->get_dl_sched(tti_tx_dl, &dl_grants[t_tx_dl]) < 0) {
Error("Getting DL scheduling from MAC\n");
goto unlock;
return;
}
} else {
dl_grants[t_tx_dl].cfi = mbsfn_cfg.non_mbsfn_region_length;
if (stack->get_mch_sched(tti_tx_dl, mbsfn_cfg.is_mcch, &dl_grants[t_tx_dl])) {
Error("Getting MCH packets from MAC\n");
goto unlock;
return;
}
}
if (dl_grants[t_tx_dl].cfi < 1 || dl_grants[t_tx_dl].cfi > 3) {
Error("Invalid CFI=%d\n", dl_grants[t_tx_dl].cfi);
goto unlock;
return;
}
// Get UL scheduling for the TX TTI from MAC
if (stack->get_ul_sched(tti_tx_ul, &ul_grants[t_tx_ul]) < 0) {
Error("Getting UL scheduling from MAC\n");
goto unlock;
return;
}
// Configure DL subframe
ZERO_OBJECT(dl_sf);
dl_sf.tti = tti_tx_dl;
dl_sf.cfi = dl_grants[t_tx_dl].cfi;
dl_sf.sf_type = sf_type;
@ -255,8 +241,6 @@ void sf_worker::work_imp()
Debug("Sending to radio\n");
phy->worker_end(tx_worker_cnt, signal_buffer_tx, SRSLTE_SF_LEN_PRB(phy->cell.nof_prb), tx_time);
is_worker_running = false;
#ifdef DEBUG_WRITE_FILE
fwrite(signal_buffer_tx, SRSLTE_SF_LEN_PRB(phy->cell.nof_prb) * sizeof(cf_t), 1, f);
#endif
@ -275,10 +259,6 @@ void sf_worker::work_imp()
}
#endif
unlock:
if (is_worker_running) {
is_worker_running = false;
}
}
/************ METRICS interface ********************/
@ -339,6 +319,11 @@ int sf_worker::read_pucch_d(cf_t* pdsch_d)
return cc_workers[0]->read_pucch_d(pdsch_d);
}
sf_worker::~sf_worker()
{
srslte_softbuffer_tx_free(&temp_mbsfn_softbuffer);
}
} // namespace srsenb
/***********************************************************

View File

@ -38,14 +38,9 @@ using namespace std;
namespace srsenb {
txrx::txrx() : tx_worker_cnt(0), nof_workers(0), tti(0), thread("TXRX")
txrx::txrx() : thread("TXRX")
{
running = false;
radio_h = NULL;
log_h = NULL;
workers_pool = NULL;
worker_com = NULL;
prach = NULL;
/* Do nothing */
}
bool txrx::init(srslte::radio_interface_phy* radio_h_,
@ -78,10 +73,11 @@ void txrx::stop()
void txrx::run_thread()
{
sf_worker* worker = NULL;
cf_t *buffer[SRSLTE_MAX_PORTS] = {NULL};
srslte_timestamp_t rx_time = {}, tx_time = {};
uint32_t sf_len = SRSLTE_SF_LEN_PRB(worker_com->cell.nof_prb);
sf_worker* worker = nullptr;
cf_t* buffer[SRSLTE_MAX_PORTS] = {};
srslte_timestamp_t rx_time = {};
srslte_timestamp_t tx_time = {};
uint32_t sf_len = SRSLTE_SF_LEN_PRB(worker_com->cell.nof_prb);
float samp_rate = srslte_sampling_freq_hz(worker_com->cell.nof_prb);
log_h->console("Setting Sampling frequency %.2f MHz\n", (float) samp_rate/1000000);