Commit 0da8e5cc authored by magounak's avatar magounak

merge with L1_renaming (RU_mask_tx)

parent 872839d1
...@@ -894,13 +894,17 @@ typedef struct eNB_proc_t_s { ...@@ -894,13 +894,17 @@ typedef struct eNB_proc_t_s {
pthread_mutex_t mutex_asynch_rxtx; pthread_mutex_t mutex_asynch_rxtx;
/// mutex for RU access to eNB processing (PDSCH/PUSCH) /// mutex for RU access to eNB processing (PDSCH/PUSCH)
pthread_mutex_t mutex_RU; pthread_mutex_t mutex_RU;
/// mutex for eNB processing to access RU TX (PDSCH/PUSCH)
pthread_mutex_t mutex_RU_tx;
/// mutex for RU access to eNB processing (PRACH) /// mutex for RU access to eNB processing (PRACH)
pthread_mutex_t mutex_RU_PRACH; pthread_mutex_t mutex_RU_PRACH;
/// mutex for RU access to eNB processing (PRACH BR) /// mutex for RU access to eNB processing (PRACH BR)
pthread_mutex_t mutex_RU_PRACH_br; pthread_mutex_t mutex_RU_PRACH_br;
/// mask for RUs serving eNB (PDSCH/PUSCH) /// mask for RUs serving eNB (PDSCH/PUSCH)
int RU_mask[10]; int RU_mask[10];
/// time measurements for RU arrivals /// mask for RUs serving eNB (PDSCH/PUSCH)
int RU_mask_tx;
/// time measurements for RU arrivals
struct timespec t[10]; struct timespec t[10];
/// Timing statistics (RU_arrivals) /// Timing statistics (RU_arrivals)
time_stats_t ru_arrival_time; time_stats_t ru_arrival_time;
......
...@@ -155,7 +155,7 @@ extern double cpuf; ...@@ -155,7 +155,7 @@ extern double cpuf;
void init_eNB(int,int); void init_eNB(int,int);
void stop_eNB(int nb_inst); void stop_eNB(int nb_inst);
int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc); int wakeup_tx(PHY_VARS_eNB *eNB);
int wakeup_txfh(eNB_rxtx_proc_t *proc,PHY_VARS_eNB *eNB); int wakeup_txfh(eNB_rxtx_proc_t *proc,PHY_VARS_eNB *eNB);
void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
...@@ -395,7 +395,6 @@ LOG_I(PHY,"ENTERED L1_thread\n"); ...@@ -395,7 +395,6 @@ LOG_I(PHY,"ENTERED L1_thread\n");
PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id]; PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id];
//RU_proc_t *ru_proc = NULL;
char thread_name[100]; char thread_name[100];
...@@ -441,7 +440,7 @@ LOG_I(PHY,"ENTERED L1_thread\n"); ...@@ -441,7 +440,7 @@ LOG_I(PHY,"ENTERED L1_thread\n");
if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break; if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break;
if (nfapi_mode!=2){ if (nfapi_mode!=2){
if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(eNB,eNB->proc.ru_proc); if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(eNB);
else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT)
{ {
phy_procedures_eNB_TX(eNB, proc, 1); phy_procedures_eNB_TX(eNB, proc, 1);
...@@ -487,52 +486,59 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t ...@@ -487,52 +486,59 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t
int wakeup_txfh(eNB_rxtx_proc_t *proc,PHY_VARS_eNB *eNB) { int wakeup_txfh(eNB_rxtx_proc_t *proc,PHY_VARS_eNB *eNB) {
RU_proc_t *ru_proc; RU_proc_t *ru_proc;
struct timespec wait; struct timespec wait;
wait.tv_sec=0; wait.tv_sec=0;
wait.tv_nsec=5000000L; wait.tv_nsec=5000000L;
LTE_DL_FRAME_PARMS *fp; LTE_DL_FRAME_PARMS *fp;
LOG_I(PHY,"ENTERED wakeup_txfh\n"); LOG_I(PHY,"ENTERED wakeup_txfh\n");
for(int ru_id=0; ru_id<eNB->num_RU; ru_id++){
ru_proc = &eNB->RU_list[ru_id]->proc; printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~inside wakeup_txfh %d.%d IC_RU = %d\n", proc->frame_tx, proc->subframe_tx, proc->instance_cnt_RUs);
fp = &eNB->RU_list[ru_id]->frame_parms; if(wait_on_condition(&proc->mutex_RUs,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) {
if ((fp->frame_type == TDD) && (subframe_select(fp,proc->subframe_tx)==SF_UL)) continue; LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", proc->frame_tx, proc->subframe_tx);
// skip the RUs that are not synced
if (eNB->RU_list[ru_id]->state == RU_SYNC) { LOG_D(PHY,"wakeup_txfh: eNB %d : Skipping ru %d\n",eNB->Mod_id,ru_id); continue; }
if(ru_proc == NULL) {return(0);}
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~inside wakeup_txfh %d.%d IC_RU = %d\n", proc->frame_tx, proc->subframe_tx, proc->instance_cnt_RUs);
if(wait_on_condition(&proc->mutex_RUs,&proc->cond_RUs,&proc->instance_cnt_RUs,"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); return(-1);
} }
if (release_thread(&proc->mutex_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) return(-1); pthread_mutex_lock(&eNB->proc.mutex_RU_tx);
if (ru_proc->instance_cnt_eNBs == 0) { eNB->proc.RU_mask_tx = 0;
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->frame_rx, proc->subframe_rx); pthread_mutex_unlock(&eNB->proc.mutex_RU_tx);
return(-1); if (release_thread(&proc->mutex_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) return(-1);
}
if (pthread_mutex_timedlock(&ru_proc->mutex_eNBs,&wait) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->subframe_rx&1,ru_proc->instance_cnt_eNBs );
exit_fun( "error locking mutex_eNB" );
return(-1);
}
LOG_I(PHY,"waking up for frame %d subframe %d for RU TX \n", proc->frame_tx, proc->subframe_tx);
ru_proc->instance_cnt_eNBs = 0;
ru_proc->timestamp_tx = proc->timestamp_tx;
ru_proc->subframe_tx = proc->subframe_tx;
ru_proc->frame_tx = proc->frame_tx;
// the thread can now be woken up for(int ru_id=0; ru_id<eNB->num_RU; ru_id++){
if (pthread_cond_signal(&ru_proc->cond_eNBs) != 0) { ru_proc = &eNB->RU_list[ru_id]->proc;
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); fp = &eNB->RU_list[ru_id]->frame_parms;
exit_fun( "ERROR pthread_cond_signal" ); if ((fp->frame_type == TDD) && (subframe_select(fp,proc->subframe_tx)==SF_UL)) continue;
return(-1); // skip the RUs that are not synced
} if (eNB->RU_list[ru_id]->state == RU_SYNC) { LOG_D(PHY,"wakeup_txfh: eNB %d : Skipping ru %d\n",eNB->Mod_id,ru_id); continue; }
pthread_mutex_unlock( &ru_proc->mutex_eNBs );
if(ru_proc == NULL) {return(0);}
if (ru_proc->instance_cnt_eNBs == 0) {
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->frame_rx, proc->subframe_rx);
return(-1);
}
if (pthread_mutex_timedlock(&ru_proc->mutex_eNBs,&wait) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->subframe_rx&1,ru_proc->instance_cnt_eNBs );
exit_fun( "error locking mutex_eNB" );
return(-1);
}
ru_proc->instance_cnt_eNBs = 0;
ru_proc->timestamp_tx = proc->timestamp_tx;
ru_proc->subframe_tx = proc->subframe_tx;
ru_proc->frame_tx = proc->frame_tx;
// the thread can now be woken up
if (pthread_cond_signal(&ru_proc->cond_eNBs) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
exit_fun( "ERROR pthread_cond_signal" );
return(-1);
}
pthread_mutex_unlock( &ru_proc->mutex_eNBs );
} }
return(0); return(0);
} }
int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc) { int wakeup_tx(PHY_VARS_eNB *eNB) {
eNB_proc_t *proc=&eNB->proc; eNB_proc_t *proc=&eNB->proc;
/* LTE_DL_FRAME_PARMS *fp; /* LTE_DL_FRAME_PARMS *fp;
......
...@@ -1508,12 +1508,12 @@ static void* ru_thread_tx( void* param ) { ...@@ -1508,12 +1508,12 @@ static void* ru_thread_tx( void* param ) {
if (oai_exit) break; if (oai_exit) break;
LOG_D(PHY,"ru_thread_tx (ru %d): Waiting for TX processing\n",ru->idx); LOG_I(PHY,"ru_thread_tx (ru %d): Waiting for TX processing\n",ru->idx);
// wait until eNBs are finished subframe RX n and TX n+4 // wait until eNBs are finished subframe RX n and TX n+4
wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx"); wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx");
LOG_I(PHY,"ru_thread_tx (ru %d): Woken from condition\n",ru->idx); LOG_I(PHY,"ru_thread_tx (ru %d): Woken from condition\n",ru->idx);
if (oai_exit) break; if (oai_exit) break;
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~ru_thread_tx is waken up %d.%d having L1 %d\n", proc->frame_tx, proc->subframe_tx, ru->num_eNB); //printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~ru_thread_tx is waken up %d.%d having L1 %d\n", proc->frame_tx, proc->subframe_tx, ru->num_eNB);
// do TX front-end processing if needed (precoding and/or IDFTs) // do TX front-end processing if needed (precoding and/or IDFTs)
if (ru->feptx_prec) ru->feptx_prec(ru); if (ru->feptx_prec) ru->feptx_prec(ru);
...@@ -1533,16 +1533,35 @@ printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~ru_thread_tx is waken up %d.%d having L1 %d\ ...@@ -1533,16 +1533,35 @@ printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~ru_thread_tx is waken up %d.%d having L1 %d\
eNB = ru->eNB_list[i]; eNB = ru->eNB_list[i];
eNB_proc = &eNB->proc; eNB_proc = &eNB->proc;
L1_proc = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? &eNB_proc->L1_proc_tx : &eNB_proc->L1_proc; L1_proc = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? &eNB_proc->L1_proc_tx : &eNB_proc->L1_proc;
char *L1_proc_name = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? "L1_proc_tx" : "L1_proc"; char *L1_proc_name = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? "L1_proc_tx" : "L1_proc";
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~ru_thread_tx signaling to eNB_list[%d] with %s IC_RU %d\n", i, L1_proc_name, L1_proc->instance_cnt_RUs); pthread_mutex_lock(&eNB_proc->mutex_RU_tx);
pthread_mutex_lock( &L1_proc->mutex_RUs ); for (int j=0;j<eNB->num_RU;j++) {
L1_proc->instance_cnt_RUs = 0; if (ru == eNB->RU_list[j]) {
// the thread can now be woken up if ((eNB_proc->RU_mask_tx&(1<<j)) > 0)
if (pthread_cond_signal(&L1_proc->cond_RUs) != 0) { LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n",
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); eNB->Mod_id,eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,eNB->num_RU,eNB_proc->RU_mask_tx);
exit_fun( "ERROR pthread_cond_signal" ); eNB_proc->RU_mask_tx |= (1<<j);
}
}
if (eNB_proc->RU_mask_tx != (1<<eNB->num_RU)-1) { // not all RUs have provided their information so return
printf("~~~~~~~~~~~~~~~~~~~~~~(mask = %d)\n", eNB_proc->RU_mask_tx);
pthread_mutex_unlock(&eNB_proc->mutex_RU_tx);
}
else { // all RUs TX are finished so send the ready signal to eNB processing
printf("~~~~~~~~~~~~~~~~~~~~~~ready to send wakeup signal\n");
eNB_proc->RU_mask_tx = 0;
pthread_mutex_unlock(&eNB_proc->mutex_RU_tx);
pthread_mutex_lock( &L1_proc->mutex_RUs);
L1_proc->instance_cnt_RUs = 0;
printf("~~~~~~~~~~~~~~~~~~~~~~ru_thread_tx send signal to L1_thread_tx with (mask = %d)\n", eNB_proc->RU_mask_tx);
// 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 TXnp4 thread\n");
exit_fun( "ERROR pthread_cond_signal" );
}
pthread_mutex_unlock( &L1_proc->mutex_RUs );
} }
pthread_mutex_unlock( &L1_proc->mutex_RUs );
} }
} }
release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx"); release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx");
......
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