diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 90a096285e..6ac889791f 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -145,7 +145,7 @@ void exit_fun(const char* s); void init_eNB(int,int); void stop_eNB(int nb_inst); - +int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc); void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); #ifdef Rel14 void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); @@ -169,9 +169,9 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam } // UE-specific RX processing for subframe n phy_procedures_eNB_uespec_RX(eNB, proc, no_relay ); - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 1 ); - + pthread_mutex_lock(&eNB->UL_INFO_mutex); eNB->UL_INFO.frame = proc->frame_rx; eNB->UL_INFO.subframe = proc->subframe_rx; @@ -179,23 +179,12 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam eNB->UL_INFO.CC_id = eNB->CC_id; eNB->if_inst->UL_indication(&eNB->UL_INFO); pthread_mutex_unlock(&eNB->UL_INFO_mutex); - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 0 ); - - // ***************************************** - // 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) - // ***************************************** - //if (wait_CCs(proc)<0) return(-1); - - - - if (oai_exit) return(-1); - - phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1); if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) return(-1); + + wakeup_tx(eNB,eNB->proc.ru_proc); stop_meas( &softmodem_stats_rxtx_sf ); @@ -203,6 +192,41 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam } +static void* tx_thread(void* param) { + + eNB_proc_t *eNB_proc = (eNB_proc_t*)param; + eNB_rxtx_proc_t *proc = &eNB_proc->proc_rxtx[1]; + PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id]; + + char thread_name[100]; + sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1); + thread_top_init(thread_name,1,850000L,1000000L,2000000L); + + while (!oai_exit) { + + if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break; + 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) + // ***************************************** + //if (wait_CCs(proc)<0) return(-1); + + + phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1); + if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break; + + + pthread_mutex_lock(&eNB_proc->ru_proc->mutex_eNBs); + ++eNB_proc->ru_proc->instance_cnt_eNBs; + pthread_cond_signal(&eNB_proc->ru_proc->cond_eNBs); + pthread_mutex_unlock(&eNB_proc->ru_proc->mutex_eNBs); + } + + return 0; +} + /*! * \brief The RX UE-specific and TX thread of eNB. * \param param is a \ref eNB_proc_t structure which contains the info what to process. @@ -251,12 +275,6 @@ static void* eNB_thread_rxtx( void* param ) { if (eNB->CC_id==0) if (rxtx(eNB,proc,thread_name) < 0) break; - pthread_mutex_lock(&eNB_proc->ru_proc->mutex_eNBs); - //printf("//////////////////////////////ru_proc->instance_cnt_eNBs == %d \n",ru_proc->instance_cnt_eNBs);////////////////////////********* - ++eNB_proc->ru_proc->instance_cnt_eNBs; - pthread_cond_signal(&eNB_proc->ru_proc->cond_eNBs); - pthread_mutex_unlock(&eNB_proc->ru_proc->mutex_eNBs); - //release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name); } // while !oai_exit VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); @@ -323,6 +341,46 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t } } +int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc) { + + eNB_proc_t *proc=&eNB->proc; + + eNB_rxtx_proc_t *proc_rxtx=&proc->proc_rxtx[1];//*proc_rxtx=&proc->proc_rxtx[proc->frame_rx&1]; + + LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; + + struct timespec wait; + wait.tv_sec=0; + wait.tv_nsec=5000000L; + + if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx,&wait) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx&1,proc_rxtx->instance_cnt_rxtx ); + exit_fun( "error locking mutex_rxtx" ); + return(-1); + } + + ++proc_rxtx->instance_cnt_rxtx; + + + proc_rxtx->subframe_rx = ru_proc->subframe_rx; + proc_rxtx->frame_rx = ru_proc->frame_rx; + proc_rxtx->subframe_tx = (ru_proc->subframe_rx+4)%10; + proc_rxtx->frame_tx = (ru_proc->subframe_rx>5) ? (1+ru_proc->frame_rx)&1023 : ru_proc->frame_rx; + proc->frame_tx = proc_rxtx->frame_tx; + proc->frame_rx = proc_rxtx->frame_rx; + proc_rxtx->timestamp_tx = ru_proc->timestamp_tx; + + // the thread can now be woken up + if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n"); + exit_fun( "ERROR pthread_cond_signal" ); + return(-1); + } + + pthread_mutex_unlock( &proc_rxtx->mutex_rxtx ); + + return(0); +} int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { @@ -707,6 +765,7 @@ void init_eNB_proc(int inst) { attr_td = &proc->attr_td; attr_te = &proc->attr_te; pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, proc ); + pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, tx_thread, proc); if (eNB->single_thread_flag==0) { pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] ); pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] );