SRSUE: Sync.h/.cc mutexes changed to C++11 std::mutex and fixed attributes initialisation

This commit is contained in:
Xavier Arteaga 2019-06-11 00:52:03 +02:00 committed by Xavier Arteaga
parent 810ce0358e
commit 9068280896
3 changed files with 93 additions and 127 deletions

View File

@ -42,7 +42,7 @@ typedef _Complex float cf_t;
class phy : public ue_lte_phy_base, public thread
{
public:
phy() : workers_pool(MAX_WORKERS), common(MAX_WORKERS), scell_sync(), thread("PHY"){};
phy() : workers_pool(MAX_WORKERS), common(MAX_WORKERS), thread("PHY"){};
~phy() override = default;
// Init defined in base class

View File

@ -22,7 +22,9 @@
#ifndef SRSUE_PHCH_RECV_H
#define SRSUE_PHCH_RECV_H
#include <condition_variable>
#include <map>
#include <mutex>
#include <pthread.h>
#include <srslte/phy/channel/channel.h>
@ -46,7 +48,7 @@ typedef _Complex float cf_t;
class sync : public thread, public chest_feedback_itf
{
public:
sync();
sync() : thread("SYNC") {};
~sync();
void init(radio_interface_phy* radio_,
@ -73,12 +75,12 @@ public:
int meas_stop(uint32_t earfcn, int pci);
// from chest_feedback_itf
void in_sync();
void out_of_sync();
void set_cfo(float cfo);
void in_sync() final;
void out_of_sync() final;
void set_cfo(float cfo) final;
void set_time_adv_sec(float time_adv_sec);
void get_current_cell(srslte_cell_t *cell, uint32_t *earfcn = NULL);
void get_current_cell(srslte_cell_t* cell, uint32_t* earfcn = nullptr);
uint32_t get_current_tti();
// From UE configuration
@ -105,19 +107,19 @@ private:
ret_code run(srslte_cell_t *cell);
private:
sync* p;
srslte::log* log_h;
cf_t *buffer[SRSLTE_MAX_PORTS];
srslte_ue_cellsearch_t cs;
srslte_ue_mib_sync_t ue_mib_sync;
int force_N_id_2;
sync* p = nullptr;
srslte::log* log_h = nullptr;
cf_t* buffer[SRSLTE_MAX_PORTS] = {};
srslte_ue_cellsearch_t cs = {};
srslte_ue_mib_sync_t ue_mib_sync = {};
int force_N_id_2 = 0;
};
// Class to synchronize system frame number
class sfn_sync {
public:
typedef enum {IDLE, SFN_FOUND, SFX0_FOUND, SFN_NOFOUND, ERROR} ret_code;
sfn_sync() = default;
~sfn_sync();
void init(srslte_ue_sync_t* ue_sync,
cf_t* buffer[SRSLTE_MAX_PORTS],
@ -132,12 +134,12 @@ private:
private:
const static int SFN_SYNC_NOF_SUBFRAMES = 100;
uint32_t cnt;
uint32_t timeout;
srslte::log *log_h;
srslte_ue_sync_t *ue_sync;
cf_t *buffer[SRSLTE_MAX_PORTS];
srslte_ue_mib_t ue_mib;
uint32_t cnt = 0;
uint32_t timeout = 0;
srslte::log* log_h = nullptr;
srslte_ue_sync_t* ue_sync = nullptr;
cf_t* buffer[SRSLTE_MAX_PORTS] = {};
srslte_ue_mib_t ue_mib = {};
};
/* TODO: Intra-freq measurements can be improved by capturing 200 ms length signal and run cell search +
@ -149,49 +151,49 @@ private:
void reset();
void radio_error();
void set_ue_sync_opts(srslte_ue_sync_t *q, float cfo);
void run_thread();
void run_thread() final;
float get_tx_cfo();
void set_sampling_rate();
bool set_frequency();
bool set_cell();
bool radio_is_overflow;
bool radio_overflow_return;
bool running;
bool radio_is_overflow = false;
bool radio_overflow_return = false;
bool running = false;
// Objects for internal use
search search_p;
sfn_sync sfn_p;
scell::intra_measure intra_freq_meas;
uint32_t current_sflen;
int next_offset; // Sample offset triggered by Time aligment commands
int next_radio_offset[SRSLTE_MAX_RADIOS]; // Sample offset triggered by SFO compensation
uint32_t current_sflen = 0;
int next_offset = 0; // Sample offset triggered by Time aligment commands
int next_radio_offset[SRSLTE_MAX_RADIOS] = {}; // Sample offset triggered by SFO compensation
// Pointers to other classes
stack_interface_phy_lte* stack;
srslte::log* log_h;
srslte::log* log_phy_lib_h;
srslte::thread_pool* workers_pool;
radio_interface_phy* radio_h;
phy_common* worker_com;
prach* prach_buffer;
scell::async_recv_vector* scell_sync;
stack_interface_phy_lte* stack = nullptr;
srslte::log* log_h = nullptr;
srslte::log* log_phy_lib_h = nullptr;
srslte::thread_pool* workers_pool = nullptr;
radio_interface_phy* radio_h = nullptr;
phy_common* worker_com = nullptr;
prach* prach_buffer = nullptr;
scell::async_recv_vector* scell_sync = nullptr;
srslte::channel_ptr channel_emulator = nullptr;
// Object for synchronization of the primary cell
srslte_ue_sync_t ue_sync;
srslte_ue_sync_t ue_sync = {};
// Buffer for primary and secondary cell samples
cf_t* sf_buffer[SRSLTE_MAX_RADIOS][SRSLTE_MAX_PORTS];
cf_t* sf_buffer[SRSLTE_MAX_RADIOS][SRSLTE_MAX_PORTS] = {};
// Sync metrics
sync_metrics_t metrics;
sync_metrics_t metrics = {};
// in-sync / out-of-sync counters
uint32_t out_of_sync_cnt;
uint32_t in_sync_cnt;
uint32_t out_of_sync_cnt = 0;
uint32_t in_sync_cnt = 0;
const static uint32_t NOF_OUT_OF_SYNC_SF = 20;
const static uint32_t NOF_IN_SYNC_SF = 10;
@ -210,33 +212,31 @@ private:
* and returns the current state
*/
state_t run_state() {
pthread_mutex_lock(&inside);
std::unique_lock<std::mutex> ul(inside);
cur_state = next_state;
if (state_setting) {
state_setting = false;
state_running = true;
}
pthread_cond_broadcast(&cvar);
pthread_mutex_unlock(&inside);
cvar.notify_all();
inside.unlock();
return cur_state;
}
// Called by the main thread at the end of each state to indicate it has finished.
void state_exit(bool exit_ok = true) {
pthread_mutex_lock(&inside);
std::unique_lock<std::mutex> ul(inside);
if (cur_state == SFN_SYNC && exit_ok == true) {
next_state = CAMPING;
} else {
next_state = IDLE;
}
state_running = false;
pthread_cond_broadcast(&cvar);
pthread_mutex_unlock(&inside);
cvar.notify_all();
}
void force_sfn_sync() {
pthread_mutex_lock(&inside);
std::unique_lock<std::mutex> ul(inside);
next_state = SFN_SYNC;
pthread_mutex_unlock(&inside);
}
/* Functions to be called from outside the STM thread to instruct the STM to switch state.
@ -245,23 +245,23 @@ private:
* These functions are mutexed and only 1 can be called at a time
*/
void go_idle() {
pthread_mutex_lock(&outside);
outside.lock();
go_state(IDLE);
pthread_mutex_unlock(&outside);
outside.unlock();
}
void run_cell_search() {
pthread_mutex_lock(&outside);
outside.lock();
go_state(CELL_SEARCH);
wait_state_run();
wait_state_next();
pthread_mutex_unlock(&outside);
outside.unlock();
}
void run_sfn_sync() {
pthread_mutex_lock(&outside);
outside.lock();
go_state(SFN_SYNC);
wait_state_run();
wait_state_next();
pthread_mutex_unlock(&outside);
outside.unlock();
}
@ -288,81 +288,71 @@ private:
}
}
sync_state() {
pthread_mutex_init(&inside, NULL);
pthread_mutex_init(&outside, NULL);
pthread_cond_init(&cvar, NULL);
cur_state = IDLE;
next_state = IDLE;
state_setting = false;
state_running = false;
}
private:
sync_state() = default;
private:
void go_state(state_t s) {
pthread_mutex_lock(&inside);
std::unique_lock<std::mutex> ul(inside);
next_state = s;
state_setting = true;
while(state_setting) {
pthread_cond_wait(&cvar, &inside);
cvar.wait(ul);
}
pthread_mutex_unlock(&inside);
}
/* Waits until there is a call to set_state() and then run_state(). Returns when run_state() returns */
void wait_state_run()
{
pthread_mutex_lock(&inside);
std::unique_lock<std::mutex> ul(inside);
while (state_running) {
pthread_cond_wait(&cvar, &inside);
cvar.wait(ul);
}
pthread_mutex_unlock(&inside);
}
void wait_state_next()
{
pthread_mutex_lock(&inside);
std::unique_lock<std::mutex> ul(inside);
while (cur_state != next_state) {
pthread_cond_wait(&cvar, &inside);
cvar.wait(ul);
}
pthread_mutex_unlock(&inside);
}
bool state_running, state_setting;
state_t cur_state, next_state;
pthread_mutex_t inside, outside;
pthread_cond_t cvar;
bool state_running = false;
bool state_setting = false;
state_t cur_state = IDLE;
state_t next_state = IDLE;
std::mutex inside;
std::mutex outside;
std::condition_variable cvar;
};
pthread_mutex_t rrc_mutex;
std::mutex rrc_mutex;
sync_state phy_state;
search::ret_code cell_search_ret;
search::ret_code cell_search_ret = search::CELL_NOT_FOUND;
// Sampling rate mode (find is 1.96 MHz, camp is the full cell BW)
enum {
SRATE_NONE=0, SRATE_FIND, SRATE_CAMP
} srate_mode;
float current_srate;
} srate_mode = SRATE_NONE;
float current_srate = 0;
// This is the primary cell
srslte_cell_t cell;
bool started;
float time_adv_sec, next_time_adv_sec;
uint32_t tti;
bool do_agc;
srslte_cell_t cell = {};
bool started = false;
float time_adv_sec = 0;
float next_time_adv_sec = 0;
uint32_t tti = 0;
uint32_t tx_worker_cnt;
uint32_t nof_workers;
uint32_t tx_worker_cnt = 0;
uint32_t nof_workers = 0;
float ul_dl_factor;
int current_earfcn;
uint32_t cellsearch_earfcn_index;
float dl_freq;
float ul_freq;
float ul_dl_factor = NAN;
int current_earfcn = 0;
uint32_t cellsearch_earfcn_index = 0;
float dl_freq = -1;
float ul_freq = -1;
};
} // namespace srsue

View File

@ -42,24 +42,6 @@ double callback_set_rx_gain(void *h, double gain) {
return ((sync*)h)->set_rx_gain(gain);
}
sync::sync() : thread("SYNC")
{
cellsearch_earfcn_index = 0;
current_sflen = 0;
next_offset = 0;
current_earfcn = 0;
current_srate = 0;
next_time_adv_sec = 0;
time_adv_sec = 0;
tti = 0;
dl_freq = -1;
ul_freq = -1;
bzero(&cell, sizeof(srslte_cell_t));
bzero(&metrics, sizeof(sync_metrics_t));
running = false;
worker_com = NULL;
}
void sync::init(radio_interface_phy* _radio,
stack_interface_phy_lte* _stack,
prach* _prach_buffer,
@ -108,8 +90,6 @@ void sync::init(radio_interface_phy* _radio,
// Start intra-frequency measurement
intra_freq_meas.init(worker_com, stack, log_h);
pthread_mutex_init(&rrc_mutex, NULL);
reset();
running = true;
@ -135,7 +115,6 @@ sync::~sync()
}
}
}
pthread_mutex_destroy(&rrc_mutex);
srslte_ue_sync_free(&ue_sync);
}
}
@ -210,7 +189,7 @@ phy_interface_rrc_lte::cell_search_ret_t sync::cell_search(phy_interface_rrc_lte
ret.found = phy_interface_rrc_lte::cell_search_ret_t::ERROR;
ret.last_freq = phy_interface_rrc_lte::cell_search_ret_t::NO_MORE_FREQS;
pthread_mutex_lock(&rrc_mutex);
rrc_mutex.lock();
// Move state to IDLE
Info("Cell Search: Start EARFCN index=%u/%zd\n", cellsearch_earfcn_index, earfcn.size());
@ -275,7 +254,7 @@ phy_interface_rrc_lte::cell_search_ret_t sync::cell_search(phy_interface_rrc_lte
ret.last_freq = phy_interface_rrc_lte::cell_search_ret_t::MORE_FREQS;
}
pthread_mutex_unlock(&rrc_mutex);
rrc_mutex.unlock();
return ret;
}
@ -284,7 +263,7 @@ phy_interface_rrc_lte::cell_search_ret_t sync::cell_search(phy_interface_rrc_lte
*/
bool sync::cell_select(phy_interface_rrc_lte::phy_cell_t* new_cell)
{
pthread_mutex_lock(&rrc_mutex);
std::unique_lock<std::mutex> ul(rrc_mutex);
bool ret = false;
int cnt = 0;
@ -295,7 +274,7 @@ bool sync::cell_select(phy_interface_rrc_lte::phy_cell_t* new_cell)
} else {
if (!srslte_cell_isvalid(&cell)) {
log_h->error("Cell Select: Invalid cell. ID=%d, PRB=%d, ports=%d\n", cell.id, cell.nof_prb, cell.nof_ports);
goto unlock;
return ret;
}
Info("Cell Select: Starting cell selection for PCI=%d, EARFCN=%d\n", new_cell->cell.id, new_cell->earfcn);
}
@ -322,7 +301,7 @@ bool sync::cell_select(phy_interface_rrc_lte::phy_cell_t* new_cell)
cell = new_cell->cell;
if (!set_cell()) {
Error("Cell Select: Reconfiguring cell\n");
goto unlock;
return ret;
}
}
@ -331,7 +310,7 @@ bool sync::cell_select(phy_interface_rrc_lte::phy_cell_t* new_cell)
Info("Cell Select: Setting new frequency EARFCN=%d\n", new_cell->earfcn);
if (set_frequency()) {
Error("Cell Select: Setting new frequency EARFCN=%d\n", new_cell->earfcn);
goto unlock;
return ret;
}
current_earfcn = new_cell->earfcn;
}
@ -352,8 +331,6 @@ bool sync::cell_select(phy_interface_rrc_lte::phy_cell_t* new_cell)
Info("Cell Select: Could not synchronize SFN\n");
}
unlock:
pthread_mutex_unlock(&rrc_mutex);
return ret;
}
@ -629,7 +606,7 @@ void sync::run_thread()
/* Radio overflow detected. If CAMPING, go through SFN sync again and when
* SFN is found again go back to camping
*/
if (!pthread_mutex_trylock(&rrc_mutex)) {
if (!rrc_mutex.try_lock()) {
if (radio_is_overflow) {
// If we are coming back from an overflow
if (radio_overflow_return) {
@ -656,7 +633,7 @@ void sync::run_thread()
// If overflow occurs in any other state, it does not harm
}
}
pthread_mutex_unlock(&rrc_mutex);
rrc_mutex.unlock();
}
// Increase TTI counter
@ -732,8 +709,7 @@ void sync::set_cfo(float cfo)
void sync::set_agc_enable(bool enable)
{
do_agc = enable;
if (do_agc) {
if (enable) {
if (running && radio_h) {
srslte_rf_info_t* rf_info = radio_h->get_info(0);
srslte_ue_sync_start_agc(