diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index 30f06e30d077f5b9b511058280c9b37e47f96068..d1505d9fdad1d82c9d049f5bece46da0f5d1ebf7 100755
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -186,9 +186,11 @@ typedef struct {
   int frame_tx;
   /// frame to act upon for reception 
   int frame_rx;
-  /// instance count for tx processing thread
+  /// \brief Instance count for tx processing thread.
+  /// \internal This variable is protected by \ref mutex_tx.
   int instance_cnt_tx;
-  /// instance count for rx processing thread
+  /// \brief Instance count for rx processing thread.
+  /// \internal This variable is protected by \ref mutex_rx.
   int instance_cnt_rx;
   /// pthread structure for tx processing thread
   pthread_t pthread_tx;
@@ -204,12 +206,16 @@ typedef struct {
   pthread_mutex_t mutex_rx;
 } eNB_proc_t;
 
-/// Top-level PHY Data Structure for eNB 
+//! \brief Number of eNB TX and RX threads.
+//! This number must be equal to the number of LTE subframes (10). Each thread is responsible for a single subframe.
+#define NUM_ENB_THREADS 10
+
+/// Top-level PHY Data Structure for eNB
 typedef struct PHY_VARS_eNB_s{
   /// Module ID indicator for this instance
   module_id_t          Mod_id;
   uint8_t              CC_id;
-  eNB_proc_t           proc[10];
+  eNB_proc_t           proc[NUM_ENB_THREADS];
   uint8_t              local_flag;
   uint32_t             rx_total_gain_eNB_dB;
   LTE_DL_FRAME_PARMS   lte_frame_parms;
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 074be3f3542e450f1931d1a84b33c7ee1915901f..b6452bc221085c141c3d6f326c5294263c8d3113 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -195,11 +195,11 @@ int sync_var=-1;
 
 struct sched_param              sched_param_UE_thread;
 
-pthread_attr_t                  attr_eNB_proc_tx[MAX_NUM_CCs][10];
-pthread_attr_t                  attr_eNB_proc_rx[MAX_NUM_CCs][10];
+pthread_attr_t                  attr_eNB_proc_tx[MAX_NUM_CCs][NUM_ENB_THREADS];
+pthread_attr_t                  attr_eNB_proc_rx[MAX_NUM_CCs][NUM_ENB_THREADS];
 #ifndef LOWLATENCY
-struct sched_param              sched_param_eNB_proc_tx[MAX_NUM_CCs][10];
-struct sched_param              sched_param_eNB_proc_rx[MAX_NUM_CCs][10];
+struct sched_param              sched_param_eNB_proc_tx[MAX_NUM_CCs][NUM_ENB_THREADS];
+struct sched_param              sched_param_eNB_proc_rx[MAX_NUM_CCs][NUM_ENB_THREADS];
 #endif
 #ifdef XFORMS
 static pthread_t                forms_thread; //xforms
@@ -922,36 +922,32 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) {
 }
 
 
-int eNB_thread_tx_status[10];
-static void * eNB_thread_tx(void *param) {
+/*!
+ * \brief The transmit thread of eNB.
+ * \ref NUM_ENB_THREADS threads of this type are active at the same time.
+ * \param param is a \ref eNB_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* eNB_thread_tx( void* param )
+{
+  static int eNB_thread_tx_status[NUM_ENB_THREADS];
 
-  //unsigned long cpuid;
   eNB_proc_t *proc = (eNB_proc_t*)param;
-  //  RTIME time_in,time_out;
+
+  // set default return value
+  eNB_thread_tx_status[proc->subframe] = 0;
+
 #ifdef RTAI
   RT_TASK *task;
   char task_name[8];
-#else 
-#ifdef LOWLATENCY
-  struct sched_attr attr;
-  unsigned int flags = 0;
-#endif
-#endif 
 
- 
-  /*#if defined(ENABLE_ITTI)
-  // Wait for eNB application initialization to be complete (eNB registration to MME)
-  wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
-  #endif*/
-
-#ifdef RTAI
   sprintf(task_name,"TXC%dS%d",proc->CC_id,proc->subframe);
   task = rt_task_init_schmod(nam2num(task_name), 0, 0, 0, SCHED_FIFO, 0xF);
 
-  if (task==NULL) {
-  LOG_E(PHY,"[SCHED][eNB] Problem starting eNB_proc_TX thread_index %d (%s)!!!!\n",proc->subframe,task_name);
-  return 0;
-}
+  if (task == NULL) {
+    LOG_E(PHY,"[SCHED][eNB] Problem starting eNB_proc_TX thread_index %d (%s)!!!!\n",proc->subframe,task_name);
+    return 0;
+  }
   else {
   LOG_I(PHY,"[SCHED][eNB] eNB TX thread CC %d SF %d started with id %p\n",
     proc->CC_id,
@@ -960,160 +956,153 @@ static void * eNB_thread_tx(void *param) {
 }
 #else
 #ifdef LOWLATENCY
+  struct sched_attr attr;
+  unsigned int flags = 0;
+
   attr.size = sizeof(attr);
   attr.sched_flags = 0;
   attr.sched_nice = 0;
   attr.sched_priority = 0;
   
-  /* This creates a 1ms reservation every 10ms period*/
-  attr.sched_policy = SCHED_DEADLINE;
-  attr.sched_runtime  = 0.9   *  1000000;  // each tx thread requires 1ms to finish its job
+  // This creates a 1ms reservation every 10ms period
+  attr.sched_policy   = SCHED_DEADLINE;
+  attr.sched_runtime  = 0.9 *  1000000; // each tx thread requires 1ms to finish its job
   attr.sched_deadline = 1   *  1000000; // each tx thread will finish within 1ms
   attr.sched_period   = 1   * 10000000; // each tx thread has a period of 10ms from the starting point
   
-  if (sched_setattr(0, &attr, flags) < 0 ){
-  perror("[SCHED] eNB tx thread: sched_setattr failed\n");
-  exit(-1);
-}
-  LOG_I(HW,"[SCHED] eNB TX deadline thread %d(id %ld) started on CPU %d\n",
-    proc->subframe, gettid(),sched_getcpu());
+  if (sched_setattr(0, &attr, flags) < 0 ) {
+    perror("[SCHED] eNB tx thread: sched_setattr failed\n");
+    return &eNB_thread_tx_status[proc->subframe];
+  }
+  LOG_I( HW, "[SCHED] eNB TX deadline thread %d(id %ld) started on CPU %d\n", proc->subframe, gettid(), sched_getcpu() );
 #else 
-  LOG_I(HW,"[SCHED] eNB TX thread %d started on CPU %d\n",
-    proc->subframe,sched_getcpu());
+  LOG_I( HW, "[SCHED][eNB] TX thread %d started on CPU %d\n", proc->subframe, sched_getcpu() );
 #endif
 
 #endif
 
   mlockall(MCL_CURRENT | MCL_FUTURE);
 
-  //rt_set_runnable_on_cpuid(task,1);
-  //cpuid = rtai_cpuid();
-
 #ifdef HARD_RT
   rt_make_hard_real_time();
 #endif
 
-  while (!oai_exit){
+  while (!oai_exit) {
     
-  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_TX0+(2*proc->subframe),0);
+    vcd_signal_dumper_dump_function_by_name( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_TX0+(2*proc->subframe), 0 );
     
-  //LOG_I(PHY,"Locking mutex for eNB proc %d (IC %d,mutex %p)\n",proc->subframe,proc->instance_cnt,&proc->mutex);
-  //    printf("Locking mutex for eNB proc %d (subframe_tx %d))\n",proc->subframe,proc->instance_cnt_tx);
-
     if (pthread_mutex_lock(&proc->mutex_tx) != 0) {
-      LOG_E(PHY,"[SCHED][eNB] error locking mutex for eNB TX proc %d\n",proc->subframe);
+      LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB TX proc %d\n", proc->subframe );
       exit_fun("nothing to add");
+      break;
     }
-    else {
       
-  while (proc->instance_cnt_tx < 0) {
-  //	LOG_I(PHY,"Waiting and unlocking mutex for eNB proc %d (IC %d,lock %d)\n",proc->subframe,proc->instance_cnt,pthread_mutex_trylock(&proc->mutex));
-  //printf("Waiting and unlocking mutex for eNB proc %d (subframe_tx %d)\n",proc->subframe,proc->instance_cnt_tx);
-	
-	pthread_cond_wait(&proc->cond_tx,&proc->mutex_tx);
-      }
-      //      LOG_I(PHY,"Waking up and unlocking mutex for eNB proc %d instance_cnt_tx %d\n",proc->subframe,proc->instance_cnt_tx);
-      if (pthread_mutex_unlock(&proc->mutex_tx) != 0) {	
-	LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for eNB TX proc %d\n",proc->subframe);
-	exit_fun("nothing to add");
-      }
+    while (proc->instance_cnt_tx < 0) {
+      pthread_cond_wait( &proc->cond_tx, &proc->mutex_tx );
+    }
+
+    if (pthread_mutex_unlock(&proc->mutex_tx) != 0) {
+      LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for eNB TX proc %d\n",proc->subframe);
+      exit_fun("nothing to add");
+      break;
     }
-    vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_TX0+(2*proc->subframe),1);    
-    vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB, proc->frame_tx);
-    start_meas(&softmodem_stats_tx_sf[proc->subframe]);
 
-  if (oai_exit) break;
+    vcd_signal_dumper_dump_function_by_name( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_TX0+(2*proc->subframe), 1 );
+    vcd_signal_dumper_dump_variable_by_name( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB, proc->frame_tx );
+    start_meas( &softmodem_stats_tx_sf[proc->subframe] );
 
+    if (oai_exit) break;
     
-  if ((((PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms.frame_type == TDD)&&
-    (subframe_select(&PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms,proc->subframe_tx)==SF_DL))||
-    (PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms.frame_type == FDD))) {
+    if ((((PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms.frame_type == TDD)&&
+          (subframe_select(&PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms,proc->subframe_tx)==SF_DL))||
+         (PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms.frame_type == FDD))) {
 
-  phy_procedures_eNB_TX( proc->subframe, PHY_vars_eNB_g[0][proc->CC_id], 0, no_relay, NULL );
+      phy_procedures_eNB_TX( proc->subframe, PHY_vars_eNB_g[0][proc->CC_id], 0, no_relay, NULL );
       
-}
-  if ((subframe_select(&PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms,proc->subframe_tx)==SF_S)) {
-  phy_procedures_eNB_TX(proc->subframe,PHY_vars_eNB_g[0][proc->CC_id],0,no_relay,NULL);
-}
+    }
+    if ((subframe_select(&PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms,proc->subframe_tx) == SF_S)) {
+      phy_procedures_eNB_TX( proc->subframe, PHY_vars_eNB_g[0][proc->CC_id], 0, no_relay, NULL );
+    }
     
-  do_OFDM_mod_rt(proc->subframe_tx,PHY_vars_eNB_g[0][proc->CC_id]);  
+    do_OFDM_mod_rt( proc->subframe_tx, PHY_vars_eNB_g[0][proc->CC_id] );
     
-  if (pthread_mutex_lock(&proc->mutex_tx) != 0) {
-  printf("[openair][SCHED][eNB] error locking mutex for eNB TX proc %d\n",proc->subframe);
-}
-  else {
-  proc->instance_cnt_tx--;
-      
-  if (pthread_mutex_unlock(&proc->mutex_tx) != 0) {	
-  printf("[openair][SCHED][eNB] error unlocking mutex for eNB TX proc %d\n",proc->subframe);
-}
-}
+    if (pthread_mutex_lock(&proc->mutex_tx) != 0) {
+      LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB TX proc %d\n", proc->subframe );
+      exit_fun("nothing to add");
+      break;
+    }
 
-    
-  proc->frame_tx++;
-  if (proc->frame_tx==1024)
-    proc->frame_tx=0;
+    proc->instance_cnt_tx--;
+
+    if (pthread_mutex_unlock(&proc->mutex_tx) != 0) {
+      LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for eNB TX proc %d\n", proc->subframe );
+      exit_fun("nothing to add");
+      break;
+    }
+
+    proc->frame_tx++;
+    if (proc->frame_tx==1024)
+      proc->frame_tx=0;
+
+  }
+
+  stop_meas( &softmodem_stats_tx_sf[proc->subframe] );
+  vcd_signal_dumper_dump_function_by_name( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_TX0+(2*proc->subframe), 0 );
 
-}    
-  stop_meas(&softmodem_stats_tx_sf[proc->subframe]);
-  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_TX0+(2*proc->subframe),0);        
 #ifdef HARD_RT
   rt_make_soft_real_time();
 #endif
   
 #ifdef DEBUG_THREADS
-  printf("Exiting eNB thread TX %d\n",proc->subframe);
+  printf( "Exiting eNB thread TX %d\n", proc->subframe );
 #endif
   // clean task
 #ifdef RTAI
   rt_task_delete(task);
-#else
-  eNB_thread_tx_status[proc->subframe]=0;
-  pthread_exit(&eNB_thread_tx_status[proc->subframe]);
 #endif
   
-#ifdef DEBUG_THREADS
-  printf("Exiting eNB TX thread %d\n",proc->subframe);
-#endif
+  eNB_thread_tx_status[proc->subframe] = 0;
+  return &eNB_thread_tx_status[proc->subframe];
 }
 
-  int eNB_thread_rx_status[10];
-  static void * eNB_thread_rx(void *param) {
 
-  //unsigned long cpuid;
+/*!
+ * \brief The receive thread of eNB.
+ * \ref NUM_ENB_THREADS threads of this type are active at the same time.
+ * \param param is a \ref eNB_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* eNB_thread_rx( void* param )
+{
+  static int eNB_thread_rx_status[NUM_ENB_THREADS];
+
   eNB_proc_t *proc = (eNB_proc_t*)param;
-  //  RTIME time_in,time_out;
+
+  // set default return value
+  eNB_thread_rx_status[proc->subframe] = 0;
+
 #ifdef RTAI
   RT_TASK *task;
   char task_name[8];
-#else
-#ifdef LOWLATENCY
-  struct sched_attr attr;
-  unsigned int flags = 0;
-#endif
-#endif
-
-  /*#if defined(ENABLE_ITTI)
-  // Wait for eNB application initialization to be complete (eNB registration to MME) 
-  wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
-  #endif*/
 
-#ifdef RTAI
   sprintf(task_name,"RXC%1dS%1d",proc->CC_id,proc->subframe);
   task = rt_task_init_schmod(nam2num(task_name), 0, 0, 0, SCHED_FIFO, 0xF);
 
   if (task==NULL) {
-  LOG_E(PHY,"[SCHED][eNB] Problem starting eNB_proc_RX thread_index %d (%s)!!!!\n",proc->subframe,task_name);
-  return 0;
-}
+    LOG_E(PHY,"[SCHED][eNB] Problem starting eNB_proc_RX thread_index %d (%s)!!!!\n",proc->subframe,task_name);
+    return 0;
+  }
   else {
     LOG_I(PHY,"[SCHED][eNB] eNB RX thread CC_id %d SF %d started with id %p\n", /*  on CPU %d*/
-	  proc->CC_id,
-	  proc->subframe,
-	  task); /*,rtai_cpuid()*/
+          proc->CC_id,
+          proc->subframe,
+          task); /*,rtai_cpuid()*/
   }
 #else
 #ifdef LOWLATENCY
+  struct sched_attr attr;
+  unsigned int flags = 0;
+
   attr.size = sizeof(attr);
   attr.sched_flags = 0;
   attr.sched_nice = 0;
@@ -1121,75 +1110,72 @@ static void * eNB_thread_tx(void *param) {
   
   /* This creates a 2ms reservation every 10ms period*/
   attr.sched_policy = SCHED_DEADLINE;
-  attr.sched_runtime  = 0.9   *  1000000;  // each rx thread must finish its job in the worst case in 2ms
+  attr.sched_runtime  = 0.9 *  1000000; // each rx thread must finish its job in the worst case in 2ms
   attr.sched_deadline = 1   *  1000000; // each rx thread will finish within 2ms
   attr.sched_period   = 1   * 10000000; // each rx thread has a period of 10ms from the starting point
   
   if (sched_setattr(0, &attr, flags) < 0 ){
     perror("[SCHED] eNB RX sched_setattr failed\n");
-    exit(-1);
+    return &eNB_thread_rx_status[proc->subframe];
   }
-  LOG_I(HW,"[SCHED] eNB RX deadline thread %d(id %ld) started on CPU %d\n",
-	proc->subframe, gettid(),sched_getcpu());
+  LOG_I( HW, "[SCHED] eNB RX deadline thread %d(id %ld) started on CPU %d\n", proc->subframe, gettid(), sched_getcpu() );
 #else 
-  LOG_I(HW,"[SCHED][eNB] eNB RX thread %d started on CPU %d\n",
-	proc->subframe,sched_getcpu());
-#endif
- 
+  LOG_I( HW, "[SCHED][eNB] RX thread %d started on CPU %d\n", proc->subframe, sched_getcpu() );
 #endif
+#endif // RTAI
 
   mlockall(MCL_CURRENT | MCL_FUTURE);
 
-  //rt_set_runnable_on_cpuid(task,1);
-  //cpuid = rtai_cpuid();
-
 #ifdef HARD_RT
   rt_make_hard_real_time();
 #endif
 
-  while (!oai_exit){
+  while (!oai_exit) {
 
-    vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX0+(2*proc->subframe),0);
+    vcd_signal_dumper_dump_function_by_name( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX0+(2*proc->subframe), 0 );
     
-    // LOG_I(PHY,"Locking mutex for eNB proc %d (IC %d,mutex %p)\n",proc->subframe,proc->instance_cnt_rx,&proc->mutex_rx);
     if (pthread_mutex_lock(&proc->mutex_rx) != 0) {
-      LOG_E(PHY,"[SCHED][eNB] error locking mutex for eNB RX proc %d\n",proc->subframe);
+      LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB RX proc %d\n", proc->subframe );
+      exit_fun( "error locking mutex" );
+      break;
     }
-    else {
-        
-      while (proc->instance_cnt_rx < 0) {
-	//	LOG_I(PHY,"Waiting and unlocking mutex for eNB proc %d (IC %d,lock %d)\n",proc->subframe,proc->instance_cnt_rx,pthread_mutex_trylock(&proc->mutex_rx));
 
-	pthread_cond_wait(&proc->cond_rx,&proc->mutex_rx);
-      }
-      //      LOG_I(PHY,"Waking up and unlocking mutex for eNB RX proc %d instance_cnt_rx %d\n",proc->subframe,proc->instance_cnt_rx);
-      if (pthread_mutex_unlock(&proc->mutex_rx) != 0) {	
-	LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for eNB RX proc %d\n",proc->subframe);
-      }
+    while (proc->instance_cnt_rx < 0) {
+      pthread_cond_wait( &proc->cond_rx, &proc->mutex_rx );
     }
-    vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX0+(2*proc->subframe),1);    
-    vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, proc->frame_rx);
-    start_meas(&softmodem_stats_rx_sf[proc->subframe]);
+
+    if (pthread_mutex_unlock(&proc->mutex_rx) != 0) {
+      LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for eNB RX proc %d\n", proc->subframe );
+      exit_fun( "error unlocking mutex" );
+      break;
+    }
+
+    vcd_signal_dumper_dump_function_by_name( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX0+(2*proc->subframe), 1 );
+    vcd_signal_dumper_dump_variable_by_name( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, proc->frame_rx );
+    start_meas( &softmodem_stats_rx_sf[proc->subframe] );
     
     if (oai_exit) break;
     
     if ((((PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms.frame_type == TDD )&&(subframe_select(&PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms,proc->subframe_rx)==SF_UL)) ||
-	 (PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms.frame_type == FDD))){
-      phy_procedures_eNB_RX(proc->subframe,PHY_vars_eNB_g[0][proc->CC_id],0,no_relay);
+         (PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms.frame_type == FDD))){
+      phy_procedures_eNB_RX( proc->subframe, PHY_vars_eNB_g[0][proc->CC_id], 0, no_relay );
     }
-    if ((subframe_select(&PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms,proc->subframe_rx)==SF_S)){
-      phy_procedures_eNB_S_RX(proc->subframe,PHY_vars_eNB_g[0][proc->CC_id],0,no_relay);
+    if ((subframe_select(&PHY_vars_eNB_g[0][proc->CC_id]->lte_frame_parms,proc->subframe_rx) == SF_S)){
+      phy_procedures_eNB_S_RX( proc->subframe, PHY_vars_eNB_g[0][proc->CC_id], 0, no_relay );
     }
-      
+
     if (pthread_mutex_lock(&proc->mutex_rx) != 0) {
-      printf("[openair][SCHED][eNB] error locking mutex for eNB RX proc %d\n",proc->subframe);
+      LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB RX proc %d\n", proc->subframe );
+      exit_fun( "error locking mutex" );
+      break;
     }
-    else {
-      proc->instance_cnt_rx--;
-      
-      if (pthread_mutex_unlock(&proc->mutex_rx) != 0) {	
-	printf("[openair][SCHED][eNB] error unlocking mutex for eNB RX proc %d\n",proc->subframe);
-      }
+
+    proc->instance_cnt_rx--;
+
+    if (pthread_mutex_unlock(&proc->mutex_rx) != 0) {
+      LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for eNB RX proc %d\n", proc->subframe );
+      exit_fun( "error unlocking mutex" );
+      break;
     }
 
     proc->frame_rx++;
@@ -1197,68 +1183,64 @@ static void * eNB_thread_tx(void *param) {
       proc->frame_rx=0;
     
   }
-  stop_meas(&softmodem_stats_rx_sf[proc->subframe]);
-  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX0+(2*proc->subframe),0);        
+
+  stop_meas( &softmodem_stats_rx_sf[proc->subframe] );
+  vcd_signal_dumper_dump_function_by_name( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX0+(2*proc->subframe), 0 );
+
 #ifdef HARD_RT
   rt_make_soft_real_time();
 #endif
 
 #ifdef DEBUG_THREADS
-  printf("Exiting eNB thread RX %d\n",proc->subframe);
+  printf( "Exiting eNB thread RX %d\n", proc->subframe );
 #endif
   // clean task
 #ifdef RTAI
   rt_task_delete(task);
-#else
-  eNB_thread_rx_status[proc->subframe]=0;
-  pthread_exit(&eNB_thread_rx_status[proc->subframe]);
 #endif
 
-#ifdef DEBUG_THREADS
-  printf("Exiting eNB RX thread %d\n",proc->subframe);
-#endif
+  eNB_thread_rx_status[proc->subframe] = 0;
+  return &eNB_thread_rx_status[proc->subframe];
 }
 
 
 
 
-void init_eNB_proc(void) {
-
+void init_eNB_proc(void)
+{
   int i;
   int CC_id;
 
-  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
-    for (i=0;i<10;i++) {
-      /*set the stack sizw */ 
-      pthread_attr_init (&attr_eNB_proc_tx[CC_id][i]);
-      if (pthread_attr_setstacksize(&attr_eNB_proc_tx[CC_id][i],PTHREAD_STACK_MIN) != 0)
+  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+    for (i=0; i<NUM_ENB_THREADS; i++) {
+      // set the stack size
+      pthread_attr_init( &attr_eNB_proc_tx[CC_id][i] );
+      if (pthread_attr_setstacksize( &attr_eNB_proc_tx[CC_id][i], PTHREAD_STACK_MIN ) != 0)
 	perror("[ENB_PROC_TX] setting thread stack size failed\n");
-
-      pthread_attr_init (&attr_eNB_proc_rx[CC_id][i]);
-      if (pthread_attr_setstacksize(&attr_eNB_proc_rx[CC_id][i],PTHREAD_STACK_MIN) != 0)
+      pthread_attr_init( &attr_eNB_proc_rx[CC_id][i] );
+      if (pthread_attr_setstacksize( &attr_eNB_proc_rx[CC_id][i], PTHREAD_STACK_MIN ) != 0)
 	perror("[ENB_PROC_RX] setting thread stack size failed\n");
-      /* set the kernel scheduling policy and priority */
+
 #ifndef LOWLATENCY
-      //attr_dlsch_threads.priority = 1;
+      // set the kernel scheduling policy and priority
       sched_param_eNB_proc_tx[CC_id][i].sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY;
       pthread_attr_setschedparam  (&attr_eNB_proc_tx[CC_id][i], &sched_param_eNB_proc_tx[CC_id][i]);
       pthread_attr_setschedpolicy (&attr_eNB_proc_tx[CC_id][i], SCHED_FIFO);
-      //attr_dlsch_threads.priority = 1;
       sched_param_eNB_proc_rx[CC_id][i].sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY;
       pthread_attr_setschedparam  (&attr_eNB_proc_rx[CC_id][i], &sched_param_eNB_proc_rx[CC_id][i]);
       pthread_attr_setschedpolicy (&attr_eNB_proc_rx[CC_id][i], SCHED_FIFO);
 #endif       
       
-      PHY_vars_eNB_g[0][CC_id]->proc[i].instance_cnt_tx=-1;
-      PHY_vars_eNB_g[0][CC_id]->proc[i].instance_cnt_rx=-1;
-      PHY_vars_eNB_g[0][CC_id]->proc[i].subframe=i;
+      PHY_vars_eNB_g[0][CC_id]->proc[i].instance_cnt_tx = -1;
+      PHY_vars_eNB_g[0][CC_id]->proc[i].instance_cnt_rx = -1;
+      PHY_vars_eNB_g[0][CC_id]->proc[i].subframe = i;
       PHY_vars_eNB_g[0][CC_id]->proc[i].CC_id = CC_id;
-      pthread_mutex_init(&PHY_vars_eNB_g[0][CC_id]->proc[i].mutex_tx,NULL);
-      pthread_mutex_init(&PHY_vars_eNB_g[0][CC_id]->proc[i].mutex_rx,NULL);
-      pthread_cond_init(&PHY_vars_eNB_g[0][CC_id]->proc[i].cond_tx,NULL);
-      pthread_cond_init(&PHY_vars_eNB_g[0][CC_id]->proc[i].cond_rx,NULL);
-      pthread_create(&PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_tx,NULL,eNB_thread_tx,(void*)&PHY_vars_eNB_g[0][CC_id]->proc[i]);
-      pthread_create(&PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_rx,NULL,eNB_thread_rx,(void*)&PHY_vars_eNB_g[0][CC_id]->proc[i]);
+      pthread_mutex_init( &PHY_vars_eNB_g[0][CC_id]->proc[i].mutex_tx, NULL);
+      pthread_mutex_init( &PHY_vars_eNB_g[0][CC_id]->proc[i].mutex_rx, NULL);
+      pthread_cond_init( &PHY_vars_eNB_g[0][CC_id]->proc[i].cond_tx, NULL);
+      pthread_cond_init( &PHY_vars_eNB_g[0][CC_id]->proc[i].cond_rx, NULL);
+      pthread_create( &PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_tx, NULL, eNB_thread_tx, &PHY_vars_eNB_g[0][CC_id]->proc[i] );
+      pthread_create( &PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_rx, NULL, eNB_thread_rx, &PHY_vars_eNB_g[0][CC_id]->proc[i] );
       PHY_vars_eNB_g[0][CC_id]->proc[i].frame_tx = 0;
       PHY_vars_eNB_g[0][CC_id]->proc[i].frame_rx = 0;
 #ifdef EXMIMO
@@ -1289,43 +1271,69 @@ void init_eNB_proc(void) {
   }
 }
 
-void kill_eNB_proc(void) {
-
-  int i;
-  void *status_tx,*status_rx;
-  int CC_id;
+/*!
+ * \brief Terminate eNB TX and RX threads.
+ */
+void kill_eNB_proc(void)
+{
+  int *status;
+  int result;
 
-  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) 
-    for (i=0;i<10;i++) {
+  for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++)
+    for (int i=0; i<NUM_ENB_THREADS; i++) {
       
 #ifdef DEBUG_THREADS
-      printf("Killing TX CC_id %d thread %d\n",CC_id,i);
+      printf( "Killing TX CC_id %d thread %d\n", CC_id, i );
 #endif
-      PHY_vars_eNB_g[0][CC_id]->proc[i].instance_cnt_tx=0; 
-      pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[i].cond_tx);
+
+      PHY_vars_eNB_g[0][CC_id]->proc[i].instance_cnt_tx = 0; // FIXME data race!
+      pthread_cond_signal( &PHY_vars_eNB_g[0][CC_id]->proc[i].cond_tx );
+
 #ifdef DEBUG_THREADS
-      printf("Joining eNB TX CC_id %d thread %d...\n",CC_id,i);
+      printf( "Joining eNB TX CC_id %d thread %d...\n", CC_id, i );
 #endif
-      pthread_join(PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_tx,&status_tx);
+      result = pthread_join( PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_tx, (void**)&status );
+
 #ifdef DEBUG_THREADS
-      if (status_tx) printf("status %p...\n",status_tx);
+      if (result != 0) {
+        printf( "Error joining thread.\n" );
+      } else {
+        if (status) {
+          printf( "status %d\n", *status );
+        } else {
+          printf( "The thread was killed. No status available.\n" );
+        }
+      }
 #endif
+
 #ifdef DEBUG_THREADS
-      printf("Killing RX CC_id %d thread %d\n",CC_id,i);
+      printf( "Killing RX CC_id %d thread %d\n", CC_id, i );
 #endif
-      PHY_vars_eNB_g[0][CC_id]->proc[i].instance_cnt_rx=0; 
-      pthread_cond_signal(&PHY_vars_eNB_g[0][CC_id]->proc[i].cond_rx);
+
+      PHY_vars_eNB_g[0][CC_id]->proc[i].instance_cnt_rx = 0; // FIXME data race!
+      pthread_cond_signal( &PHY_vars_eNB_g[0][CC_id]->proc[i].cond_rx );
+
 #ifdef DEBUG_THREADS
-      printf("Joining eNB RX CC_id %d thread %d...\n",CC_id,i);
+      printf( "Joining eNB RX CC_id %d thread %d...\n", CC_id, i );
 #endif
-      pthread_join(PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_rx,&status_rx);
+      result = pthread_join( PHY_vars_eNB_g[0][CC_id]->proc[i].pthread_rx, (void**)&status );
+
 #ifdef DEBUG_THREADS 
-      if (status_rx) printf("status %p...\n",status_rx);
+      if (result != 0) {
+        printf( "Error joining thread.\n" );
+      } else {
+        if (status) {
+          printf( "status %d\n", *status );
+        } else {
+          printf( "The thread was killed. No status available.\n" );
+        }
+      }
 #endif
-      pthread_mutex_destroy(&PHY_vars_eNB_g[0][CC_id]->proc[i].mutex_tx);
-      pthread_mutex_destroy(&PHY_vars_eNB_g[0][CC_id]->proc[i].mutex_rx);
-      pthread_cond_destroy(&PHY_vars_eNB_g[0][CC_id]->proc[i].cond_tx);
-      pthread_cond_destroy(&PHY_vars_eNB_g[0][CC_id]->proc[i].cond_rx);
+
+      pthread_mutex_destroy( &PHY_vars_eNB_g[0][CC_id]->proc[i].mutex_tx );
+      pthread_mutex_destroy( &PHY_vars_eNB_g[0][CC_id]->proc[i].mutex_rx );
+      pthread_cond_destroy( &PHY_vars_eNB_g[0][CC_id]->proc[i].cond_tx );
+      pthread_cond_destroy( &PHY_vars_eNB_g[0][CC_id]->proc[i].cond_rx );
     }
 }
 
@@ -1333,22 +1341,16 @@ void kill_eNB_proc(void) {
 
 
   
-/* This is the main eNB thread. */
-int eNB_thread_status;
-
 
-
-static void *eNB_thread(void *arg)
+/*!
+ * \brief This is the main eNB thread.
+ * \param arg unused
+ * \returns a pointer to an int. The storage is not on the heap and must not be freed.
+ */
+static void* eNB_thread( void* arg )
 {
-#ifdef RTAI
-  RT_TASK *task;
-#else 
-#ifdef LOWLATENCY
-  struct sched_attr attr;
-  unsigned int flags = 0;
-//  unsigned long mask = 1; /* processor 0 */
-#endif
-#endif
+  UNUSED(arg);
+  static int eNB_thread_status;
 
 #ifdef EXMIMO
   unsigned char slot=0;
@@ -1375,8 +1377,7 @@ static void *eNB_thread(void *arg)
   int spp;
   int tx_launched=0;
  
-  //  int tx_offset;
-  void *rxp[2],*txp[2];
+  void *rxp[2], *txp[2];
   int i;
 
   openair0_timestamp timestamp;
@@ -1397,9 +1398,12 @@ static void *eNB_thread(void *arg)
   */
 
 #ifdef RTAI
-  task = rt_task_init_schmod(nam2num("eNBmain"), 0, 0, 0, SCHED_FIFO, 0xF);
+  RT_TASK* task = rt_task_init_schmod(nam2num("eNBmain"), 0, 0, 0, SCHED_FIFO, 0xF);
 #else 
 #ifdef LOWLATENCY
+  struct sched_attr attr;
+  unsigned int flags = 0;
+
   attr.size = sizeof(attr);
   attr.sched_flags = 0;
   attr.sched_nice = 0;
@@ -1751,14 +1755,13 @@ static void *eNB_thread(void *arg)
   // clean task
 #ifdef RTAI
   rt_task_delete(task);
-#else
-  eNB_thread_status = 0;
-  pthread_exit(&eNB_thread_status);
 #endif
 #ifdef DEBUG_THREADS
   printf("eNB_thread deleted. returning\n");
 #endif
-  return 0;
+
+  eNB_thread_status = 0;
+  return &eNB_thread_status;
 }
 
 
@@ -2119,13 +2122,8 @@ static void get_options (int argc, char **argv) {
   }
 }
 
-int main(int argc, char **argv) {
-#ifdef RTAI
-  // RT_TASK *task;
-#else
-  int *eNB_thread_status_p;
-  //  int *eNB_thread_status_rx[10],*eNB_thread_status_tx[10];
-#endif
+int main( int argc, char **argv )
+{
   int i,aa,card;
 #if defined (XFORMS) || defined (EMOS) || defined (EXMIMO)
   void *status;
@@ -2868,7 +2866,7 @@ int main(int argc, char **argv) {
 #ifdef RTAI
     main_eNB_thread = rt_thread_create(eNB_thread, NULL, PTHREAD_STACK_MIN);
 #else
-    error_code = pthread_create(&main_eNB_thread, &attr_dlsch_threads, eNB_thread, NULL);
+    error_code = pthread_create( &main_eNB_thread, &attr_dlsch_threads, eNB_thread, NULL );
     if (error_code!= 0) {
       LOG_D(HW,"[lte-softmodem.c] Could not allocate eNB_thread, error %d\n",error_code);
       return(error_code);
@@ -2958,11 +2956,20 @@ int main(int argc, char **argv) {
 #ifdef RTAI
     rt_thread_join(main_eNB_thread); 
 #else
-    pthread_join(main_eNB_thread,(void**)&eNB_thread_status_p); 
+    int *eNB_thread_status_p;
+    int result = pthread_join( main_eNB_thread, (void**)&eNB_thread_status_p );
 #ifdef DEBUG_THREADS
-    printf("status %d\n",*eNB_thread_status_p);
-#endif
-#endif
+    if (result != 0) {
+        printf( "\nError joining main_eNB_thread.\n" );
+    } else {
+        if (eNB_thread_status_p) {
+            printf( "status %d\n", *eNB_thread_status_p );
+        } else {
+            printf( "The thread was killed. No status available.\n");
+        }
+    }
+#endif // DEBUG_THREADS
+#endif // RTAI
 
     if (multi_thread>0) {
       printf("Killing eNB processing threads\n");