Commit 8c1f9c9e authored by Raymond Knopp's avatar Raymond Knopp

modifications to synchronization between RU_TX and L1_TX (timed cond wait to drop slots)

tested on both 40 and 80 MHz channels
parent c3b3b39e
......@@ -1011,6 +1011,35 @@ static inline int wait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,
return(0);
}
static inline int timedwait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name,uint32_t time_ns) {
int rc;
int waitret=0;
if ((rc = pthread_mutex_lock(mutex)) != 0) {
LOG_E(PHY, "[SCHED][eNB] wait_on_condition(): error locking mutex for %s (%d %s, %p)\n",
name, rc, strerror(rc), (void *)mutex);
exit_fun("nothing to add");
return(-1);
}
struct timespec now,abstime;
while (*instance_cnt < 0) {
clock_gettime(CLOCK_REALTIME,&now);
// most of the time the thread is waiting here
// proc->instance_cnt_rxtx is -1
abstime.tv_sec=now.tv_sec;
abstime.tv_nsec = now.tv_nsec + time_ns;
if ((waitret = pthread_cond_timedwait(cond,mutex,&abstime))==ETIMEDOUT) break; // this unlocks mutex_rxtx while waiting and then locks it again
}
if (pthread_mutex_unlock(mutex) != 0) {
LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for %s\n",name);
exit_fun("nothing to add");
return(-1);
}
return(waitret);
}
static inline int wait_on_busy_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) {
int rc;
if ((rc = pthread_mutex_lock(mutex)) != 0) {
......
[*]
[*] GTKWave Analyzer v3.3.61 (w)1999-2014 BSI
[*] Wed May 1 00:14:54 2019
[*] Mon May 6 11:32:36 2019
[*]
[dumpfile] "/tmp/openair_dump_eNB.vcd"
[dumpfile_mtime] "Wed May 1 00:10:57 2019"
[dumpfile_size] 22152850
[dumpfile] "/tmp/openair_dump_gNB40.vcd"
[dumpfile_mtime] "Mon May 6 11:32:05 2019"
[dumpfile_size] 803075
[savefile] "/home/caracal/raymond/openairinterface5g/targets/RT/USER/gNB_usrp.gtkw"
[timestart] 11537525000
[size] 1859 841
[timestart] 10835824000
[size] 1920 859
[pos] -1 -1
*-19.848083 11540069031 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
*-19.848083 10838512202 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[sst_width] 386
[signals_width] 344
[sst_expanded] 1
[sst_vpaned_height] 421
[sst_vpaned_height] 197
@28
functions.trx_read
functions.trx_write
......@@ -30,8 +30,6 @@ variables.tti_number_TX0_RU[63:0]
@28
functions.mac_schedule_dlsch
functions.macxface_eNB_dlsch_ulsch_scheduler
functions.macxface_ue_scheduler
functions.phy_eNB_ofdm_mod_l
@24
variables.frame_number_RX0_gNB[63:0]
variables.slot_number_RX0_gNB[63:0]
......@@ -46,6 +44,13 @@ variables.frame_number_TX1_gNB[63:0]
variables.slot_number_TX1_gNB[63:0]
@28
functions.gNB_thread_rxtx1
functions.phy_enb_pdcch_tx
functions.phy_eNB_dlsch_encoding
functions.phy_eNB_dlsch_encoding_w
functions.generate_dlsch
@421
variables.frame_number_RX0_UE[63:0]
@28
functions.phy_procedures_ru_feprx0
functions.phy_procedures_ru_feprx1
functions.phy_procedures_ru_feptx_ofdm0
......
......@@ -248,7 +248,8 @@ static void* gNB_L1_thread_tx(void* param) {
while (!oai_exit) {
if (wait_on_condition(&L1_proc_tx->mutex,&L1_proc_tx->cond,&L1_proc_tx->instance_cnt,thread_name)<0) break;
while (L1_proc_tx->instance_cnt==-1)
if (wait_on_condition(&L1_proc_tx->mutex,&L1_proc_tx->cond,&L1_proc_tx->instance_cnt,thread_name)<0) break;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 1 );
if (oai_exit) break;
// *****************************************
......@@ -273,8 +274,8 @@ static void* gNB_L1_thread_tx(void* param) {
exit_fun( "ERROR pthread_cond_signal" );
}
pthread_mutex_unlock( &L1_proc_tx->mutex );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 );
wakeup_txfh(gNB,L1_proc_tx,frame_tx,slot_tx,timestamp_tx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 );
}
return 0;
......@@ -398,22 +399,31 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot
RU_t *ru;
RU_proc_t *ru_proc;
int waitret;
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
if(wait_on_condition(&proc->mutex_RUs_tx,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) {
LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", proc->frame_tx, proc->slot_tx);
return(-1);
}
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs);
// note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time
waitret=timedwait_on_condition(&proc->mutex_RUs_tx,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh",500000);
pthread_mutex_lock(&gNB->proc.mutex_RU_tx);
gNB->proc.RU_mask_tx = 0;
pthread_mutex_unlock(&gNB->proc.mutex_RU_tx);
if (release_thread(&proc->mutex_RUs_tx,&proc->instance_cnt_RUs,"wakeup_txfh")<0) return(-1);
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 because FH is blocked more than 2 slot times (1000us)\n");
pthread_mutex_lock(&gNB->proc.mutex_RU_tx);
gNB->proc.RU_mask_tx = 0;
pthread_mutex_unlock(&gNB->proc.mutex_RU_tx);
return(-1);
}
for(int i=0; i<gNB->num_RU; i++)
{
ru = gNB->RU_list[i];
......@@ -523,7 +533,7 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
/* accept some delay in processing - up to 5ms */
for (i = 0; i < fp->slots_per_frame && L1_proc->instance_cnt == 0; i++) {
LOG_W( PHY,"[gNB] SFN.SL %d.%d, gNB RXn-TXnp4 thread busy!! (i %d, cnt %i)\n", L1_proc->frame_tx, L1_proc->slot_tx, i,L1_proc->instance_cnt);
LOG_W( PHY,"[gNB] SFN.SL %d.%d, gNB L1 thread busy!! (i %d, cnt %i)\n", L1_proc->frame_tx, L1_proc->slot_tx, i,L1_proc->instance_cnt);
usleep(100);
}
if (L1_proc->instance_cnt == 0) {
......@@ -534,7 +544,7 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
// wake up TX for subframe n+sl_ahead
// lock the TX mutex and make sure the thread is ready
if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) {
LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB RXTX thread %d (IC %d)\n", L1_proc->slot_rx&1,L1_proc->instance_cnt );
LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB L1 thread %d (IC %d)\n", L1_proc->slot_rx&1,L1_proc->instance_cnt );
exit_fun( "error locking mutex" );
return(-1);
}
......
......@@ -791,7 +791,7 @@ void tx_rf(RU_t *ru) {
txp,
siglen+sf_extension,
ru->nb_tx,
flags);
4);//flags);
LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx,
(long long unsigned int)proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->tti_tx);
......@@ -1370,6 +1370,8 @@ static void* ru_thread_tx( void* param ) {
pthread_mutex_lock(&L1_proc->mutex_RUs_tx);
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);
// the thread can now be woken up
if (pthread_cond_signal(&L1_proc->cond_RUs) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB L1 TX thread\n");
......
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