From 2ebc75b9a24adf084664700f7b3698fda76c322b Mon Sep 17 00:00:00 2001 From: Raymond Knopp <raymond.knopp@eurecom.fr> Date: Wed, 22 Jan 2020 15:09:32 +0100 Subject: [PATCH] fixes for the thread blocking problem --- common/utils/LOG/vcd_signal_dumper.c | 3 ++- common/utils/LOG/vcd_signal_dumper.h | 1 + common/utils/T/T_defs.h | 2 +- common/utils/T/T_messages.txt | 5 ++++ executables/nr-gnb.c | 13 ++++++++--- executables/nr-ru.c | 27 +++++++++++++++------- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 7 +++--- 7 files changed, 41 insertions(+), 17 deletions(-) diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c index 63c5336bd88..3597add1b5f 100644 --- a/common/utils/LOG/vcd_signal_dumper.c +++ b/common/utils/LOG/vcd_signal_dumper.c @@ -512,7 +512,8 @@ const char* eurecomFunctionsNames[] = { /*NR softmodem signal*/ "wakeup_txfh", "gNB_thread_rxtx0", - "gNB_thread_rxtx1" + "gNB_thread_rxtx1", + "ru_thread_tx_wait" }; struct vcd_module_s vcd_modules[] = { diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h index 3a6fb6d6abb..b9cc0e47422 100644 --- a/common/utils/LOG/vcd_signal_dumper.h +++ b/common/utils/LOG/vcd_signal_dumper.h @@ -505,6 +505,7 @@ typedef enum { VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, + VCD_SIGNAL_DUMPER_FUNCTIONS_RU_TX_WAIT, VCD_SIGNAL_DUMPER_FUNCTIONS_END } vcd_signal_dump_functions; diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index ab275d4d62d..344344710a1 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -73,7 +73,7 @@ typedef struct { } T_cache_t; /* number of VCD functions (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_FUNCTIONS (245) +#define VCD_NUM_FUNCTIONS (246) /* number of VCD variables (to be kept up to date! see in T_messages.txt) */ #define VCD_NUM_VARIABLES (186) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 407bb66be17..f9d92cc418f 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -3285,3 +3285,8 @@ ID = VCD_FUNCTION_gNB_PROC_RXTX1 GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value VCD_NAME = gNB_thread_rxtx1 +ID = VCD_FUNCTION_RU_TX_WAIT + DESC = VCD function RU_TX_WAIT + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = ru_thread_tx_wait diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 4196b8451d1..bea2bb47952 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -423,11 +423,16 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot // 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); - waitret=wait_on_condition(&proc->mutex_RUs_tx,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh"); - AssertFatal(release_thread(&proc->mutex_RUs_tx,&proc->instance_cnt_RUs,"wakeup_txfh")==0, "error releaseing gNB lock on RUs\n"); + AssertFatal((ret = pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret); + while (proc->instance_cnt_RUs < 0) { + pthread_cond_wait(&proc->cond_RUs,&proc->mutex_RUs_tx); // 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); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); + 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); @@ -465,6 +470,8 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot return(-1); } + AssertFatal((ret=pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"mutex_lock returned %d\n",ret); + ru_proc->instance_cnt_gNBs = 0; ru_proc->timestamp_tx = timestamp_tx; ru_proc->tti_tx = slot_tx; diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 168274bfa5d..ea3408f2f69 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -721,8 +721,9 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(slot), T_INT(0), T_BUFFER(&ru->common.txdata[0][slot * fp->samples_per_slot], fp->samples_per_slot * 4)); - int slot_type = nr_slot_select(cfg,frame,slot%((1<<cfg->ssb_config.scs_common.value)*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)); - int prevslot_type = nr_slot_select(cfg,frame,(slot+(((1<<cfg->ssb_config.scs_common.value)*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)-1))%((1<<cfg->ssb_config.scs_common.value)*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)); + int slot_type = nr_slot_select(cfg,frame,slot%fp->slots_per_frame); + int prevslot_type = nr_slot_select(cfg,frame,(slot+(fp->slots_per_frame-1))%fp->slots_per_frame); + int nextslot_type = nr_slot_select(cfg,frame,(slot+1)%fp->slots_per_frame); int sf_extension = 0; //sf_extension = ru->sf_extension; int siglen=fp->samples_per_slot; int flags=1; @@ -747,7 +748,14 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { prevslot_type == NR_UPLINK_SLOT) { flags = 2; // start of burst } - + + if (cfg->cell_config.frame_duplex_type.value == TDD && + slot_type == NR_DOWNLINK_SLOT && + nextslot_type == NR_UPLINK_SLOT) { + flags = 3; // end of burst + } + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS, flags ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot ); for (i=0; i<ru->nb_tx; i++) @@ -1262,7 +1270,10 @@ void *ru_thread_tx( void *param ) { 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); @@ -1355,14 +1366,14 @@ void *ru_thread_tx( void *param ) { 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) { + 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"); + } //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); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs); } } } @@ -1502,11 +1513,11 @@ void *ru_thread( void *param ) { // do RX front-end processing (frequency-shift, dft) if needed - if (proc->tti_rx == NR_UPLINK_SLOT || fp->frame_type == FDD) { + /*if (proc->tti_rx == NR_UPLINK_SLOT || fp->frame_type == FDD) { if (ru->feprx) ru->feprx(ru,proc->tti_rx); - } + }*/ LOG_D(PHY,"RU proc: frame_rx = %d, tti_rx = %d\n", proc->frame_rx, proc->tti_rx); LOG_D(PHY,"Copying rxdataF from RU to gNB\n"); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 73f51ed39a4..096e4674686 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -323,13 +323,12 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, NR_COMMON_channels_t *cc = RC.nrmac[module_idP]->common_channels; //nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = NULL; - start_meas(&RC.nrmac[module_idP]->eNB_scheduler); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN); - - // Check if there are downlink symbols in the slot, if not return, no scheduling opportunities if (is_nr_DL_slot(cc->ServingCellConfigCommon,slot_txP)==0) return; + start_meas(&RC.nrmac[module_idP]->eNB_scheduler); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN); + RC.nrmac[module_idP]->frame = frame_rxP; RC.nrmac[module_idP]->slot = slot_rxP; -- GitLab