diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index 0a25dca3606fbd7bbd072c185618631f1937f41a..d20b614ad79d4332bc10915d270106bc67c3340b 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 60b5a0b15f3b36b415c6c2e14637ce332c69d461..25a55a6e56d2e6eb15bba9155af31f0901866e43 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 2eb4b0d60d4bbaade10d08a9e08c036b3e6a09ed..3aec62ca0c3f2ec57a0985fdfc24a10c32ac0844 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