From f0670154b332af38b9cb7c25800fff245a422176 Mon Sep 17 00:00:00 2001 From: Robert Schmidt <robert.schmidt@eurecom.fr> Date: Fri, 20 Apr 2018 14:25:41 +0200 Subject: [PATCH] Correctly join RU threads * join pthread_FH (ru_thread) once all condition variables have been set * join RU FHTX only if it has been started (check as for pthread_create()) * join PRACH thread in the monolithic case * send broadcast on condition variable cond_eNBs, as there can be multiple waits on it * integrate stop_ru(*ru) into kill_RU_proc(*ru) * Correct memory freeing --- targets/RT/USER/lte-ru.c | 79 +++++++++++++++------------------ targets/RT/USER/lte-softmodem.c | 34 +++++++------- targets/RT/USER/lte-softmodem.h | 2 +- 3 files changed, 53 insertions(+), 62 deletions(-) diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 0a25dca360..d20b614ad7 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -2230,11 +2230,36 @@ void init_RU_proc(RU_t *ru) { } -void kill_RU_proc(int inst) +void kill_RU_proc(RU_t *ru) { - RU_t *ru = RC.ru[inst]; RU_proc_t *proc = &ru->proc; +#if defined(PRE_SCD_THREAD) + pthread_mutex_lock(&proc->mutex_pre_scd); + ru->proc.instance_pre_scd = 0; + pthread_cond_signal(&proc->cond_pre_scd); + pthread_mutex_unlock(&proc->mutex_pre_scd); + pthread_join(proc->pthread_pre_scd, NULL); + pthread_mutex_destroy(&proc->mutex_pre_scd); + pthread_cond_destroy(&proc->cond_pre_scd); +#endif +#ifdef PHY_TX_THREAD + pthread_mutex_lock(&proc->mutex_phy_tx); + proc->instance_cnt_phy_tx = 0; + pthread_cond_signal(&proc->cond_phy_tx); + pthread_mutex_unlock(&proc->mutex_phy_tx); + pthread_join(ru->proc.pthread_phy_tx, NULL); + pthread_mutex_destroy( &proc->mutex_phy_tx); + pthread_cond_destroy( &proc->cond_phy_tx); + pthread_mutex_lock(&proc->mutex_rf_tx); + proc->instance_cnt_rf_tx = 0; + pthread_cond_signal(&proc->cond_rf_tx); + pthread_mutex_unlock(&proc->mutex_rf_tx); + pthread_join(proc->pthread_rf_tx, NULL); + pthread_mutex_destroy( &proc->mutex_rf_tx); + pthread_cond_destroy( &proc->cond_rf_tx); +#endif + if (get_nprocs() > 2 && fepw) { LOG_D(PHY, "killing FEP thread\n"); kill_fep_thread(ru); @@ -2271,8 +2296,10 @@ void kill_RU_proc(int inst) pthread_mutex_lock(&proc->mutex_eNBs); proc->ru_tx_ready = 0; - proc->instance_cnt_eNBs = 0; - pthread_cond_signal(&proc->cond_eNBs); + proc->instance_cnt_eNBs = 1; + // cond_eNBs is used by both ru_thread and ru_thread_tx, so we need to send + // a broadcast to wake up both threads + pthread_cond_broadcast(&proc->cond_eNBs); pthread_mutex_unlock(&proc->mutex_eNBs); pthread_mutex_lock(&proc->mutex_asynch_rxtx); @@ -2280,10 +2307,12 @@ void kill_RU_proc(int inst) pthread_cond_signal(&proc->cond_asynch_rxtx); pthread_mutex_unlock(&proc->mutex_asynch_rxtx); - /*LOG_D(PHY, "Joining pthread_FH\n"); + LOG_D(PHY, "Joining pthread_FH\n"); pthread_join(proc->pthread_FH, NULL); - LOG_D(PHY, "Joining pthread_FHTX\n"); - pthread_join(proc->pthread_FH1, NULL);*/ + if (!single_thread_flag && get_nprocs() > 4) { + LOG_D(PHY, "Joining pthread_FHTX\n"); + pthread_join(proc->pthread_FH1, NULL); + } if (ru->function == NGFI_RRU_IF4p5) { LOG_D(PHY, "Joining pthread_prach\n"); pthread_join(proc->pthread_prach, NULL); @@ -2755,45 +2784,11 @@ void init_RU(char *rf_config_file) { } - - - -void stop_ru(RU_t *ru) { - -#if defined(PRE_SCD_THREAD) || defined(PHY_TX_THREAD) - int *status; -#endif - printf("Stopping RU %p processing threads\n",(void*)ru); -#if defined(PRE_SCD_THREAD) - if(ru){ - ru->proc.instance_pre_scd = 0; - pthread_cond_signal( &ru->proc.cond_pre_scd ); - pthread_join(ru->proc.pthread_pre_scd, (void**)&status ); - pthread_mutex_destroy(&ru->proc.mutex_pre_scd ); - pthread_cond_destroy(&ru->proc.cond_pre_scd ); - } -#endif -#ifdef PHY_TX_THREAD - if(ru){ - ru->proc.instance_cnt_phy_tx = 0; - pthread_cond_signal(&ru->proc.cond_phy_tx); - pthread_join( ru->proc.pthread_phy_tx, (void**)&status ); - pthread_mutex_destroy( &ru->proc.mutex_phy_tx ); - pthread_cond_destroy( &ru->proc.cond_phy_tx ); - ru->proc.instance_cnt_rf_tx = 0; - pthread_cond_signal(&ru->proc.cond_rf_tx); - pthread_join( ru->proc.pthread_rf_tx, (void**)&status ); - pthread_mutex_destroy( &ru->proc.mutex_rf_tx ); - pthread_cond_destroy( &ru->proc.cond_rf_tx ); - } -#endif -} - void stop_RU(int nb_ru) { for (int inst = 0; inst < nb_ru; inst++) { LOG_I(PHY, "Stopping RU %d processing threads\n", inst); - kill_RU_proc(inst); + kill_RU_proc(RC.ru[inst]); } } diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 60b5a0b15f..25a55a6e56 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -793,10 +793,11 @@ int stop_L1L2(module_id_t enb_id) /* these tasks need to pick up new configuration */ terminate_task(enb_id, TASK_ENB_APP, TASK_RRC_ENB); terminate_task(enb_id, TASK_ENB_APP, TASK_L2L1); + oai_exit = 1; LOG_I(ENB_APP, "calling kill_eNB_proc() for instance %d\n", enb_id); kill_eNB_proc(enb_id); LOG_I(ENB_APP, "calling kill_RU_proc() for instance %d\n", enb_id); - kill_RU_proc(enb_id); + kill_RU_proc(RC.ru[enb_id]); oai_exit = 0; for (int cc_id = 0; cc_id < RC.nb_CC[enb_id]; cc_id++) { free_transport(RC.eNB[enb_id][cc_id]); @@ -1241,25 +1242,20 @@ int main( int argc, char **argv ) printf("stopping MODEM threads\n"); - // cleanup - for (ru_id=0;ru_id<RC.nb_RU;ru_id++) { - stop_ru(RC.ru[ru_id]); - } - - stop_eNB(NB_eNB_INST); - stop_RU(RC.nb_RU); - /* release memory used by the RU/eNB threads (incomplete), after all - * threads have been stopped (they partially use the same memory) */ - for (int inst = 0; inst < NB_eNB_INST; inst++) { - for (int cc_id = 0; cc_id < RC.nb_CC[inst]; cc_id++) { - free_transport(RC.eNB[inst][cc_id]); - phy_free_lte_eNB(RC.eNB[inst][cc_id]); - } + stop_eNB(NB_eNB_INST); + stop_RU(RC.nb_RU); + /* release memory used by the RU/eNB threads (incomplete), after all + * threads have been stopped (they partially use the same memory) */ + for (int inst = 0; inst < NB_eNB_INST; inst++) { + for (int cc_id = 0; cc_id < RC.nb_CC[inst]; cc_id++) { + free_transport(RC.eNB[inst][cc_id]); + phy_free_lte_eNB(RC.eNB[inst][cc_id]); } - for (int inst = 0; inst < RC.nb_RU; inst++) { - phy_free_RU(RC.ru[inst]); - } - free_lte_top(); + } + for (int inst = 0; inst < RC.nb_RU; inst++) { + phy_free_RU(RC.ru[inst]); + } + free_lte_top(); printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); end_configmodule(); diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 2eb4b0d60d..3aec62ca0c 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -253,7 +253,7 @@ extern void init_RU(const char*); extern void stop_ru(RU_t *ru); extern void init_RU_proc(RU_t *ru); extern void stop_RU(int nb_ru); -extern void kill_RU_proc(int inst); +extern void kill_RU_proc(RU_t *ru); extern void set_function_spec_param(RU_t *ru); // In lte-ue.c -- GitLab