From 23f5628735ef1332811a6e6b70958212dd047877 Mon Sep 17 00:00:00 2001
From: Wang Tsu-Han <wangts@eurecom.fr>
Date: Mon, 5 Mar 2018 11:20:51 +0100
Subject: [PATCH] changing into double sided signal for pipeline

---
 openair1/PHY/defs.h                         |  1 +
 openair2/LAYER2/MAC/eNB_scheduler_phytest.c |  3 +-
 targets/RT/USER/lte-enb.c                   | 69 ++++++++++++---------
 targets/RT/USER/lte-ru.c                    | 19 ++++--
 4 files changed, 56 insertions(+), 36 deletions(-)

diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index c140c3bcaa..e53513817d 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -456,6 +456,7 @@ typedef struct RU_proc_t_s {
   struct RU_proc_t_s           **slave_proc;
   /// pipeline ready state
   int ru_rx_ready;
+  int ru_tx_ready;
 } RU_proc_t;
 
 /// Context data structure for eNB subframe processing
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
index b2abcf8cb2..3245b9e8f0 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
@@ -216,10 +216,9 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s
   nfapi_hi_dci0_request_body_t   *hi_dci0_req = &eNB->HI_DCI0_req[CC_id].hi_dci0_request_body;
   nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu;
 
-  nfapi_ul_config_request_pdu_t  *ul_config_pdu;
+  //nfapi_ul_config_request_pdu_t  *ul_config_pdu = &ul_req->ul_config_pdu_list[0];;
   nfapi_ul_config_request_body_t *ul_req       = &eNB->UL_req[CC_id].ul_config_request_body;
 
-  ul_config_pdu                                    = &ul_req->ul_config_pdu_list[0]; 
 
   eNB->UL_req[CC_id].sfn_sf   = (sched_frame<<4) + sched_subframe;
   eNB->HI_DCI0_req[CC_id].sfn_sf = (frameP<<4)+subframeP;
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index d36f83b739..8b0609d428 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -183,12 +183,11 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
   pthread_mutex_unlock(&eNB->UL_INFO_mutex);
   
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 0 );
-  proc->pipe_ready = 1;
   if(get_nprocs() >= 8)
   {
     wakeup_tx(eNB,eNB->proc.ru_proc);
   }
-  else if(get_nprocs() > 4)
+  else if(get_nprocs() >= 4)
   {
     if(oai_exit) return(-1);
     phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
@@ -200,7 +199,6 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
     if(oai_exit) return(-1);
     phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
   }
-  proc->pipe_ready = 0;
 
   stop_meas( &softmodem_stats_rxtx_sf );
   
@@ -221,6 +219,15 @@ static void* tx_thread(void* param) {
   //wait_sync("tx_thread");
   
   while (!oai_exit) {
+    
+    pthread_mutex_lock( &proc->mutex_rxtx );
+    proc->pipe_ready++;
+    // the thread can now be woken up
+    if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
+      LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
+      exit_fun( "ERROR pthread_cond_signal" );
+    }
+    pthread_mutex_unlock( &proc->mutex_rxtx );
 
     if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
     if (oai_exit) break;    
@@ -237,9 +244,7 @@ static void* tx_thread(void* param) {
     phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
 	if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
 	
-    proc->pipe_ready = 1;
     wakeup_txfh(eNB,eNB_proc->ru_proc);
-    proc->pipe_ready = 0;
   }
 
   return 0;
@@ -279,7 +284,18 @@ static void* eNB_thread_rxtx( void* param ) {
   //wait_sync("eNB_thread_rxtx");
 
   while (!oai_exit) {
+    
+    pthread_mutex_lock( &proc->mutex_rxtx );
+    proc->pipe_ready++;
+    // the thread can now be woken up
+    if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
+      LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
+      exit_fun( "ERROR pthread_cond_signal" );
+    }
+    pthread_mutex_unlock( &proc->mutex_rxtx );
+    
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
+    T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
 
     if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
 
@@ -368,17 +384,16 @@ int wakeup_txfh(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc) {
   wait.tv_nsec=5000000L;
   eNB_proc_t *proc=&eNB->proc;
   eNB_rxtx_proc_t *proc_rxtx1=&proc->proc_rxtx[1];
-  eNB_rxtx_proc_t *proc_rxtx0=&proc->proc_rxtx[0];
+  //eNB_rxtx_proc_t *proc_rxtx0=&proc->proc_rxtx[0];
   
-  int ru_rx_ready = ru_proc->ru_rx_ready;
-  int pipe_ready_rx  = proc_rxtx0->pipe_ready;
-  int pipe_ready_tx  = proc_rxtx1->pipe_ready;
-  
-  while(!ru_rx_ready && !pipe_ready_rx && !pipe_ready_tx){
-    usleep(10);
+  if(wait_on_condition(&ru_proc->mutex_eNBs,&ru_proc->cond_eNBs,&ru_proc->ru_tx_ready,"wakeup_txfh")<0) {
+    LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", ru_proc->frame_tx, ru_proc->subframe_tx);
+    return(-1);
   }
+  if (release_thread(&ru_proc->mutex_eNBs,&ru_proc->ru_tx_ready,"wakeup_txfh")<0) return(-1);
+  
   if (ru_proc->instance_cnt_eNBs == 0) {
-    LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping\n",proc_rxtx1->frame_rx,proc_rxtx1->subframe_rx);
+    LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->subframe_tx, proc_rxtx1->frame_rx, proc_rxtx1->subframe_rx);
     return(-1);
   }
   if (pthread_mutex_timedlock(&ru_proc->mutex_eNBs,&wait) != 0) {
@@ -417,13 +432,14 @@ int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc) {
   wait.tv_sec=0;
   wait.tv_nsec=5000000L;
   
-  int ru_rx_ready = ru_proc->ru_rx_ready;
-  int pipe_ready_rx  = proc_rxtx0->pipe_ready;
   int pipe_ready_tx  = proc_rxtx1->pipe_ready;
   
-  while(!ru_rx_ready && !pipe_ready_rx && !pipe_ready_tx){
-    usleep(10);
+  if(wait_on_condition(&proc_rxtx1->mutex_rxtx,&proc_rxtx1->cond_rxtx,&proc_rxtx1->pipe_ready,"wakeup_tx")<0) {
+    LOG_E(PHY,"Frame %d, subframe %d: TX1 not ready\n",proc_rxtx1->frame_rx,proc_rxtx1->subframe_rx);
+    return(-1);
   }
+  if (release_thread(&proc_rxtx1->mutex_rxtx,&proc_rxtx1->pipe_ready,"wakeup_tx")<0)  return(-1);
+  
   if (proc_rxtx1->instance_cnt_rxtx == 0) {
     LOG_E(PHY,"Frame %d, subframe %d: TX1 thread busy, dropping\n",proc_rxtx1->frame_rx,proc_rxtx1->subframe_rx);
     return(-1);
@@ -493,17 +509,14 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
 
   wait.tv_sec=0;
   wait.tv_nsec=5000000L;
-  int ru_rx_ready = ru_proc->ru_rx_ready;
-  int pipe_ready_rx  = proc_rxtx0->pipe_ready;
-  int pipe_ready_tx  = proc_rxtx1->pipe_ready;
+
   
-  while(!ru_rx_ready && !pipe_ready_rx && !pipe_ready_tx){
-    usleep(10);
+  if(wait_on_condition(&proc_rxtx0->mutex_rxtx,&proc_rxtx0->cond_rxtx,&proc_rxtx0->pipe_ready,"wakeup_rxtx")<0) {
+    LOG_E(PHY,"Frame %d, subframe %d: RXTX0 not ready\n",proc_rxtx0->frame_rx,proc_rxtx0->subframe_rx);
+    return(-1);
   }
-  /* accept some delay in processing - up to 50us */
-  //if (proc_rxtx0->instance_cnt_rxtx == 0) {
-  //  usleep(50);
-  //}
+  if (release_thread(&proc_rxtx0->mutex_rxtx,&proc_rxtx0->pipe_ready,"wakeup_rxtx")<0) return(-1);
+  
   if (proc_rxtx0->instance_cnt_rxtx == 0) {
     LOG_E(PHY,"Frame %d, subframe %d: RXTX0 thread busy, dropping\n",proc_rxtx0->frame_rx,proc_rxtx0->subframe_rx);
     return(-1);
@@ -812,8 +825,8 @@ void init_eNB_proc(int inst) {
     proc_rxtx                      = proc->proc_rxtx;
     proc_rxtx[0].instance_cnt_rxtx = -1;
     proc_rxtx[1].instance_cnt_rxtx = -1;
-    proc_rxtx[0].pipe_ready        = 1;
-    proc_rxtx[1].pipe_ready        = 1;
+    proc_rxtx[0].pipe_ready        = 0;
+    proc_rxtx[1].pipe_ready        = 0;
     proc->instance_cnt_prach       = -1;
     proc->instance_cnt_asynch_rxtx = -1;
     proc->instance_cnt_synch       = -1;
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index 640f15ef7f..792cf4cc4d 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -1156,7 +1156,7 @@ void wakeup_eNBs(RU_t *ru) {
 
   LOG_D(PHY,"wakeup_eNBs (num %d) for RU %d\n",ru->num_eNB,ru->idx);
 
-  if (get_nprocs() <= 4) {
+  if (get_nprocs() < 4) {
     // call eNB function directly
   
     char string[20];
@@ -1440,8 +1440,16 @@ static void* ru_thread_tx( void* param ) {
   	      
       if (ru->fh_north_out) ru->fh_north_out(ru);
 	}
-
     release_thread(&proc->mutex_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx");
+    
+    pthread_mutex_lock( &proc->mutex_eNBs );
+    proc->ru_tx_ready++;
+    // the thread can now be woken up
+    if (pthread_cond_signal(&proc->cond_eNBs) != 0) {
+      LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
+      exit_fun( "ERROR pthread_cond_signal" );
+    }
+    pthread_mutex_unlock( &proc->mutex_eNBs );
   }
   release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx");
   return 0;
@@ -1596,12 +1604,10 @@ static void* ru_thread( void* param ) {
 
     LOG_D(PHY,"RU %d/%d frame_tx %d, subframe_tx %d\n",0,ru->idx,proc->frame_tx,proc->subframe_tx);
     // wakeup all eNB processes waiting for this RU
-    proc->ru_rx_ready = 1;
     if (ru->num_eNB>0) wakeup_eNBs(ru);
-    proc->ru_rx_ready = 0;
 
     
-	if(get_nprocs() <=4)
+	if(get_nprocs() <4)
 	{
       if(!emulate_rf){
         // do TX front-end processing if needed (precoding and/or IDFTs)
@@ -1754,7 +1760,8 @@ void init_RU_proc(RU_t *ru) {
   proc->frame_offset             = 0;
   proc->num_slaves               = 0;
   proc->frame_tx_unwrap          = 0;
-  proc->ru_rx_ready              = 1;
+  proc->ru_rx_ready              = 0;
+  proc->ru_tx_ready              = 0;
 
   for (i=0;i<10;i++) proc->symbol_mask[i]=0;
   
-- 
GitLab