removed uneeded locks in the rlc, moved ue stack get_metrics to stack thread, solved the idle procedure double-locking

master
Francisco Paisana 5 years ago committed by Francisco Paisana
parent 95c6916987
commit 599588ff51

@ -82,20 +82,16 @@ void rlc::reset_metrics()
void rlc::stop() void rlc::stop()
{ {
pthread_rwlock_rdlock(&rwlock);
for (rlc_map_t::iterator it = rlc_array.begin(); it != rlc_array.end(); ++it) { for (rlc_map_t::iterator it = rlc_array.begin(); it != rlc_array.end(); ++it) {
it->second->stop(); it->second->stop();
} }
for (rlc_map_t::iterator it = rlc_array_mrb.begin(); it != rlc_array_mrb.end(); ++it) { for (rlc_map_t::iterator it = rlc_array_mrb.begin(); it != rlc_array_mrb.end(); ++it) {
it->second->stop(); it->second->stop();
} }
pthread_rwlock_unlock(&rwlock);
} }
void rlc::get_metrics(rlc_metrics_t& m) void rlc::get_metrics(rlc_metrics_t& m)
{ {
pthread_rwlock_rdlock(&rwlock);
gettimeofday(&metrics_time[2], NULL); gettimeofday(&metrics_time[2], NULL);
get_time_interval(metrics_time); get_time_interval(metrics_time);
double secs = (double)metrics_time[0].tv_sec + metrics_time[0].tv_usec * 1e-6; double secs = (double)metrics_time[0].tv_sec + metrics_time[0].tv_usec * 1e-6;
@ -120,15 +116,11 @@ void rlc::get_metrics(rlc_metrics_t& m)
memcpy(&metrics_time[1], &metrics_time[2], sizeof(struct timeval)); memcpy(&metrics_time[1], &metrics_time[2], sizeof(struct timeval));
reset_metrics(); reset_metrics();
pthread_rwlock_unlock(&rwlock);
} }
// Reestablish all RLC bearer // Reestablish all RLC bearer
void rlc::reestablish() void rlc::reestablish()
{ {
pthread_rwlock_rdlock(&rwlock);
for (rlc_map_t::iterator it = rlc_array.begin(); it != rlc_array.end(); ++it) { for (rlc_map_t::iterator it = rlc_array.begin(); it != rlc_array.end(); ++it) {
it->second->reestablish(); it->second->reestablish();
} }
@ -136,21 +128,17 @@ void rlc::reestablish()
for (rlc_map_t::iterator it = rlc_array_mrb.begin(); it != rlc_array_mrb.end(); ++it) { for (rlc_map_t::iterator it = rlc_array_mrb.begin(); it != rlc_array_mrb.end(); ++it) {
it->second->reestablish(); it->second->reestablish();
} }
pthread_rwlock_unlock(&rwlock);
} }
// Reestablish a specific RLC bearer // Reestablish a specific RLC bearer
void rlc::reestablish(uint32_t lcid) void rlc::reestablish(uint32_t lcid)
{ {
pthread_rwlock_rdlock(&rwlock);
if (valid_lcid(lcid)) { if (valid_lcid(lcid)) {
rlc_log->info("Reestablishing LCID %d\n", lcid); rlc_log->info("Reestablishing LCID %d\n", lcid);
rlc_array.at(lcid)->reestablish(); rlc_array.at(lcid)->reestablish();
} else { } else {
rlc_log->warning("RLC LCID %d doesn't exist. Deallocating SDU\n", lcid); rlc_log->warning("RLC LCID %d doesn't exist. Deallocating SDU\n", lcid);
} }
pthread_rwlock_unlock(&rwlock);
} }
// Resetting the RLC layer returns the object to the state after the call to init(): // Resetting the RLC layer returns the object to the state after the call to init():
@ -180,11 +168,9 @@ void rlc::reset()
void rlc::empty_queue() void rlc::empty_queue()
{ {
// Empty Tx queue, not needed for MCH bearers // Empty Tx queue, not needed for MCH bearers
pthread_rwlock_rdlock(&rwlock);
for (rlc_map_t::iterator it = rlc_array.begin(); it != rlc_array.end(); ++it) { for (rlc_map_t::iterator it = rlc_array.begin(); it != rlc_array.end(); ++it) {
it->second->empty_queue(); it->second->empty_queue();
} }
pthread_rwlock_unlock(&rwlock);
} }
/******************************************************************************* /*******************************************************************************

@ -176,7 +176,8 @@ private:
static const int STACK_MAIN_THREAD_PRIO = -1; // Use default high-priority below UHD static const int STACK_MAIN_THREAD_PRIO = -1; // Use default high-priority below UHD
srslte::task_multiqueue pending_tasks; srslte::task_multiqueue pending_tasks;
int sync_queue_id = -1, ue_queue_id = -1, gw_queue_id = -1, mac_queue_id = -1, background_queue_id = -1; int sync_queue_id = -1, ue_queue_id = -1, gw_queue_id = -1, mac_queue_id = -1, background_queue_id = -1;
srslte::task_thread_pool background_tasks; ///< Thread pool used for long, low-priority tasks srslte::task_thread_pool background_tasks; ///< Thread pool used for long, low-priority tasks
srslte::block_queue<stack_metrics_t> pending_stack_metrics;
// TTI stats // TTI stats
srslte::tprof<srslte::sliding_window_stats_ms> tti_tprof; srslte::tprof<srslte::sliding_window_stats_ms> tti_tprof;

@ -1003,7 +1003,8 @@ proc_outcome_t rrc::go_idle_proc::init()
{ {
Info("Starting...\n"); Info("Starting...\n");
rlc_flush_timer.run(); rlc_flush_timer.run();
return step(); // Do not call step() directly. Instead we defer for one TTI to avoid double-locking the RLC mutex
return proc_outcome_t::yield;
} }
srslte::proc_outcome_t rrc::go_idle_proc::react(bool timeout) srslte::proc_outcome_t rrc::go_idle_proc::react(bool timeout)

@ -210,10 +210,16 @@ bool ue_stack_lte::disable_data()
bool ue_stack_lte::get_metrics(stack_metrics_t* metrics) bool ue_stack_lte::get_metrics(stack_metrics_t* metrics)
{ {
mac.get_metrics(metrics->mac); // use stack thread to query metrics
rlc.get_metrics(metrics->rlc); pending_tasks.try_push(ue_queue_id, [this]() {
nas.get_metrics(&metrics->nas); stack_metrics_t metrics{};
rrc.get_metrics(metrics->rrc); mac.get_metrics(metrics.mac);
rlc.get_metrics(metrics.rlc);
nas.get_metrics(&metrics.nas);
rrc.get_metrics(metrics.rrc);
});
// wait for result
*metrics = pending_stack_metrics.wait_pop();
return (metrics->nas.state == EMM_STATE_REGISTERED && metrics->rrc.state == RRC_STATE_CONNECTED); return (metrics->nas.state == EMM_STATE_REGISTERED && metrics->rrc.state == RRC_STATE_CONNECTED);
} }

Loading…
Cancel
Save