Commit f0670154 authored by Robert Schmidt's avatar Robert Schmidt

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
parent 2e1dfb5b
......@@ -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]);
}
}
......
......@@ -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();
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment