Commit 2ebc75b9 authored by Raymond Knopp's avatar Raymond Knopp

fixes for the thread blocking problem

parent 63866165
...@@ -512,7 +512,8 @@ const char* eurecomFunctionsNames[] = { ...@@ -512,7 +512,8 @@ const char* eurecomFunctionsNames[] = {
/*NR softmodem signal*/ /*NR softmodem signal*/
"wakeup_txfh", "wakeup_txfh",
"gNB_thread_rxtx0", "gNB_thread_rxtx0",
"gNB_thread_rxtx1" "gNB_thread_rxtx1",
"ru_thread_tx_wait"
}; };
struct vcd_module_s vcd_modules[] = { struct vcd_module_s vcd_modules[] = {
......
...@@ -505,6 +505,7 @@ typedef enum { ...@@ -505,6 +505,7 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH,
VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0,
VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1,
VCD_SIGNAL_DUMPER_FUNCTIONS_RU_TX_WAIT,
VCD_SIGNAL_DUMPER_FUNCTIONS_END VCD_SIGNAL_DUMPER_FUNCTIONS_END
} vcd_signal_dump_functions; } vcd_signal_dump_functions;
......
...@@ -73,7 +73,7 @@ typedef struct { ...@@ -73,7 +73,7 @@ typedef struct {
} T_cache_t; } T_cache_t;
/* number of VCD functions (to be kept up to date! see in T_messages.txt) */ /* 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) */ /* number of VCD variables (to be kept up to date! see in T_messages.txt) */
#define VCD_NUM_VARIABLES (186) #define VCD_NUM_VARIABLES (186)
......
...@@ -3285,3 +3285,8 @@ ID = VCD_FUNCTION_gNB_PROC_RXTX1 ...@@ -3285,3 +3285,8 @@ ID = VCD_FUNCTION_gNB_PROC_RXTX1
GROUP = ALL:VCD:ENB:VCD_FUNCTION GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value FORMAT = int,value
VCD_NAME = gNB_thread_rxtx1 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
...@@ -423,11 +423,16 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot ...@@ -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 // 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); 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((ret = pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret);
AssertFatal(release_thread(&proc->mutex_RUs_tx,&proc->instance_cnt_RUs,"wakeup_txfh")==0, "error releaseing gNB lock on RUs\n"); 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_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) { 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); 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 ...@@ -465,6 +470,8 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot
return(-1); 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->instance_cnt_gNBs = 0;
ru_proc->timestamp_tx = timestamp_tx; ru_proc->timestamp_tx = timestamp_tx;
ru_proc->tti_tx = slot_tx; ru_proc->tti_tx = slot_tx;
......
...@@ -721,8 +721,9 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { ...@@ -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(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)); 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 slot_type = nr_slot_select(cfg,frame,slot%fp->slots_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 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 sf_extension = 0; //sf_extension = ru->sf_extension;
int siglen=fp->samples_per_slot; int siglen=fp->samples_per_slot;
int flags=1; int flags=1;
...@@ -748,6 +749,13 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { ...@@ -748,6 +749,13 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
flags = 2; // start of burst 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_FRAME_NUMBER_TX0_RU, frame );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot );
for (i=0; i<ru->nb_tx; i++) for (i=0; i<ru->nb_tx; i++)
...@@ -1262,7 +1270,10 @@ void *ru_thread_tx( void *param ) { ...@@ -1262,7 +1270,10 @@ void *ru_thread_tx( void *param ) {
LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n"); LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n");
// wait until eNBs are finished subframe RX n and TX n+4 // 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"); 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); ret = pthread_mutex_lock(&proc->mutex_gNBs);
AssertFatal(ret == 0,"mutex_lock return %d\n",ret); AssertFatal(ret == 0,"mutex_lock return %d\n",ret);
...@@ -1355,14 +1366,14 @@ void *ru_thread_tx( void *param ) { ...@@ -1355,14 +1366,14 @@ void *ru_thread_tx( void *param ) {
ret = pthread_mutex_lock(&L1_proc->mutex_RUs_tx); ret = pthread_mutex_lock(&L1_proc->mutex_RUs_tx);
AssertFatal(ret == 0,"mutex_lock returns %d\n",ret); AssertFatal(ret == 0,"mutex_lock returns %d\n",ret);
// the thread can now be woken up // 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; 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, AssertFatal(pthread_cond_signal(&L1_proc->cond_RUs) == 0,
"ERROR pthread_cond_signal for gNB_L1_thread\n"); "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); ret = pthread_mutex_unlock(&L1_proc->mutex_RUs_tx);
AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret); 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 ) { ...@@ -1502,11 +1513,11 @@ void *ru_thread( void *param ) {
// do RX front-end processing (frequency-shift, dft) if needed // 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); 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,"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"); LOG_D(PHY,"Copying rxdataF from RU to gNB\n");
......
...@@ -323,13 +323,12 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, ...@@ -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; NR_COMMON_channels_t *cc = RC.nrmac[module_idP]->common_channels;
//nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = NULL; //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 // 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; 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]->frame = frame_rxP;
RC.nrmac[module_idP]->slot = slot_rxP; RC.nrmac[module_idP]->slot = slot_rxP;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment