From 7854133bc2f573d574b49c83a52341d2722f13fc Mon Sep 17 00:00:00 2001
From: Sakthivel Velumani <velumani@eurecom.fr>
Date: Wed, 10 Feb 2021 22:00:09 +0100
Subject: [PATCH] Removing some of the old pthreads Leaving ru_thread and L1
 stats thread

---
 executables/nr-gnb.c           | 700 +++------------------------------
 executables/nr-ru.c            | 642 ------------------------------
 executables/softmodem-common.h |   4 +
 openair1/PHY/defs_RU.h         |   6 +
 openair1/PHY/defs_gNB.h        |   9 +
 5 files changed, 71 insertions(+), 1290 deletions(-)

diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index c36db7b1ef..a23a8a4a5d 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -81,7 +81,7 @@
 
 #include "s1ap_eNB.h"
 #include "SIMULATION/ETH_TRANSPORT/proto.h"
-
+#include <executables/softmodem-common.h>
 
 #include "T.h"
 
@@ -111,30 +111,15 @@ time_stats_t softmodem_stats_rxtx_sf; // total tx time
 time_stats_t nfapi_meas; // total tx time
 time_stats_t softmodem_stats_rx_sf; // total rx time
 
-/* mutex, cond and variable to serialize phy proc TX calls
- * (this mechanism may be relaxed in the future for better
- * performances)
- */
-static struct {
-  pthread_mutex_t  mutex_phy_proc_tx;
-  pthread_cond_t   cond_phy_proc_tx;
-  volatile uint8_t phy_proc_CC_id;
-} sync_phy_proc;
-
 extern double cpuf;
 
 void init_gNB(int,int);
 void stop_gNB(int nb_inst);
 
-int wakeup_txfh(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, int frame_tx, int slot_tx, uint64_t timestamp_tx);
-int wakeup_tx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_tx, int slot_tx, uint64_t timestamp_tx);
 #include "executables/thread-common.h"
 //extern PARALLEL_CONF_t get_thread_parallel_conf(void);
 //extern WORKER_CONF_t   get_thread_worker_conf(void);
 
-
-void wakeup_prach_gNB(PHY_VARS_gNB *gNB, RU_t *ru, int frame, int subframe);
-
 extern uint8_t nfapi_mode;
 extern void oai_subframe_ind(uint16_t sfn, uint16_t sf);
 extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset);
@@ -142,41 +127,42 @@ extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset);
 //#define TICK_TO_US(ts) (ts.diff)
 #define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials)
 
-static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_tx, int slot_tx, char *thread_name) {
+extern void init_td_thread(PHY_VARS_gNB *);
+extern void init_te_thread(PHY_VARS_gNB *);
+
+void tx_func(void *param) {
+
+  processingData_L1_t *info = (processingData_L1_t *) param;
+  PHY_VARS_gNB *gNB = info->gNB;
+  int frame_tx = info->frame_tx;
+  int slot_tx = info->slot_tx;
+
+  phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
+
+  // start FH TX processing
+  notifiedFIFO_elt_t *res; 
+  res = pullTpool(gNB->resp_RU_tx, gNB->threadPool);
+  processingData_RU_t *syncMsg = (processingData_RU_t *)NotifiedFifoData(res);
+  syncMsg->frame_tx = frame_tx;
+  syncMsg->slot_tx = slot_tx;
+  syncMsg->timestamp_tx = info->timestamp_tx;
+  syncMsg->ru = gNB->RU_list[0];
+  res->key = slot_tx;
+  pushTpool(gNB->threadPool, res);
+}
+
+void rx_func(void *param) {
 
+  processingData_L1_t *info = (processingData_L1_t *) param;
+  PHY_VARS_gNB *gNB = info->gNB;
+  int frame_rx = info->frame_rx;
+  int slot_rx = info->slot_rx;
+  int frame_tx = info->frame_tx;
+  int slot_tx = info->slot_tx;
   sl_ahead = sf_ahead*gNB->frame_parms.slots_per_subframe;
   nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
 
-  start_meas(&softmodem_stats_rxtx_sf);
-
-  // *******************************************************************
-  // NFAPI not yet supported for NR - this code has to be revised
-  if (nfapi_mode == 1) {
-    // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick
-    //add_subframe(&frame, &subframe, 4);
-    //oai_subframe_ind(proc->frame_tx, proc->subframe_tx);
-    //LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe);
-    start_meas(&nfapi_meas);
-    oai_subframe_ind(frame_rx, slot_rx);
-    stop_meas(&nfapi_meas);
-
-    /*if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
-        gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs ||
-        gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs ||
-        gNB->UL_INFO.rach_ind.number_of_pdus ||
-        gNB->UL_INFO.cqi_ind.number_of_cqis
-       ) {
-      LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d rach_pdus:%0d.%d:%d cqis:%d] RX:%04d%d TX:%04d%d \n",
-            NFAPI_SFNSF2DEC(gNB->UL_INFO.rx_ind.sfn_sf),   gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus,
-            NFAPI_SFNSF2DEC(gNB->UL_INFO.harq_ind.sfn_sf), gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs,
-            NFAPI_SFNSF2DEC(gNB->UL_INFO.crc_ind.sfn_sf),  gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs,
-            gNB->UL_INFO.rach_ind.sfn, gNB->UL_INFO.rach_ind.slot,gNB->UL_INFO.rach_ind.number_of_pdus,
-            gNB->UL_INFO.cqi_ind.number_of_cqis,
-            frame_rx, slot_rx,
-            frame_tx, slot_tx);
-    }*/
-  }
-  // ****************************************
+  //start_meas(&softmodem_stats_rxtx_sf);
 
   T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx));
 
@@ -233,12 +219,6 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
   rnti_to_remove_count = 0;
   if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1);
 
-  /*
-  // if this is IF5 or 3GPP_gNB
-  if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
-    wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx);
-  }
-  */
   // Call the scheduler
 
   pthread_mutex_lock(&gNB->UL_INFO_mutex);
@@ -273,21 +253,24 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
 
   if (oai_exit) return(-1);
 
-  // *****************************************
-  // TX processing for subframe n+sf_ahead
-  // run PHY TX procedures the one after the other for all CCs to avoid race conditions
-  // (may be relaxed in the future for performance reasons)
-  // *****************************************
+  //stop_meas( &softmodem_stats_rxtx_sf );
+  LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx);
 
-  if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) {
+  notifiedFIFO_elt_t *res; 
 
-    if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) {
-      phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
-    }
+  if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) {
+    res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
+    processingData_L1_t *syncMsg = (processingData_L1_t *)NotifiedFifoData(res);
+    syncMsg->gNB = gNB;
+    syncMsg->frame_rx = frame_rx;
+    syncMsg->slot_rx = slot_rx;
+    syncMsg->frame_tx = frame_tx;
+    syncMsg->slot_tx = slot_tx;
+    syncMsg->timestamp_tx = info->timestamp_tx;
+    res->key = slot_tx;
+    pushTpool(gNB->threadPool, res);
   }
-
-  stop_meas( &softmodem_stats_rxtx_sf );
-  LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx);
+    
 #if 0
   LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ",
         softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now,
@@ -327,466 +310,7 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
         TICK_TO_US(gNB->ulsch_tc_intl2_stats)
        );
 #endif
-  return(0);
-}
-
-static void *gNB_L1_thread_tx(void *param) {
-  PHY_VARS_gNB *gNB        = (PHY_VARS_gNB *)param;
-  gNB_L1_proc_t *gNB_proc  = &gNB->proc;
-  gNB_L1_rxtx_proc_t *L1_proc_tx = &gNB_proc->L1_proc_tx;
-  //PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id];
-  char thread_name[100];
-
-  sprintf(thread_name,"gNB_L1_thread_tx\n");
-
-  while (!oai_exit) {
-    if (wait_on_condition(&L1_proc_tx->mutex,&L1_proc_tx->cond,&L1_proc_tx->instance_cnt,thread_name)<0) break;
-
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 1 );
-
-    if (oai_exit) break;
-
-    // *****************************************
-    // TX processing for subframe n+4
-    // run PHY TX procedures the one after the other for all CCs to avoid race conditions
-    // (may be relaxed in the future for performance reasons)
-    // *****************************************
-    int      frame_tx = L1_proc_tx->frame_tx;
-    int      slot_tx = L1_proc_tx->slot_tx;
-    uint64_t timestamp_tx = L1_proc_tx->timestamp_tx;
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,slot_tx);
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB,frame_tx);
-    phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
-
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, 1 );
-    pthread_mutex_lock( &L1_proc_tx->mutex );
-    L1_proc_tx->instance_cnt = -1;
-
-    // the thread can now be woken up
-    if (pthread_cond_signal(&L1_proc_tx->cond) != 0) {
-      LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n");
-      exit_fun( "ERROR pthread_cond_signal" );
-    }
-    pthread_mutex_unlock(&L1_proc_tx->mutex);
-
-    wakeup_txfh(gNB,L1_proc_tx,frame_tx,slot_tx,timestamp_tx);
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, 0 );
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 );
-  }
-
-  return 0;
-}
-
-/*!
- * \brief The RX UE-specific and TX thread of gNB.
- * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process.
- * \returns a pointer to an int. The storage is not on the heap and must not be freed.
- */
-
-static void *gNB_L1_thread( void *param ) {
-  static int gNB_thread_rxtx_status;
-  PHY_VARS_gNB *gNB        = (PHY_VARS_gNB *)param;
-  gNB_L1_proc_t *gNB_proc  = &gNB->proc;
-  gNB_L1_rxtx_proc_t *L1_proc = &gNB_proc->L1_proc;
-  //PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id];
-  char thread_name[100];
-  // set default return value
-  // set default return value
-  gNB_thread_rxtx_status = 0;
-
-  sprintf(thread_name,"gNB_L1_thread");
-
-
-  while (!oai_exit) {
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 0 );
-    if (wait_on_condition(&L1_proc->mutex,&L1_proc->cond,&L1_proc->instance_cnt,thread_name)<0) break;
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 1 );
-
-    int frame_rx          = L1_proc->frame_rx;
-    int slot_rx           = L1_proc->slot_rx;
-    int frame_tx          = L1_proc->frame_tx;
-    int slot_tx           = L1_proc->slot_tx;
-    uint64_t timestamp_tx = L1_proc->timestamp_tx;
-
-
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX0_GNB,slot_tx);
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB,slot_rx);
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_GNB,frame_tx);
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_GNB,frame_rx);
-
-    if (oai_exit) break;
-
-    if (gNB->CC_id==0) {
-      if (rxtx(gNB,frame_rx,slot_rx,frame_tx,slot_tx,thread_name) < 0) break;
-    }
-
-    if (release_thread(&L1_proc->mutex,&L1_proc->instance_cnt,thread_name)<0) break;
-
-    if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)  wakeup_tx(gNB,frame_rx,slot_rx,frame_tx,slot_tx,timestamp_tx);
-    else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) wakeup_txfh(gNB,L1_proc,frame_tx,slot_tx,timestamp_tx);
-  } // while !oai_exit
-
-  LOG_D(PHY, " *** Exiting gNB thread RXn_TXnp4\n");
-  gNB_thread_rxtx_status = 0;
-  return &gNB_thread_rxtx_status;
-}
-
-
-#if 0 
-// Wait for gNB application initialization to be complete (gNB registration to MME)
-static void wait_system_ready (char *message, volatile int *start_flag) {
-  static char *indicator[] = {".    ", "..   ", "...  ", ".... ", ".....",
-                              " ....", "  ...", "   ..", "    .", "     "
-                             };
-  int i = 0;
-
-  while ((!oai_exit) && (*start_flag == 0)) {
-    LOG_N(EMU, message, indicator[i]);
-    fflush(stdout);
-    i = (i + 1) % (sizeof(indicator) / sizeof(indicator[0]));
-    usleep(200000);
-  }
-
-  LOG_D(EMU,"\n");
-}
-#endif
-
-
-
-
-
-void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, char *string, struct RU_t_s *ru) {
-  gNB_L1_proc_t *proc           = &gNB->proc;
-  gNB_L1_rxtx_proc_t *L1_proc = &proc->L1_proc;
-  NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
-  RU_proc_t *ru_proc=&ru->proc;
-  proc->frame_rx    = frame_rx;
-  proc->slot_rx = slot_rx;
-  sl_ahead = sf_ahead*fp->slots_per_subframe;
-
-  if (!oai_exit) {
-    T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->slot_rx));
-    L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe);
-    L1_proc->frame_rx     = ru_proc->frame_rx;
-    L1_proc->slot_rx      = ru_proc->tti_rx;
-    L1_proc->frame_tx     = (L1_proc->slot_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
-    L1_proc->slot_tx      = (L1_proc->slot_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame;
-
-    if (rxtx(gNB,L1_proc->frame_rx,L1_proc->slot_rx,L1_proc->frame_tx,L1_proc->slot_tx,string) < 0) LOG_E(PHY,"gNB %d CC_id %d failed during execution\n",gNB->Mod_id,gNB->CC_id);
-
-    ru_proc->timestamp_tx = L1_proc->timestamp_tx;
-    ru_proc->tti_tx       = L1_proc->slot_tx;
-    ru_proc->frame_tx     = L1_proc->frame_tx;
-  }
-}
-
-int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot_tx,uint64_t timestamp_tx) {
-
-  RU_t *ru;
-  RU_proc_t *ru_proc;
-
-  int waitret = 0, ret = 0, time_ns = 1000*1000;
-  struct timespec now, abstime;
-  // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time
-  // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,1);
-  time_ns = time_ns/gNB->frame_parms.slots_per_subframe;
-  AssertFatal((ret = pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret);
-  while (proc->instance_cnt_RUs < 0) {
-    clock_gettime(CLOCK_REALTIME, &now);
-    abstime.tv_sec = now.tv_sec;
-    abstime.tv_nsec = now.tv_nsec + time_ns;
-
-    if (abstime.tv_nsec >= 1000*1000*1000) {
-      abstime.tv_nsec -= 1000*1000*1000;
-      abstime.tv_sec  += 1;
-    }
-    if((waitret = pthread_cond_timedwait(&proc->cond_RUs,&proc->mutex_RUs_tx,&abstime)) == 0) break; // this unlocks mutex_rxtx while waiting and then locks it again
-  }
-  proc->instance_cnt_RUs = -1;
-  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs);
-  AssertFatal((ret = pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret);
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,0);
-
-  if (waitret == ETIMEDOUT) {
-    LOG_W(PHY,"Dropping TX slot (%d.%d) because FH is blocked more than 1 slot times (500us)\n",frame_tx,slot_tx);
-
-    AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret);
-    gNB->proc.RU_mask_tx = 0;
-    AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret);
-    AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret);
-    proc->instance_cnt_RUs = 0;
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs);
-    AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret);
-
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,1);
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,0);
-
-    return(-1);
-  }
-
-  for(int i=0; i<gNB->num_RU; i++)
-  {
-    ru      = gNB->RU_list[i];
-    ru_proc = &ru->proc;
-
-
-    if (ru_proc->instance_cnt_gNBs == 0) {
-      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 1);
-      LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->tti_tx, proc->frame_rx, proc->slot_rx);
-      AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret);
-      gNB->proc.RU_mask_tx = 0;
-      AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret);
-
-      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 0);
-      return(-1);
-    }
-    AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret);
-
-    ru_proc->instance_cnt_gNBs = 0;
-    ru_proc->timestamp_tx = timestamp_tx;
-    ru_proc->tti_tx       = slot_tx;
-    ru_proc->frame_tx     = frame_tx;
-
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, ru_proc->instance_cnt_gNBs);
-
-    LOG_D(PHY,"Signaling tx_thread_fh for %d.%d\n",frame_tx,slot_tx);
-    // the thread can now be woken up
-    AssertFatal(pthread_cond_signal(&ru_proc->cond_gNBs) == 0,
-                "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n");
-    AssertFatal((ret=pthread_mutex_unlock(&ru_proc->mutex_gNBs))==0,"mutex_unlock returned %d\n",ret);
-
-  }
-  return(0);
-}
-
-int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_tx,uint64_t timestamp_tx) {
-
-
-  gNB_L1_rxtx_proc_t *L1_proc_tx = &gNB->proc.L1_proc_tx;
-
-  int ret;
- 
-  
-  AssertFatal((ret = pthread_mutex_lock(&L1_proc_tx->mutex))==0,"mutex_lock returns %d\n",ret);
-
-
-  while(L1_proc_tx->instance_cnt == 0) {
-    pthread_cond_wait(&L1_proc_tx->cond,&L1_proc_tx->mutex);
-  }
-
-  L1_proc_tx->instance_cnt = 0;
-
-  
-  L1_proc_tx->slot_rx       = slot_rx;
-  L1_proc_tx->frame_rx      = frame_rx;
-  L1_proc_tx->slot_tx       = slot_tx;
-  L1_proc_tx->frame_tx      = frame_tx;
-  L1_proc_tx->timestamp_tx  = timestamp_tx;
-
- 
-  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,1);
-  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,0);
-  // the thread can now be woken up
-  // the thread can now be woken up
-  AssertFatal(pthread_cond_signal(&L1_proc_tx->cond) == 0, "ERROR pthread_cond_signal for gNB L1 thread\n");
-  
-  AssertFatal((ret=pthread_mutex_unlock(&L1_proc_tx->mutex))==0,"mutex_unlock returns %d\n",ret);
-
-  return(0);
-}
-
-int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
-  gNB_L1_proc_t *proc=&gNB->proc;
-  gNB_L1_rxtx_proc_t *L1_proc=&proc->L1_proc;
-  NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
-  RU_proc_t *ru_proc=&ru->proc;
-  int ret;
-  int i;
-  struct timespec abstime;
-  int time_ns = 50000;
-  int wait_timer = 0;
-  bool do_last_check = 1;
-  
-  AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU))==0,"mutex_lock returns %d\n",ret);
-  for (i=0; i<gNB->num_RU; i++) {
-    if (ru == gNB->RU_list[i]) {
-      if ((proc->RU_mask&(1<<i)) > 0)
-        LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n",
-              gNB->Mod_id,proc->frame_rx,proc->slot_rx,ru->idx,gNB->num_RU,proc->RU_mask);
-      proc->RU_mask |= (1<<i);
-    }
-  }
-  if (proc->RU_mask != (1<<gNB->num_RU)-1) {  // not all RUs have provided their information so return
-    LOG_E(PHY,"Not all RUs have provided their info\n");
-    AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"mutex_unlock returns %d\n",ret);
-    return(0);
-  }
-  else { // all RUs have provided their information so continue on and wakeup gNB processing
-    proc->RU_mask = 0;
-    AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"muex_unlock returns %d\n",ret);
-  }
-
-  // wake up TX for subframe n+sf_ahead
-  // lock the TX mutex and make sure the thread is ready
-  while (wait_timer < 200) {
-    clock_gettime(CLOCK_REALTIME, &abstime);
-    abstime.tv_nsec = abstime.tv_nsec + time_ns;
-
-    if (abstime.tv_nsec >= 1000*1000*1000) {
-      abstime.tv_nsec -= 1000*1000*1000;
-      abstime.tv_sec  += 1;
-    }
-
-    AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret);
-
-    if (L1_proc->instance_cnt == 0) { // L1_thread is busy so wait for a bit
-      AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret);
-      wait_timer += 50;
-      usleep(50);
-    }
-    else {
-      do_last_check = 0;
-      break;
-    }
-  }
-  if (do_last_check) {
-    AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret);
-    if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe
-      AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret);
-      LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx);
-      return (-1);
-    }
-  }
-
-  ++L1_proc->instance_cnt;
-  // We have just received and processed the common part of a subframe, say n.
-  // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
-  // transmitted timestamp of the next TX slot (first).
-
-  // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, 
-  // we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti,
-  // and proc->slot_tx = proc->slot_rx+sf_ahead
-  L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe);
-  L1_proc->frame_rx     = ru_proc->frame_rx;
-  L1_proc->slot_rx  = ru_proc->tti_rx;
-  L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
-  L1_proc->slot_tx  = (L1_proc->slot_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame;
-
-  LOG_D(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sf_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sf_ahead);
-
-  pthread_mutex_unlock( &L1_proc->mutex );
-
-  // the thread can now be woken up
-  if (pthread_cond_signal(&L1_proc->cond) != 0) {
-    LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB RXn-TXnp4 thread\n");
-    exit_fun( "ERROR pthread_cond_signal" );
-    return(-1);
-  }
-
-  return(0);
-}
-/*
-void wakeup_prach_gNB(PHY_VARS_gNB *gNB,RU_t *ru,int frame,int subframe) {
-
-  gNB_L1_proc_t *proc = &gNB->proc;
-  LTE_DL_FRAME_PARMS *fp=&gNB->frame_parms;
-  int i;
-
-  if (ru!=NULL) {
-    pthread_mutex_lock(&proc->mutex_RU_PRACH);
-    for (i=0;i<gNB->num_RU;i++) {
-      if (ru == gNB->RU_list[i]) {
-  LOG_D(PHY,"frame %d, subframe %d: RU %d for gNB %d signals PRACH (mask %x, num_RU %d)\n",frame,subframe,i,gNB->Mod_id,proc->RU_mask_prach,gNB->num_RU);
-  if ((proc->RU_mask_prach&(1<<i)) > 0)
-    LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information (PRACH) from RU %d (num_RU %d, mask %x) has not been served yet!\n",
-    gNB->Mod_id,frame,subframe,ru->idx,gNB->num_RU,proc->RU_mask_prach);
-  proc->RU_mask_prach |= (1<<i);
-      }
-    }
-    if (proc->RU_mask_prach != (1<<gNB->num_RU)-1) {  // not all RUs have provided their information so return
-      pthread_mutex_unlock(&proc->mutex_RU_PRACH);
-      return;
-    }
-    else { // all RUs have provided their information so continue on and wakeup gNB processing
-      proc->RU_mask_prach = 0;
-      pthread_mutex_unlock(&proc->mutex_RU_PRACH);
-    }
-  }
-
-  // check if we have to detect PRACH first
-  if (is_prach_subframe(fp,frame,subframe)>0) {
-    LOG_D(PHY,"Triggering prach processing, frame %d, subframe %d\n",frame,subframe);
-    if (proc->instance_cnt_prach == 0) {
-      LOG_W(PHY,"[gNB] Frame %d Subframe %d, dropping PRACH\n", frame,subframe);
-      return;
-    }
-
-    // wake up thread for PRACH RX
-    if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
-      LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB PRACH thread %d (IC %d)\n", proc->thread_index, proc->instance_cnt_prach);
-      exit_fun( "error locking mutex_prach" );
-      return;
-    }
-
-    ++proc->instance_cnt_prach;
-    // set timing for prach thread
-    proc->frame_prach = frame;
-    proc->subframe_prach = subframe;
-
-    // the thread can now be woken up
-    if (pthread_cond_signal(&proc->cond_prach) != 0) {
-      LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB PRACH thread %d\n", proc->thread_index);
-      exit_fun( "ERROR pthread_cond_signal" );
-      return;
-    }
-
-    pthread_mutex_unlock( &proc->mutex_prach );
-  }
-
-}*/
-
-/*!
- * \brief The prach receive thread of gNB.
- * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process.
- * \returns a pointer to an int. The storage is not on the heap and must not be freed.
- */
-/*
-static void* gNB_thread_prach( void* param ) {
- static int gNB_thread_prach_status;
-
-
- PHY_VARS_gNB *gNB= (PHY_VARS_gNB *)param;
- gNB_L1_proc_t *proc = &gNB->proc;
-
- // set default return value
- gNB_thread_prach_status = 0;
-
-
-
- while (!oai_exit) {
-
-   if (oai_exit) break;
-
-
-   if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"gNB_prach_thread") < 0) break;
-
-   LOG_D(PHY,"Running gNB prach procedures\n");
-   prach_procedures(gNB ,0);
-
-   if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"gNB_prach_thread") < 0) break;
- }
-
- LOG_I(PHY, "Exiting gNB thread PRACH\n");
-
- gNB_thread_prach_status = 0;
- return &gNB_thread_prach_status;
 }
-*/
-
-extern void init_td_thread(PHY_VARS_gNB *);
-extern void init_te_thread(PHY_VARS_gNB *);
-
 static void *process_stats_thread(void *param) {
 
   PHY_VARS_gNB *gNB  = (PHY_VARS_gNB *)param;
@@ -807,90 +331,10 @@ static void *process_stats_thread(void *param) {
   return(NULL);
 }
 
-
-void init_gNB_proc(int inst) {
-  int i=0;
-  int CC_id = 0;
-  PHY_VARS_gNB *gNB;
-  gNB_L1_proc_t *proc;
-  gNB_L1_rxtx_proc_t *L1_proc,*L1_proc_tx;
-//  LOG_I(PHY,"%s(inst:%d) RC.nb_nr_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_nr_CC[inst]);
-  gNB = RC.gNB[inst];
-  LOG_I(PHY,"Initializing gNB processes instance:%d CC_id %d \n",inst,CC_id);
-  
-  proc = &gNB->proc;
-  L1_proc                        = &proc->L1_proc;
-  L1_proc_tx                     = &proc->L1_proc_tx;
-  L1_proc->instance_cnt          = -1;
-  L1_proc_tx->instance_cnt       = -1;
-  L1_proc->instance_cnt_RUs      = 0;
-  L1_proc_tx->instance_cnt_RUs   = 0;
-  proc->instance_cnt_prach       = -1;
-  proc->instance_cnt_asynch_rxtx = -1;
-  proc->CC_id                    = CC_id;
-  proc->first_rx                 =1;
-  proc->first_tx                 =1;
-  proc->RU_mask                  =0;
-  proc->RU_mask_tx               = (1<<gNB->num_RU)-1;
-  proc->RU_mask_prach            =0;
-  pthread_mutex_init( &gNB->UL_INFO_mutex, NULL);
-  pthread_mutex_init( &L1_proc->mutex, NULL);
-  pthread_mutex_init( &L1_proc_tx->mutex, NULL);
-  pthread_cond_init( &L1_proc->cond, NULL);
-  pthread_cond_init( &L1_proc_tx->cond, NULL);
-  pthread_mutex_init( &proc->mutex_prach, NULL);
-  pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
-  pthread_mutex_init( &proc->mutex_RU,NULL);
-  pthread_mutex_init( &proc->mutex_RU_tx,NULL);
-  pthread_mutex_init( &proc->mutex_RU_PRACH,NULL);
-  pthread_cond_init( &proc->cond_prach, NULL);
-  pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
-  LOG_I(PHY,"gNB->single_thread_flag:%d\n", gNB->single_thread_flag);
-  
-  if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
-    threadCreate( &L1_proc->pthread, gNB_L1_thread, gNB, "L1_proc", -1, OAI_PRIORITY_RT );
-    threadCreate( &L1_proc_tx->pthread, gNB_L1_thread_tx, gNB,"L1_proc_tx", -1, OAI_PRIORITY_RT);
-  }
-  
-  if(opp_enabled == 1) threadCreate(&proc->L1_stats_thread, process_stats_thread,(void *)gNB, "time_meas", -1, OAI_PRIORITY_RT_LOW);
-  //pthread_create( &proc->pthread_prach, attr_prach, gNB_thread_prach, gNB );
-  char name[16];
-  
-  if (gNB->single_thread_flag==0) {
-    snprintf( name, sizeof(name), "L1 %d", i );
-    pthread_setname_np( L1_proc->pthread, name );
-    snprintf( name, sizeof(name), "L1TX %d", i );
-    pthread_setname_np( L1_proc_tx->pthread, name );
-  }
-  
-  AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach);
-
-  /* setup PHY proc TX sync mechanism */
-  pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL);
-  pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL);
-  sync_phy_proc.phy_proc_CC_id = 0;
-
-  gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
-  gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
-  int numCPU = sysconf(_SC_NPROCESSORS_ONLN);
-  uint32_t num_threads_pusch;
-  paramdef_t PUSCHThreads[] = NUM_THREADS_DESC;
-  config_get( PUSCHThreads,sizeof(PUSCHThreads)/sizeof(paramdef_t),NULL);
-  int threadCnt = min(numCPU, num_threads_pusch);
-  char ul_pool[80];
-  sprintf(ul_pool,"-1");
-  int s_offset = 0;
-  for (int icpu=1; icpu<threadCnt; icpu++) {
-    sprintf(ul_pool+2+s_offset,",-1");
-    s_offset += 3;
-  }
-  initTpool(ul_pool, gNB->threadPool, false);
-  initNotifiedFIFO(gNB->respDecode);
-}
-
 void init_gNB_Tpool(int inst) {
   PHY_VARS_gNB *gNB;
   gNB = RC.gNB[inst];
+  gNB_L1_proc_t *proc = &gNB->proc;
 
   // ULSCH decoding threadpool
   gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
@@ -922,6 +366,9 @@ void init_gNB_Tpool(int inst) {
   // RU TX result FIFO 
   gNB->resp_RU_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
   initNotifiedFIFO(gNB->resp_RU_tx);
+
+  // Stats measurement thread
+  if(opp_enabled == 1) threadCreate(&proc->L1_stats_thread, process_stats_thread,(void *)gNB, "time_meas", -1, OAI_PRIORITY_RT_LOW);
 }
 
 
@@ -929,56 +376,13 @@ void init_gNB_Tpool(int inst) {
  * \brief Terminate gNB TX and RX threads.
  */
 void kill_gNB_proc(int inst) {
-  int *status;
   PHY_VARS_gNB *gNB;
-  gNB_L1_proc_t *proc;
-  gNB_L1_rxtx_proc_t *L1_proc, *L1_proc_tx;
 
   gNB=RC.gNB[inst];
-  proc = &gNB->proc;
-  L1_proc     = &proc->L1_proc;
-  L1_proc_tx  = &proc->L1_proc_tx;
-  LOG_I(PHY, "Killing TX inst %d\n",inst );
   
-  if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
-    pthread_mutex_lock(&L1_proc->mutex);
-    L1_proc->instance_cnt = 0;
-    pthread_cond_signal(&L1_proc->cond);
-    pthread_mutex_unlock(&L1_proc->mutex);
-    pthread_mutex_lock(&L1_proc_tx->mutex);
-    L1_proc_tx->instance_cnt = 0;
-    pthread_cond_signal(&L1_proc_tx->cond);
-    pthread_mutex_unlock(&L1_proc_tx->mutex);
-  }
-  
-  proc->instance_cnt_prach = 0;
-  pthread_cond_signal( &proc->cond_prach );
-  pthread_cond_signal( &proc->cond_asynch_rxtx );
-  pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
-  //    LOG_D(PHY, "joining pthread_prach\n");
-  //    pthread_join( proc->pthread_prach, (void**)&status );
-  LOG_I(PHY, "Destroying prach mutex/cond\n");
-  pthread_mutex_destroy( &proc->mutex_prach );
-  pthread_cond_destroy( &proc->cond_prach );
   LOG_I(PHY, "Destroying UL_INFO mutex\n");
   pthread_mutex_destroy(&gNB->UL_INFO_mutex);
   
-  if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
-    LOG_I(PHY, "Joining L1_proc mutex/cond\n");
-    pthread_join( L1_proc->pthread, (void **)&status );
-    LOG_I(PHY, "Joining L1_proc_tx mutex/cond\n");
-    pthread_join( L1_proc_tx->pthread, (void **)&status );
-  }
-  
-  LOG_I(PHY, "Destroying L1_proc mutex/cond\n");
-  pthread_mutex_destroy( &L1_proc->mutex );
-  pthread_cond_destroy( &L1_proc->cond );
-  LOG_I(PHY, "Destroying L1_proc_tx mutex/cond\n");
-  pthread_mutex_destroy( &L1_proc_tx->mutex );
-  pthread_cond_destroy( &L1_proc_tx->cond );
-  pthread_mutex_destroy( &proc->mutex_RU );
-  pthread_mutex_destroy( &proc->mutex_RU_tx );
-  
 }
 
 
diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index dec62469da..9fd83bab76 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -120,22 +120,6 @@ extern int emulate_rf;
 extern int numerology;
 extern int usrp_tx_thread;
 
-typedef struct processingData_L1 {
-  int frame_rx;
-  int frame_tx;
-  int slot_rx;
-  int slot_tx;
-  openair0_timestamp timestamp_tx;
-  PHY_VARS_gNB *gNB;
-} processingData_L1_t;
-
-typedef struct processingData_RU {
-  int frame_tx;
-  int slot_tx;
-  openair0_timestamp timestamp_tx;
-  RU_t *ru;
-} processingData_RU_t;
-
 /*************************************************************/
 /* Functions to attach and configure RRU                     */
 
@@ -805,101 +789,6 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
 
 
 
-/*!
- * \brief The Asynchronous RX/TX FH thread of RAU/RCC/gNB/RRU.
- * This handles the RX FH for an asynchronous RRU/UE
- * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process.
- * \returns a pointer to an int. The storage is not on the heap and must not be freed.
- */
-void *ru_thread_asynch_rxtx( void *param ) {
-  static int ru_thread_asynch_rxtx_status;
-  RU_t *ru         = (RU_t *)param;
-  RU_proc_t *proc  = &ru->proc;
-  nfapi_nr_config_request_scf_t *cfg = &ru->config;
-  int slot=0, frame=0;
-  // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe
-  wait_sync("ru_thread_asynch_rxtx");
-  // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe
-  printf( "waiting for devices (ru_thread_asynch_rx)\n");
-  wait_on_condition(&proc->mutex_asynch_rxtx,&proc->cond_asynch_rxtx,&proc->instance_cnt_asynch_rxtx,"thread_asynch");
-  printf( "devices ok (ru_thread_asynch_rx)\n");
-
-  while (!oai_exit) {
-
-    if (slot==ru->nr_frame_parms->slots_per_frame) {
-      slot=0;
-      frame++;
-      frame&=1023;
-    } else {
-      slot++;
-    }
-
-    LOG_D(PHY,"ru_thread_asynch_rxtx: Waiting on incoming fronthaul\n");
-
-    // asynchronous receive from north (RRU IF4/IF5)
-    if (ru->fh_north_asynch_in) {
-      if ((nr_slot_select(cfg,frame,slot) & NR_DOWNLINK_SLOT)>0)
-        ru->fh_north_asynch_in(ru,&frame,&slot);
-    } else AssertFatal(1==0,"Unknown function in ru_thread_asynch_rxtx\n");
-  }
-
-  ru_thread_asynch_rxtx_status=0;
-  return(&ru_thread_asynch_rxtx_status);
-}
-
-
-
-
-/*!
- * \brief The prach receive thread of RU.
- * \param param is a \ref RU_proc_t structure which contains the info what to process.
- * \returns a pointer to an int. The storage is not on the heap and must not be freed.
- */
-void *ru_thread_prach( void *param ) {
-  static int ru_thread_prach_status;
-  RU_t *ru        = (RU_t *)param;
-  RU_proc_t *proc = (RU_proc_t *)&ru->proc;
-  // set default return value
-  ru_thread_prach_status = 0;
-
-  while (RC.ru_mask>0) {
-    usleep(1e6);
-    LOG_I(PHY,"%s() RACH waiting for RU to be configured\n", __FUNCTION__);
-  }
-
-  LOG_I(PHY,"%s() RU configured - RACH processing thread running\n", __FUNCTION__);
-
-  while (!oai_exit) {
-    
-
-    if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break;
-
-    /*VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 );
-
-    if (ru->gNB_list[0]){
-      prach_procedures(
-        ru->gNB_list[0],0
-        );
-    }
-    else {
-       rx_prach(NULL,
-            ru,
-          NULL,
-                NULL,
-                NULL,
-                proc->frame_prach,
-                0,0
-          );
-    }
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 );*/
-    if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break;
-  }
-
-  LOG_I(PHY, "Exiting RU thread PRACH\n");
-  ru_thread_prach_status = 0;
-  return &ru_thread_prach_status;
-}
-
 
 int wakeup_synch(RU_t *ru) {
   struct timespec wait;
@@ -999,63 +888,6 @@ void do_ru_synch(RU_t *ru) {
   ru->rfdevice.trx_set_freq_func(&ru->rfdevice,ru->rfdevice.openair0_cfg,0);
 }
 
-
-
-void wakeup_gNB_L1s(RU_t *ru) {
-  int i;
-  PHY_VARS_gNB **gNB_list = ru->gNB_list;
-  LOG_D(PHY,"wakeup_gNB_L1s (num %d) for RU %d ru->gNB_top:%p\n",ru->num_gNB,ru->idx, ru->gNB_top);
-
-  if (ru->num_gNB==1 && ru->gNB_top!=0 && get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) {
-    // call gNB function directly
-    char string[20];
-    sprintf(string,"Incoming RU %u",ru->idx);
-    LOG_D(PHY,"RU %d Call gNB_top\n",ru->idx);
-    ru->gNB_top(gNB_list[0],ru->proc.frame_rx,ru->proc.tti_rx,string,ru);
-  } else {
-    LOG_D(PHY,"ru->num_gNB:%d\n", ru->num_gNB);
-
-    for (i=0; i<ru->num_gNB; i++) {
-      LOG_D(PHY,"ru->wakeup_rxtx:%p\n", ru->nr_wakeup_rxtx);
-
-      if (ru->nr_wakeup_rxtx!=0 && ru->nr_wakeup_rxtx(gNB_list[i],ru) < 0) {
-        LOG_E(PHY,"could not wakeup gNB rxtx process for subframe %d\n", ru->proc.tti_rx);
-      }
-    }
-  }
-}
-
-int wakeup_prach_ru(RU_t *ru) {
-  struct timespec wait;
-  wait.tv_sec=0;
-  wait.tv_nsec=5000000L;
-
-  if (pthread_mutex_timedlock(&ru->proc.mutex_prach,&wait) !=0) {
-    LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for RU prach thread (IC %d)\n", ru->proc.instance_cnt_prach);
-    exit_fun( "error locking mutex_rxtx" );
-    return(-1);
-  }
-
-  if (ru->proc.instance_cnt_prach==-1) {
-    ++ru->proc.instance_cnt_prach;
-    ru->proc.frame_prach    = ru->proc.frame_rx;
-    ru->proc.subframe_prach = ru->proc.tti_rx;
-
-    // DJP - think prach_procedures() is looking at gNB frame_prach
-    if (ru->gNB_list[0]) {
-      ru->gNB_list[0]->proc.frame_prach = ru->proc.frame_rx;
-      ru->gNB_list[0]->proc.slot_prach = ru->proc.tti_rx;
-    }
-
-    LOG_I(PHY,"RU %d: waking up PRACH thread\n",ru->idx);
-    // the thread can now be woken up
-    AssertFatal(pthread_cond_signal(&ru->proc.cond_prach) == 0, "ERROR pthread_cond_signal for RU prach thread\n");
-  } else LOG_W(PHY,"RU prach thread busy, skipping\n");
-
-  pthread_mutex_unlock( &ru->proc.mutex_prach );
-  return(0);
-}
-
 // this is for RU with local RF unit
 void fill_rf_config(RU_t *ru, char *rf_config_file) {
   int i;
@@ -1371,320 +1203,6 @@ void ru_tx_func(void *param) {
   }//else  emulate_rf
 }
 
-void *ru_thread_tx( void *param ) {
-  RU_t               *ru      = (RU_t *)param;
-  RU_proc_t          *proc    = &ru->proc;
-  NR_DL_FRAME_PARMS  *fp      = ru->nr_frame_parms;
-  PHY_VARS_gNB       *gNB;
-  gNB_L1_proc_t      *gNB_proc;
-  gNB_L1_rxtx_proc_t *L1_proc;
-  char               filename[40];
-  int                print_frame = 8;
-  int                i = 0;
-  int                ret;
-  
-
-  wait_on_condition(&proc->mutex_FH1,&proc->cond_FH1,&proc->instance_cnt_FH1,"ru_thread_tx");
-  printf( "ru_thread_tx ready\n");
-
-  while (!oai_exit) {
-
-    LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n");
-    // wait until eNBs are finished subframe RX n and TX n+4
-
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RU_TX_WAIT, 1 );
-    wait_on_condition(&proc->mutex_gNBs,&proc->cond_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx");
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RU_TX_WAIT, 0 );
-
-    ret = pthread_mutex_lock(&proc->mutex_gNBs);
-    AssertFatal(ret == 0,"mutex_lock return %d\n",ret);
-    int frame_tx=proc->frame_tx;
-    int tti_tx  =proc->tti_tx;
-    uint64_t timestamp_tx = proc->timestamp_tx;
-
-    ret = pthread_mutex_unlock(&proc->mutex_gNBs);
-    AssertFatal(ret == 0,"mutex_lock returns %d\n",ret);
-
-    if (oai_exit) break;
-
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame_tx );
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, tti_tx );
-
-    // do TX front-end processing if needed (precoding and/or IDFTs)
-    if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,tti_tx);
-
-    // do OFDM with/without TX front-end processing  if needed
-    if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,tti_tx);
-
-    if(!emulate_rf) {
-      // do outgoing fronthaul (south) if needed
-      if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,frame_tx,tti_tx,timestamp_tx);
-
-      if (ru->fh_north_out) ru->fh_north_out(ru);
-    } else {
-      if(proc->frame_tx == print_frame) {
-        for (i=0; i<ru->nb_tx; i++) {
-
-          if(proc->tti_tx == 0) {
-            sprintf(filename,"gNBdataF_frame%d_sl%d.m", print_frame, proc->tti_tx);
-            LOG_M(filename,"txdataF_frame",&ru->gNB_list[0]->common_vars.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1);
-
-            sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx);
-            LOG_M(filename,"txdataF_frame",&ru->common.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1);
-
-            sprintf(filename,"tx%ddataF_BF_frame%d_sl%d.m", i, print_frame, proc->tti_tx);
-            LOG_M(filename,"txdataF_BF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1);
-          }
-
-          if(proc->tti_tx == 9) {
-            sprintf(filename,"tx%ddata_frame%d.m", i, print_frame);
-            LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1);
-            sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame);
-            FILE *output_fd = fopen(filename,"w");
-
-            if (output_fd) {
-              fwrite(&ru->common.txdata[i][0],
-                     sizeof(int32_t),
-                     fp->samples_per_frame,
-                     output_fd);
-              fclose(output_fd);
-            } else {
-              LOG_E(PHY,"Cannot write to file %s\n",filename);
-            }
-          }//if(proc->tti_tx == 9)
-        }//for (i=0; i<ru->nb_tx; i++)
-      }//if(proc->frame_tx == print_frame)
-    }//else  emulate_rf
-
-    release_thread(&proc->mutex_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx");
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, proc->instance_cnt_gNBs);
-
-    for(i = 0; i<ru->num_gNB; i++) {
-      gNB       = ru->gNB_list[i];
-      gNB_proc  = &gNB->proc;
-      L1_proc   = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? &gNB_proc->L1_proc_tx : &gNB_proc->L1_proc;
-      ret = pthread_mutex_lock(&gNB_proc->mutex_RU_tx);
-      AssertFatal(ret == 0,"mutex_lock returns %d\n",ret);
-
-      for (int j=0; j<gNB->num_RU; j++) {
-        if (ru == gNB->RU_list[j]) {
-          if ((gNB_proc->RU_mask_tx&(1<<j)) > 0)
-            LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n",
-                  gNB->Mod_id,gNB_proc->frame_rx,gNB_proc->slot_rx,ru->idx,gNB->num_RU,gNB_proc->RU_mask_tx);
-
-          gNB_proc->RU_mask_tx |= (1<<j);
-        }
-      }
-
-      if (gNB_proc->RU_mask_tx != (1<<gNB->num_RU)-1) {  // not all RUs have provided their information so return
-        ret = pthread_mutex_unlock(&gNB_proc->mutex_RU_tx);
-        AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret);
-      } else { // all RUs TX are finished so send the ready signal to gNB processing
-        gNB_proc->RU_mask_tx = 0;
-        ret = pthread_mutex_unlock(&gNB_proc->mutex_RU_tx);
-        AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret);
-
-        ret = pthread_mutex_lock(&L1_proc->mutex_RUs_tx);
-        AssertFatal(ret == 0,"mutex_lock returns %d\n",ret);
-        // the thread can now be woken up
-        if (L1_proc->instance_cnt_RUs == -1) {
-          L1_proc->instance_cnt_RUs = 0;
-          VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs);
-          AssertFatal(pthread_cond_signal(&L1_proc->cond_RUs) == 0,
-                      "ERROR pthread_cond_signal for gNB_L1_thread\n");
-        } //else AssertFatal(1==0,"gNB TX thread is not ready\n");
-        ret = pthread_mutex_unlock(&L1_proc->mutex_RUs_tx);
-        AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret);
-      }
-    }
-  }
-
-  release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx");
-  return 0;
-}
-
-void tx_func(void *param) {
-
-  processingData_L1_t *info = (processingData_L1_t *) param;
-  PHY_VARS_gNB *gNB = info->gNB;
-  int frame_tx = info->frame_tx;
-  int slot_tx = info->slot_tx;
-
-  phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
-
-  // start FH TX processing
-  notifiedFIFO_elt_t *res; 
-  res = pullTpool(gNB->resp_RU_tx, gNB->threadPool);
-  processingData_RU_t *syncMsg = (processingData_RU_t *)NotifiedFifoData(res);
-  syncMsg->frame_tx = frame_tx;
-  syncMsg->slot_tx = slot_tx;
-  syncMsg->timestamp_tx = info->timestamp_tx;
-  syncMsg->ru = gNB->RU_list[0];
-  res->key = slot_tx;
-  pushTpool(gNB->threadPool, res);
-}
-
-void rx_func(void *param) {
-
-  processingData_L1_t *info = (processingData_L1_t *) param;
-  PHY_VARS_gNB *gNB = info->gNB;
-  int frame_rx = info->frame_rx;
-  int slot_rx = info->slot_rx;
-  int frame_tx = info->frame_tx;
-  int slot_tx = info->slot_tx;
-  sl_ahead = sf_ahead*gNB->frame_parms.slots_per_subframe;
-  nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
-
-  //start_meas(&softmodem_stats_rxtx_sf);
-
-  T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx));
-
-  /* hack to remove UEs */
-  extern int rnti_to_remove[10];
-  extern volatile int rnti_to_remove_count;
-  extern pthread_mutex_t rnti_to_remove_mutex;
-  if (pthread_mutex_lock(&rnti_to_remove_mutex)) exit(1);
-  int up_removed = 0;
-  int down_removed = 0;
-  int pucch_removed = 0;
-  for (int i = 0; i < rnti_to_remove_count; i++) {
-    LOG_W(PHY, "to remove rnti %d\n", rnti_to_remove[i]);
-    void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch);
-    void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch);
-    int j;
-    for (j = 0; j < NUMBER_OF_NR_ULSCH_MAX; j++)
-      if (gNB->ulsch[j][0]->rnti == rnti_to_remove[i]) {
-        gNB->ulsch[j][0]->rnti = 0;
-        gNB->ulsch[j][0]->harq_mask = 0;
-        //clean_gNB_ulsch(gNB->ulsch[j][0]);
-        int h;
-        for (h = 0; h < NR_MAX_ULSCH_HARQ_PROCESSES; h++) {
-          gNB->ulsch[j][0]->harq_processes[h]->status = SCH_IDLE;
-          gNB->ulsch[j][0]->harq_processes[h]->round  = 0;
-          gNB->ulsch[j][0]->harq_processes[h]->handled = 0;
-        }
-        up_removed++;
-      }
-    for (j = 0; j < NUMBER_OF_NR_DLSCH_MAX; j++)
-      if (gNB->dlsch[j][0]->rnti == rnti_to_remove[i]) {
-        gNB->dlsch[j][0]->rnti = 0;
-        gNB->dlsch[j][0]->harq_mask = 0;
-        //clean_gNB_dlsch(gNB->dlsch[j][0]);
-        down_removed++;
-      }
-    for (j = 0; j < NUMBER_OF_NR_PUCCH_MAX; j++)
-      if (gNB->pucch[j]->active > 0 &&
-          gNB->pucch[j]->pucch_pdu.rnti == rnti_to_remove[i]) {
-        gNB->pucch[j]->active = 0;
-        gNB->pucch[j]->pucch_pdu.rnti = 0;
-        pucch_removed++;
-      }
-#if 0
-    for (j = 0; j < NUMBER_OF_NR_PDCCH_MAX; j++)
-      gNB->pdcch_pdu[j].frame = -1;
-    for (j = 0; j < NUMBER_OF_NR_PDCCH_MAX; j++)
-      gNB->ul_pdcch_pdu[j].frame = -1;
-    for (j = 0; j < NUMBER_OF_NR_PRACH_MAX; j++)
-      gNB->prach_vars.list[j].frame = -1;
-#endif
-  }
-  if (rnti_to_remove_count) LOG_W(PHY, "to remove rnti_to_remove_count=%d, up_removed=%d down_removed=%d pucch_removed=%d\n", rnti_to_remove_count, up_removed, down_removed, pucch_removed);
-  rnti_to_remove_count = 0;
-  if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1);
-
-  // Call the scheduler
-
-  pthread_mutex_lock(&gNB->UL_INFO_mutex);
-  gNB->UL_INFO.frame     = frame_rx;
-  gNB->UL_INFO.slot      = slot_rx;
-  gNB->UL_INFO.module_id = gNB->Mod_id;
-  gNB->UL_INFO.CC_id     = gNB->CC_id;
-  gNB->if_inst->NR_UL_indication(&gNB->UL_INFO);
-  pthread_mutex_unlock(&gNB->UL_INFO_mutex);
-  
-  // RX processing
-  int tx_slot_type         = nr_slot_select(cfg,frame_tx,slot_tx);
-  int rx_slot_type         = nr_slot_select(cfg,frame_rx,slot_rx);
-
-  if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) {
-    // UE-specific RX processing for subframe n
-    // TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT
-
-    // Do PRACH RU processing
-    L1_nr_prach_procedures(gNB,frame_rx,slot_rx);
-
-    //apply the rx signal rotation here
-    apply_nr_rotation_ul(&gNB->frame_parms,
-			 gNB->common_vars.rxdataF[0],
-			 slot_rx,
-			 0,
-			 gNB->frame_parms.Ncp==EXTENDED?12:14,
-			 gNB->frame_parms.ofdm_symbol_size);
-    
-    phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
-  }
-
-  if (oai_exit) return(-1);
-
-  //stop_meas( &softmodem_stats_rxtx_sf );
-  LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx);
-
-  notifiedFIFO_elt_t *res; 
-
-  if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) {
-    res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
-    processingData_L1_t *syncMsg = (processingData_L1_t *)NotifiedFifoData(res);
-    syncMsg->gNB = gNB;
-    syncMsg->frame_rx = frame_rx;
-    syncMsg->slot_rx = slot_rx;
-    syncMsg->frame_tx = frame_tx;
-    syncMsg->slot_tx = slot_tx;
-    syncMsg->timestamp_tx = info->timestamp_tx;
-    res->key = slot_tx;
-    pushTpool(gNB->threadPool, res);
-  }
-    
-#if 0
-  LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ",
-        softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now,
-        TICK_TO_US(gNB->phy_proc),
-        TICK_TO_US(gNB->phy_proc_tx),
-        TICK_TO_US(gNB->phy_proc_rx),
-        TICK_TO_US(gNB->rx_prach),
-        TICK_TO_US(gNB->ofdm_mod_stats),
-        softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now);
-  LOG_D(PHY,
-        "dlsch[enc:%lld mod:%lld scr:%lld rm:%lld t:%lld i:%lld] rx_dft:%lld ",
-        TICK_TO_US(gNB->dlsch_encoding_stats),
-        TICK_TO_US(gNB->dlsch_modulation_stats),
-        TICK_TO_US(gNB->dlsch_scrambling_stats),
-        TICK_TO_US(gNB->dlsch_rate_matching_stats),
-        TICK_TO_US(gNB->dlsch_turbo_encoding_stats),
-        TICK_TO_US(gNB->dlsch_interleaving_stats),
-        TICK_TO_US(gNB->rx_dft_stats));
-  LOG_D(PHY," ulsch[ch:%lld freq:%lld dec:%lld demod:%lld ru:%lld ",
-        TICK_TO_US(gNB->ulsch_channel_estimation_stats),
-        TICK_TO_US(gNB->ulsch_freq_offset_estimation_stats),
-        TICK_TO_US(gNB->ulsch_decoding_stats),
-        TICK_TO_US(gNB->ulsch_demodulation_stats),
-        TICK_TO_US(gNB->ulsch_rate_unmatching_stats));
-  LOG_D(PHY, "td:%lld dei:%lld dem:%lld llr:%lld tci:%lld ",
-        TICK_TO_US(gNB->ulsch_turbo_decoding_stats),
-        TICK_TO_US(gNB->ulsch_deinterleaving_stats),
-        TICK_TO_US(gNB->ulsch_demultiplexing_stats),
-        TICK_TO_US(gNB->ulsch_llr_stats),
-        TICK_TO_US(gNB->ulsch_tc_init_stats));
-  LOG_D(PHY, "tca:%lld tcb:%lld tcg:%lld tce:%lld l1:%lld l2:%lld]\n\n",
-        TICK_TO_US(gNB->ulsch_tc_alpha_stats),
-        TICK_TO_US(gNB->ulsch_tc_beta_stats),
-        TICK_TO_US(gNB->ulsch_tc_gamma_stats),
-        TICK_TO_US(gNB->ulsch_tc_ext_stats),
-        TICK_TO_US(gNB->ulsch_tc_intl1_stats),
-        TICK_TO_US(gNB->ulsch_tc_intl2_stats)
-       );
-#endif
-}
-
 void *ru_thread( void *param ) {
   static int ru_thread_status;
   RU_t               *ru      = (RU_t *)param;
@@ -1771,16 +1289,6 @@ void *ru_thread( void *param ) {
       else LOG_I(PHY,"RU %d rf device ready\n",ru->idx);
     } else LOG_I(PHY,"RU %d no rf device\n",ru->idx);
 
-    // if an asnych_rxtx thread exists
-    // wakeup the thread because the devices are ready at this point
-
-    if ((ru->fh_south_asynch_in)||(ru->fh_north_asynch_in)) {
-      pthread_mutex_lock(&proc->mutex_asynch_rxtx);
-      proc->instance_cnt_asynch_rxtx=0;
-      pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
-      pthread_cond_signal(&proc->cond_asynch_rxtx);
-    } else LOG_I(PHY,"RU %d no asynch_south interface\n",ru->idx);
-
     // if this is a slave RRU, try to synchronize on the DL frequency
     if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru);
 
@@ -1797,11 +1305,6 @@ void *ru_thread( void *param ) {
     }
   }
 
-  pthread_mutex_lock(&proc->mutex_FH1);
-  proc->instance_cnt_FH1 = 0;
-  pthread_mutex_unlock(&proc->mutex_FH1);
-  pthread_cond_signal(&proc->cond_FH1);
-
   // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
   while (!oai_exit) {
     // these are local subframe/frame counters to check that we are in synch with the fronthaul timing.
@@ -1829,18 +1332,7 @@ void *ru_thread( void *param ) {
           proc->frame_tx,proc->tti_tx,
           RC.gNB[0]->proc.frame_rx,RC.gNB[0]->proc.slot_rx,
 	  RC.gNB[0]->proc.frame_tx);
-    /*
-          LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n",
-              ru->do_prach,
-              is_prach_subframe(fp, proc->frame_rx, proc->tti_rx),
-              proc->frame_rx,proc->tti_rx);
 
-        if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->tti_rx)==1)) {
-          wakeup_prach_ru(ru);
-        }*/
-
-    // adjust for timing offset between RU
-    //printf("~~~~~~~~~~~~~~~~~~~~~~~~~~%d.%d in ru_thread is in process\n", proc->frame_rx, proc->tti_rx);
     if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023;
 
     // do RX front-end processing (frequency-shift, dft) if needed
@@ -1924,82 +1416,6 @@ void *ru_thread( void *param ) {
   ru_thread_status = 0;
   return &ru_thread_status;
 }
-/*
-// This thread run the initial synchronization like a UE
-void *ru_thread_synch(void *arg) {
-
-  RU_t *ru = (RU_t*)arg;
-  NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms;
-  int32_t sync_pos,sync_pos2;
-  uint32_t peak_val;
-  uint32_t sync_corr[307200] __attribute__((aligned(32)));
-  static int ru_thread_synch_status;
-
-
-
-  wait_sync("ru_thread_synch");
-
-  // initialize variables for PSS detection
-  lte_sync_time_init(ru->nr_frame_parms);
-
-  while (!oai_exit) {
-
-    // wait to be woken up
-    if (wait_on_condition(&ru->proc.mutex_synch,&ru->proc.cond_synch,&ru->proc.instance_cnt_synch,"ru_thread_synch")<0) break;
-
-    // if we're not in synch, then run initial synch
-    if (ru->in_synch == 0) {
-      // run intial synch like UE
-      LOG_I(PHY,"Running initial synchronization\n");
-
-      sync_pos = lte_sync_time_gNB(ru->common.rxdata,
-           fp,
-           fp->samples_per_subframe*5,
-           &peak_val,
-           sync_corr);
-      LOG_I(PHY,"RU synch: %d, val %d\n",sync_pos,peak_val);
-
-      if (sync_pos >= 0) {
-  if (sync_pos >= fp->nb_prefix_samples)
-    sync_pos2 = sync_pos - fp->nb_prefix_samples;
-  else
-    sync_pos2 = sync_pos + (fp->samples_per_subframe*10) - fp->nb_prefix_samples;
-
-  if (fp->frame_type == FDD) {
-
-    // PSS is hypothesized in last symbol of first slot in Frame
-    int sync_pos_slot = (fp->samples_per_subframe>>1) - fp->ofdm_symbol_size - fp->nb_prefix_samples;
-
-    if (sync_pos2 >= sync_pos_slot)
-      ru->rx_offset = sync_pos2 - sync_pos_slot;
-    else
-      ru->rx_offset = (fp->samples_per_subframe*10) + sync_pos2 - sync_pos_slot;
-  }
-  else {
-
-  }
-
-  LOG_I(PHY,"Estimated sync_pos %d, peak_val %d => timing offset %d\n",sync_pos,peak_val,ru->rx_offset);
-
-  if ((peak_val > 300000) && (sync_pos > 0)) {
-  //      if (sync_pos++ > 3) {
-  write_output("ru_sync.m","sync",(void*)&sync_corr[0],fp->samples_per_subframe*5,1,2);
-  write_output("ru_rx.m","rxs",(void*)ru->ru_time.rxdata[0][0],fp->samples_per_subframe*10,1,1);
-  exit(-1);
-  }
-
-  ru->in_synch=1;
-      }
-    }
-
-    if (release_thread(&ru->proc.mutex_synch,&ru->proc.instance_cnt_synch,"ru_synch_thread") < 0) break;
-  } // oai_exit
-
-  ru_thread_synch_status = 0;
-  return &ru_thread_synch_status;
-
-}
-*/
 
 int nr_start_if(struct RU_t_s *ru, struct PHY_VARS_gNB_s *gNB) {
   return(ru->ifdevice.trx_start_func(&ru->ifdevice));
@@ -2026,12 +1442,7 @@ void init_RU_proc(RU_t *ru) {
   proc = &ru->proc;
   memset((void *)proc,0,sizeof(RU_proc_t));
   proc->ru = ru;
-  proc->instance_cnt_prach       = -1;
   proc->instance_cnt_synch       = -1;
-  proc->instance_cnt_FH          = -1;
-  proc->instance_cnt_FH1         = -1;
-  proc->instance_cnt_gNBs        = -1;
-  proc->instance_cnt_asynch_rxtx = -1;
   proc->instance_cnt_emulateRF   = -1;
   proc->first_rx                 = 1;
   proc->first_tx                 = 1;
@@ -2042,44 +1453,15 @@ void init_RU_proc(RU_t *ru) {
 
   for (i=0; i<10; i++) proc->symbol_mask[i]=0;
 
-  pthread_mutex_init( &proc->mutex_prach, NULL);
-  pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
   pthread_mutex_init( &proc->mutex_synch,NULL);
-  pthread_mutex_init( &proc->mutex_FH,NULL);
-  pthread_mutex_init( &proc->mutex_FH1,NULL);
   pthread_mutex_init( &proc->mutex_emulateRF,NULL);
-  pthread_mutex_init( &proc->mutex_gNBs, NULL);
-  pthread_cond_init( &proc->cond_prach, NULL);
-  pthread_cond_init( &proc->cond_FH, NULL);
-  pthread_cond_init( &proc->cond_FH1, NULL);
   pthread_cond_init( &proc->cond_emulateRF, NULL);
-  pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
   pthread_cond_init( &proc->cond_synch,NULL);
-  pthread_cond_init( &proc->cond_gNBs, NULL);
   threadCreate( &proc->pthread_FH, ru_thread, (void *)ru, "thread_FH", -1, OAI_PRIORITY_RT_MAX );
 
-  if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)
-    threadCreate( &proc->pthread_FH1, ru_thread_tx, (void *)ru, "thread_FH1", -1, OAI_PRIORITY_RT );
-
   if(emulate_rf)
     threadCreate( &proc->pthread_emulateRF, emulatedRF_thread, (void *)proc, "emulateRF", -1, OAI_PRIORITY_RT );
 
-  if (ru->function == NGFI_RRU_IF4p5) {
-    threadCreate( &proc->pthread_prach, ru_thread_prach, (void *)ru, "RACH", -1, OAI_PRIORITY_RT );
-    ///tmp deactivation of synch thread
-    //    if (ru->is_slave == 1) pthread_create( &proc->pthread_synch, attr_synch, ru_thread_synch, (void*)ru);
-
-    if ((ru->if_timing == synch_to_other) ||
-        (ru->function == NGFI_RRU_IF5) ||
-        (ru->function == NGFI_RRU_IF4p5)) threadCreate( &proc->pthread_asynch_rxtx, ru_thread_asynch_rxtx, (void *)ru, "asynch_rxtx", -1, OAI_PRIORITY_RT );
-
-    snprintf( name, sizeof(name), "ru_thread_FH %d", ru->idx );
-    pthread_setname_np( proc->pthread_FH, name );
-  } else if (ru->function == gNodeB_3GPP && ru->if_south == LOCAL_RF) { // DJP - need something else to distinguish between monolithic and PNF
-    LOG_I(PHY,"%s() DJP - added creation of pthread_prach\n", __FUNCTION__);
-    threadCreate( &proc->pthread_prach, ru_thread_prach, (void *)ru,"RACH", -1, OAI_PRIORITY_RT );
-  }
-
   if (get_thread_worker_conf() == WORKER_ENABLE) {
     if (ru->feprx) nr_init_feprx_thread(ru);
 
@@ -2092,26 +1474,10 @@ void init_RU_proc(RU_t *ru) {
 void kill_NR_RU_proc(int inst) {
   RU_t *ru = RC.ru[inst];
   RU_proc_t *proc = &ru->proc;
-  pthread_mutex_lock(&proc->mutex_FH);
-  proc->instance_cnt_FH = 0;
-  pthread_mutex_unlock(&proc->mutex_FH);
-  pthread_cond_signal(&proc->cond_FH);
-  pthread_mutex_lock(&proc->mutex_prach);
-  proc->instance_cnt_prach = 0;
-  pthread_mutex_unlock(&proc->mutex_prach);
-  pthread_cond_signal(&proc->cond_prach);
   pthread_mutex_lock(&proc->mutex_synch);
   proc->instance_cnt_synch = 0;
   pthread_mutex_unlock(&proc->mutex_synch);
   pthread_cond_signal(&proc->cond_synch);
-  pthread_mutex_lock(&proc->mutex_gNBs);
-  proc->instance_cnt_gNBs = 0;
-  pthread_mutex_unlock(&proc->mutex_gNBs);
-  pthread_cond_signal(&proc->cond_gNBs);
-  pthread_mutex_lock(&proc->mutex_asynch_rxtx);
-  proc->instance_cnt_asynch_rxtx = 0;
-  pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
-  pthread_cond_signal(&proc->cond_asynch_rxtx);
   LOG_D(PHY, "Joining pthread_FH\n");
   pthread_join(proc->pthread_FH, NULL);
 
@@ -2161,16 +1527,8 @@ void kill_NR_RU_proc(int inst) {
     pthread_join(ru->ru_stats_thread, NULL);
   }
 
-  pthread_mutex_destroy(&proc->mutex_prach);
-  pthread_mutex_destroy(&proc->mutex_asynch_rxtx);
   pthread_mutex_destroy(&proc->mutex_synch);
-  pthread_mutex_destroy(&proc->mutex_FH);
-  pthread_mutex_destroy(&proc->mutex_gNBs);
-  pthread_cond_destroy(&proc->cond_prach);
-  pthread_cond_destroy(&proc->cond_FH);
-  pthread_cond_destroy(&proc->cond_asynch_rxtx);
   pthread_cond_destroy(&proc->cond_synch);
-  pthread_cond_destroy(&proc->cond_gNBs);
 }
 
 int check_capabilities(RU_t *ru,RRU_capabilities_t *cap)
diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h
index a6035122c0..47aecd7b10 100644
--- a/executables/softmodem-common.h
+++ b/executables/softmodem-common.h
@@ -240,6 +240,10 @@ extern char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr);
 extern void set_softmodem_sighandler(void);
 extern uint64_t downlink_frequency[MAX_NUM_CCs][4];
 extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
+
+void tx_func(void *param);
+void rx_func(void *param);
+void ru_tx_func(void *param);
 #ifdef __cplusplus
 }
 #endif
diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h
index b465a51a2a..885f955a2a 100644
--- a/openair1/PHY/defs_RU.h
+++ b/openair1/PHY/defs_RU.h
@@ -741,4 +741,10 @@ typedef struct RRU_config_s {
   MBSFN_config_t MBSFN_config[8];
 } RRU_config_t;
 
+typedef struct processingData_RU {
+  int frame_tx;
+  int slot_tx;
+  openair0_timestamp timestamp_tx;
+  RU_t *ru;
+} processingData_RU_t;
 #endif //__PHY_DEFS_RU__H__
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index 440cfc7a69..24cecc85da 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -875,4 +875,13 @@ union ldpcReqUnion {
   uint64_t p;
 };
 
+typedef struct processingData_L1 {
+  int frame_rx;
+  int frame_tx;
+  int slot_rx;
+  int slot_tx;
+  openair0_timestamp timestamp_tx;
+  PHY_VARS_gNB *gNB;
+} processingData_L1_t;
+
 #endif
-- 
2.26.2