Commit d7781f7a authored by S. Sandeep Kumar's avatar S. Sandeep Kumar

asthetic fixes for lte-enb.c

parent c5745c16
...@@ -108,10 +108,6 @@ unsigned short config_frames[4] = {2,9,11,13}; ...@@ -108,10 +108,6 @@ unsigned short config_frames[4] = {2,9,11,13};
# endif # endif
#endif #endif
//#define DEBUG_THREADS 1 //#define DEBUG_THREADS 1
//#define USRP_DEBUG 1 //#define USRP_DEBUG 1
...@@ -158,15 +154,14 @@ static struct { ...@@ -158,15 +154,14 @@ static struct {
volatile uint8_t phy_proc_CC_id; volatile uint8_t phy_proc_CC_id;
} sync_phy_proc; } sync_phy_proc;
void exit_fun(const char* s); void exit_fun(const char* s);
void init_eNB(eNB_func_t node_function); void init_eNB(eNB_func_t node_function);
void stop_eNB(void); void stop_eNB(void);
void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
{
void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) {
unsigned int aa,slot_offset, slot_offset_F; unsigned int aa,slot_offset, slot_offset_F;
int dummy_tx_b[7680*4] __attribute__((aligned(32))); int dummy_tx_b[7680*4] __attribute__((aligned(32)));
int i,j, tx_offset; int i,j, tx_offset;
...@@ -183,7 +178,6 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) ...@@ -183,7 +178,6 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
((subframe_select(&phy_vars_eNB->frame_parms,subframe)==SF_S))) { ((subframe_select(&phy_vars_eNB->frame_parms,subframe)==SF_S))) {
// LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot); // LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot);
for (aa=0; aa<phy_vars_eNB->frame_parms.nb_antennas_tx; aa++) { for (aa=0; aa<phy_vars_eNB->frame_parms.nb_antennas_tx; aa++) {
if (phy_vars_eNB->frame_parms.Ncp == EXTENDED) { if (phy_vars_eNB->frame_parms.Ncp == EXTENDED) {
PHY_ofdm_mod(&phy_vars_eNB->common_vars.txdataF[0][aa][slot_offset_F], PHY_ofdm_mod(&phy_vars_eNB->common_vars.txdataF[0][aa][slot_offset_F],
...@@ -204,7 +198,7 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) ...@@ -204,7 +198,7 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
7, 7,
&(phy_vars_eNB->frame_parms)); &(phy_vars_eNB->frame_parms));
// if S-subframe generate first slot only // if S-subframe generate first slot only
if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_DL) if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_DL)
normal_prefix_mod(&phy_vars_eNB->common_vars.txdataF[0][aa][slot_offset_F+slot_sizeF], normal_prefix_mod(&phy_vars_eNB->common_vars.txdataF[0][aa][slot_offset_F+slot_sizeF],
dummy_tx_b+(phy_vars_eNB->frame_parms.samples_per_tti>>1), dummy_tx_b+(phy_vars_eNB->frame_parms.samples_per_tti>>1),
7, 7,
...@@ -237,9 +231,8 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) ...@@ -237,9 +231,8 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
txdata[j++] = ((int16_t*)dummy_tx_b)[i]<<openair0_cfg[0].iq_txshift; txdata[j++] = ((int16_t*)dummy_tx_b)[i]<<openair0_cfg[0].iq_txshift;
} }
} }
} }
else if ((slot_offset+time_offset[aa]+len)>(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti)) { else if ((slot_offset+time_offset[aa]+len)>(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti)) {
tx_offset = (int)slot_offset+time_offset[aa]; tx_offset = (int)slot_offset+time_offset[aa];
txdata = (int16_t*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset]; txdata = (int16_t*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset];
len2 = -tx_offset+LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti; len2 = -tx_offset+LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti;
...@@ -260,7 +253,6 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) ...@@ -260,7 +253,6 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
} }
} }
// if S-subframe switch to RX in second subframe // if S-subframe switch to RX in second subframe
/* /*
if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_S) { if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_S) {
...@@ -270,34 +262,35 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) ...@@ -270,34 +262,35 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
} }
*/ */
if ((((phy_vars_eNB->frame_parms.tdd_config==0) || if ((((phy_vars_eNB->frame_parms.tdd_config==0) ||
(phy_vars_eNB->frame_parms.tdd_config==1) || (phy_vars_eNB->frame_parms.tdd_config==1) ||
(phy_vars_eNB->frame_parms.tdd_config==2) || (phy_vars_eNB->frame_parms.tdd_config==2) ||
(phy_vars_eNB->frame_parms.tdd_config==6)) && (phy_vars_eNB->frame_parms.tdd_config==6)) &&
(subframe==0)) || (subframe==5)) { (subframe==0)) || (subframe==5)) {
// turn on tx switch N_TA_offset before // turn on tx switch N_TA_offset before
//LOG_D(HW,"subframe %d, time to switch to tx (N_TA_offset %d, slot_offset %d) \n",subframe,phy_vars_eNB->N_TA_offset,slot_offset); //LOG_D(HW,"subframe %d, time to switch to tx (N_TA_offset %d, slot_offset %d) \n",subframe,phy_vars_eNB->N_TA_offset,slot_offset);
for (i=0; i<phy_vars_eNB->N_TA_offset; i++) { for (i=0; i<phy_vars_eNB->N_TA_offset; i++) {
tx_offset = (int)slot_offset+time_offset[aa]+i-phy_vars_eNB->N_TA_offset/2; tx_offset = (int)slot_offset+time_offset[aa]+i-phy_vars_eNB->N_TA_offset/2;
if (tx_offset<0) if (tx_offset<0)
tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti; tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti;
if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti)) if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti))
tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti; tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti;
phy_vars_eNB->common_vars.txdata[0][aa][tx_offset] = 0x00000000; phy_vars_eNB->common_vars.txdata[0][aa][tx_offset] = 0x00000000;
} }
} }
} }
} }
} }
/*! /*!
* \brief The RX UE-specific and TX thread of eNB. * \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. * \param param is a \ref eNB_proc_t structure which contains the info what to process.
* \returns a pointer to an int. The storage is not on the heap and must not be freed. * \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/ */
static void* eNB_thread_rxtx( void* param ) static void* eNB_thread_rxtx( void* param ) {
{
static int eNB_thread_rxtx_status; static int eNB_thread_rxtx_status;
eNB_rxtx_proc_t *proc = (eNB_rxtx_proc_t*)param; eNB_rxtx_proc_t *proc = (eNB_rxtx_proc_t*)param;
...@@ -365,56 +358,47 @@ static void* eNB_thread_rxtx( void* param ) ...@@ -365,56 +358,47 @@ static void* eNB_thread_rxtx( void* param )
#endif //CPU_AFFINITY #endif //CPU_AFFINITY
/* Check the actual affinity mask assigned to the thread */ /* Check the actual affinity mask assigned to the thread */
s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0) if (s != 0) {
{
perror( "pthread_getaffinity_np"); perror( "pthread_getaffinity_np");
exit_fun("Error getting processor affinity "); exit_fun("Error getting processor affinity ");
} }
memset(cpu_affinity,0,sizeof(cpu_affinity)); memset(cpu_affinity,0,sizeof(cpu_affinity));
for (j = 0; j < CPU_SETSIZE; j++) for (j = 0; j < CPU_SETSIZE; j++)
if (CPU_ISSET(j, &cpuset)) if (CPU_ISSET(j, &cpuset)) {
{ char temp[1024];
char temp[1024]; sprintf (temp, " CPU_%d", j);
sprintf (temp, " CPU_%d", j); strcat(cpu_affinity, temp);
strcat(cpu_affinity, temp); }
}
memset(&sparam, 0 , sizeof (sparam)); memset(&sparam, 0, sizeof(sparam));
sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1;
policy = SCHED_FIFO ; policy = SCHED_FIFO ;
s = pthread_setschedparam(pthread_self(), policy, &sparam); s = pthread_setschedparam(pthread_self(), policy, &sparam);
if (s != 0) if (s != 0) {
{ perror("pthread_setschedparam : ");
perror("pthread_setschedparam : "); exit_fun("Error setting thread priority");
exit_fun("Error setting thread priority"); }
}
s = pthread_getschedparam(pthread_self(), &policy, &sparam); s = pthread_getschedparam(pthread_self(), &policy, &sparam);
if (s != 0) if (s != 0) {
{ perror("pthread_getschedparam : ");
perror("pthread_getschedparam : "); exit_fun("Error getting thread priority");
exit_fun("Error getting thread priority"); }
}
LOG_I( HW, "[SCHED][eNB] TX thread started on CPU %d TID %ld, sched_policy = %s , priority = %d, CPU Affinity=%s \n",sched_getcpu(),gettid(), LOG_I(HW, "[SCHED][eNB] TX thread started on CPU %d TID %ld, sched_policy = %s , priority = %d, CPU Affinity=%s \n",sched_getcpu(),gettid(),
(policy == SCHED_FIFO) ? "SCHED_FIFO" : (policy == SCHED_FIFO) ? "SCHED_FIFO" :
(policy == SCHED_RR) ? "SCHED_RR" : (policy == SCHED_RR) ? "SCHED_RR" :
(policy == SCHED_OTHER) ? "SCHED_OTHER" : (policy == SCHED_OTHER) ? "SCHED_OTHER" :
"???", "???",
sparam.sched_priority, cpu_affinity ); sparam.sched_priority, cpu_affinity );
#endif //LOW_LATENCY #endif //LOW_LATENCY
mlockall(MCL_CURRENT | MCL_FUTURE); mlockall(MCL_CURRENT | MCL_FUTURE);
while (!oai_exit) { while (!oai_exit) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
...@@ -462,6 +446,7 @@ static void* eNB_thread_rxtx( void* param ) ...@@ -462,6 +446,7 @@ static void* eNB_thread_rxtx( void* param )
exit_fun("nothing to add"); exit_fun("nothing to add");
break; break;
} }
// wait for our turn or oai_exit // wait for our turn or oai_exit
while (sync_phy_proc.phy_proc_CC_id != proc->CC_id && !oai_exit) { while (sync_phy_proc.phy_proc_CC_id != proc->CC_id && !oai_exit) {
pthread_cond_wait(&sync_phy_proc.cond_phy_proc_tx, pthread_cond_wait(&sync_phy_proc.cond_phy_proc_tx,
...@@ -473,28 +458,27 @@ static void* eNB_thread_rxtx( void* param ) ...@@ -473,28 +458,27 @@ static void* eNB_thread_rxtx( void* param )
exit_fun("nothing to add"); exit_fun("nothing to add");
} }
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB, proc->frame_tx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB, proc->frame_tx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX_ENB, proc->subframe_tx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX_ENB, proc->subframe_tx );
if (oai_exit)
break; if (oai_exit) break;
if (PHY_vars_eNB_g[0][proc->CC_id]->node_function != NGFI_RRU_IF4) { if (PHY_vars_eNB_g[0][proc->CC_id]->node_function != NGFI_RRU_IF4) {
phy_procedures_eNB_TX(PHY_vars_eNB_g[0][proc->CC_id], proc, 0, no_relay, NULL ); phy_procedures_eNB_TX(PHY_vars_eNB_g[0][proc->CC_id], proc, 0, no_relay, NULL );
/* we're done, let the next one proceed */ /* we're done, let the next one proceed */
if (pthread_mutex_lock(&sync_phy_proc.mutex_phy_proc_tx) != 0) { if (pthread_mutex_lock(&sync_phy_proc.mutex_phy_proc_tx) != 0) {
LOG_E(PHY, "[SCHED][eNB] error locking PHY proc mutex for eNB TX proc\n"); LOG_E(PHY, "[SCHED][eNB] error locking PHY proc mutex for eNB TX proc\n");
exit_fun("nothing to add"); exit_fun("nothing to add");
break; break;
} }
sync_phy_proc.phy_proc_CC_id++; sync_phy_proc.phy_proc_CC_id++;
sync_phy_proc.phy_proc_CC_id %= MAX_NUM_CCs; sync_phy_proc.phy_proc_CC_id %= MAX_NUM_CCs;
pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
if (pthread_mutex_unlock(&sync_phy_proc.mutex_phy_proc_tx) != 0) { if (pthread_mutex_unlock(&sync_phy_proc.mutex_phy_proc_tx) != 0) {
LOG_E(PHY, "[SCHED][eNB] error unlocking PHY proc mutex for eNB TX proc\n"); LOG_E(PHY, "[SCHED][eNB] error unlocking PHY proc mutex for eNB TX proc\n");
exit_fun("nothing to add"); exit_fun("nothing to add");
break; break;
} }
} else { } else {
...@@ -504,53 +488,51 @@ static void* eNB_thread_rxtx( void* param ) ...@@ -504,53 +488,51 @@ static void* eNB_thread_rxtx( void* param )
} }
} }
// eNodeB_3GPP and RRU create txdata and write to RF device // eNodeB_3GPP and RRU create txdata and write to RF device
if (PHY_vars_eNB_g[0][proc->CC_id]->node_function != NGFI_RCC_IF4) { if (PHY_vars_eNB_g[0][proc->CC_id]->node_function != NGFI_RCC_IF4) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 1 );
do_OFDM_mod_rt( proc->subframe_tx, PHY_vars_eNB_g[0][proc->CC_id] ); do_OFDM_mod_rt( proc->subframe_tx, PHY_vars_eNB_g[0][proc->CC_id] );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 0 );
/*
short *txdata = (short*)&PHY_vars_eNB_g[0][proc->CC_id]->common_vars.txdata[0][0][proc->subframe_tx*PHY_vars_eNB_g[0][proc->CC_id]->frame_parms.samples_per_tti];
int i;
for (i=0;i<PHY_vars_eNB_g[0][proc->CC_id]->frame_parms.samples_per_tti*2;i+=8) {
txdata[i] = 2047;
txdata[i+1] = 0;
txdata[i+2] = 0;
txdata[i+3] = 2047;
txdata[i+4] = -2047;
txdata[i+5] = 0;
txdata[i+6] = 0;
txdata[i+7] = -2047; }
*/
// Transmit TX buffer based on timestamp from RX
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); /*
// prepare tx buffer pointers short *txdata = (short*)&PHY_vars_eNB_g[0][proc->CC_id]->common_vars.txdata[0][0][proc->subframe_tx*PHY_vars_eNB_g[0][proc->CC_id]->frame_parms.samples_per_tti];
int i; int i;
for (i=0; i<PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx; i++) for (i=0;i<PHY_vars_eNB_g[0][proc->CC_id]->frame_parms.samples_per_tti*2;i+=8) {
txp[i] = (void*)&PHY_vars_eNB_g[0][0]->common_vars.txdata[0][i][proc->subframe_tx*PHY_vars_eNB_g[0][0]->frame_parms.samples_per_tti]; txdata[i] = 2047;
// if symb_written < spp ==> error txdata[i+1] = 0;
PHY_vars_eNB_g[0][proc->CC_id]->rfdevice.trx_write_func(&PHY_vars_eNB_g[0][proc->CC_id]->rfdevice, txdata[i+2] = 0;
(proc->timestamp_tx-openair0_cfg[0].tx_sample_advance), txdata[i+3] = 2047;
txp, txdata[i+4] = -2047;
PHY_vars_eNB_g[0][0]->frame_parms.samples_per_tti, txdata[i+5] = 0;
PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx, txdata[i+6] = 0;
1); txdata[i+7] = -2047; }
*/
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_tx-openair0_cfg[0].tx_sample_advance)&0xffffffff ); // Transmit TX buffer based on timestamp from RX
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
// prepare tx buffer pointers
int i;
for (i=0; i<PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx; i++)
txp[i] = (void*)&PHY_vars_eNB_g[0][0]->common_vars.txdata[0][i][proc->subframe_tx*PHY_vars_eNB_g[0][0]->frame_parms.samples_per_tti];
// if symb_written < spp ==> error
PHY_vars_eNB_g[0][proc->CC_id]->rfdevice.trx_write_func(&PHY_vars_eNB_g[0][proc->CC_id]->rfdevice,
(proc->timestamp_tx-openair0_cfg[0].tx_sample_advance),
txp,
PHY_vars_eNB_g[0][0]->frame_parms.samples_per_tti,
PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx,
1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_tx-openair0_cfg[0].tx_sample_advance)&0xffffffff );
} else { // RCC sends the txdataF using send_IF4 function } else {
/// **** send_IF4 of txdataF to RRU **** ///
//send_IF4(PHY_vars_eNB_g[0][proc->CC_id], proc);
/// **** send_IF4 of txdataF to RRU **** /// }
//send_IF4(PHY_vars_eNB_g[0][proc->CC_id], proc);
}
if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB TX proc\n"); LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB TX proc\n");
...@@ -567,19 +549,18 @@ static void* eNB_thread_rxtx( void* param ) ...@@ -567,19 +549,18 @@ static void* eNB_thread_rxtx( void* param )
} }
stop_meas( &softmodem_stats_rxtx_sf ); stop_meas( &softmodem_stats_rxtx_sf );
#ifdef LOWLATENCY #ifdef LOWLATENCY
if (opp_enabled){ if (opp_enabled) {
if(softmodem_stats_rxtx_sf.diff_now/(cpuf) > attr.sched_runtime){ if(softmodem_stats_rxtx_sf.diff_now/(cpuf) > attr.sched_runtime) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_TX_ENB, (softmodem_stats_rxtx_sf.diff_now/cpuf - attr.sched_runtime)/1000000.0); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_TX_ENB, (softmodem_stats_rxtx_sf.diff_now/cpuf - attr.sched_runtime)/1000000.0);
} }
} }
#endif #endif
print_meas_now(&softmodem_stats_rxtx_sf,"eNB_TX_SF",tx_time_file);
print_meas_now(&softmodem_stats_rxtx_sf,"eNB_TX_SF",tx_time_file);
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
...@@ -591,13 +572,11 @@ static void* eNB_thread_rxtx( void* param ) ...@@ -591,13 +572,11 @@ static void* eNB_thread_rxtx( void* param )
} }
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
static void wait_system_ready (char *message, volatile int *start_flag) /* Wait for eNB application initialization to be complete (eNB registration to MME) */
static void wait_system_ready (char *message, volatile int *start_flag) {
/* Wait for eNB application initialization to be complete (eNB registration to MME) */
{
static char *indicator[] = {". ", ".. ", "... ", ".... ", ".....", static char *indicator[] = {". ", ".. ", "... ", ".... ", ".....",
" ....", " ...", " ..", " .", " " " ....", " ...", " ..", " .", " "};
};
int i = 0; int i = 0;
while ((!oai_exit) && (*start_flag == 0)) { while ((!oai_exit) && (*start_flag == 0)) {
...@@ -609,16 +588,16 @@ static void wait_system_ready (char *message, volatile int *start_flag) ...@@ -609,16 +588,16 @@ static void wait_system_ready (char *message, volatile int *start_flag)
LOG_D(EMU,"\n"); LOG_D(EMU,"\n");
} }
#endif #endif
/*! /*!
* \brief The RX common thread of eNB. * \brief The RX common thread of eNB.
* \param param is a \ref eNB_proc_t structure which contains the info what to process. * \param param is a \ref eNB_proc_t structure which contains the info what to process.
* \returns a pointer to an int. The storage is not on the heap and must not be freed. * \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/ */
static void* eNB_thread_rx_common( void* param ) static void* eNB_thread_rx_common( void* param ) {
{
static int eNB_thread_rx_status; static int eNB_thread_rx_status;
eNB_proc_t *proc = (eNB_proc_t*)param; eNB_proc_t *proc = (eNB_proc_t*)param;
...@@ -629,7 +608,7 @@ static void* eNB_thread_rx_common( void* param ) ...@@ -629,7 +608,7 @@ static void* eNB_thread_rx_common( void* param )
char rx_time_name[101]; char rx_time_name[101];
//int i; //int i;
if (opp_enabled == 1){ if (opp_enabled == 1) {
snprintf(rx_time_name, 100,"/tmp/%s_rx_time_thread_sf", "eNB"); snprintf(rx_time_name, 100,"/tmp/%s_rx_time_thread_sf", "eNB");
rx_time_file = fopen(rx_time_name,"w"); rx_time_file = fopen(rx_time_name,"w");
} }
...@@ -674,14 +653,12 @@ static void* eNB_thread_rx_common( void* param ) ...@@ -674,14 +653,12 @@ static void* eNB_thread_rx_common( void* param )
/* Set CPU Affinity only if number of CPUs >2 */ /* Set CPU Affinity only if number of CPUs >2 */
CPU_ZERO(&cpuset); CPU_ZERO(&cpuset);
#ifdef CPU_AFFINITY #ifdef CPU_AFFINITY
if (get_nprocs() >2) if (get_nprocs() >2) {
{
for (j = 1; j < get_nprocs(); j++) for (j = 1; j < get_nprocs(); j++)
CPU_SET(j, &cpuset); CPU_SET(j, &cpuset);
s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0) if (s != 0) {
{
perror( "pthread_setaffinity_np"); perror( "pthread_setaffinity_np");
exit_fun (" Error setting processor affinity :"); exit_fun (" Error setting processor affinity :");
} }
...@@ -690,66 +667,58 @@ static void* eNB_thread_rx_common( void* param ) ...@@ -690,66 +667,58 @@ static void* eNB_thread_rx_common( void* param )
/* Check the actual affinity mask assigned to the thread */ /* Check the actual affinity mask assigned to the thread */
s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0) if (s != 0) {
{ perror ("pthread_getaffinity_np");
perror ("pthread_getaffinity_np"); exit_fun (" Error getting processor affinity :");
exit_fun (" Error getting processor affinity :");
} }
memset(cpu_affinity,0, sizeof(cpu_affinity)); memset(cpu_affinity,0, sizeof(cpu_affinity));
for (j = 0; j < CPU_SETSIZE; j++) for (j = 0; j < CPU_SETSIZE; j++)
if (CPU_ISSET(j, &cpuset)) if (CPU_ISSET(j, &cpuset)) {
{ char temp[1024];
char temp[1024]; sprintf (temp, " CPU_%d", j);
sprintf (temp, " CPU_%d", j); strcat(cpu_affinity, temp);
strcat(cpu_affinity, temp); }
}
memset(&sparam, 0 , sizeof (sparam)); memset(&sparam, 0 , sizeof (sparam));
sparam.sched_priority = sched_get_priority_max(SCHED_FIFO); sparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
policy = SCHED_FIFO ; policy = SCHED_FIFO ;
s = pthread_setschedparam(pthread_self(), policy, &sparam); s = pthread_setschedparam(pthread_self(), policy, &sparam);
if (s != 0) if (s != 0) {
{ perror("pthread_setschedparam : ");
perror("pthread_setschedparam : "); exit_fun("Error setting thread priority");
exit_fun("Error setting thread priority"); }
}
memset(&sparam, 0 , sizeof (sparam)); memset(&sparam, 0 , sizeof (sparam));
s = pthread_getschedparam(pthread_self(), &policy, &sparam); s = pthread_getschedparam(pthread_self(), &policy, &sparam);
if (s != 0) if (s != 0) {
{ perror("pthread_getschedparam");
perror("pthread_getschedparam"); exit_fun("Error getting thread priority");
exit_fun("Error getting thread priority"); }
}
LOG_I( HW, "[SCHED][eNB] RX thread started on CPU %d TID %ld, sched_policy = %s, priority = %d, CPU Affinity = %s\n", sched_getcpu(),gettid(), LOG_I(HW, "[SCHED][eNB] RX thread started on CPU %d TID %ld, sched_policy = %s, priority = %d, CPU Affinity = %s\n", sched_getcpu(),gettid(),
(policy == SCHED_FIFO) ? "SCHED_FIFO" : (policy == SCHED_FIFO) ? "SCHED_FIFO" :
(policy == SCHED_RR) ? "SCHED_RR" : (policy == SCHED_RR) ? "SCHED_RR" :
(policy == SCHED_OTHER) ? "SCHED_OTHER" : (policy == SCHED_OTHER) ? "SCHED_OTHER" :
"???", "???",
sparam.sched_priority, cpu_affinity); sparam.sched_priority, cpu_affinity);
#endif // LOWLATENCY #endif // LOWLATENCY
mlockall(MCL_CURRENT | MCL_FUTURE); mlockall(MCL_CURRENT | MCL_FUTURE);
// wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe of TX and RX threads // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe of TX and RX threads
printf( "waiting for sync (eNB_thread_rx_common)\n"); printf( "waiting for sync (eNB_thread_rx_common)\n");
pthread_mutex_lock( &sync_mutex ); pthread_mutex_lock( &sync_mutex );
while (sync_var<0) while (sync_var<0)
pthread_cond_wait( &sync_cond, &sync_mutex ); pthread_cond_wait( &sync_cond, &sync_mutex );
pthread_mutex_unlock(&sync_mutex); pthread_mutex_unlock(&sync_mutex);
printf( "got sync (eNB_thread)\n" ); printf( "got sync (eNB_thread)\n" );
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB); wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
...@@ -767,96 +736,90 @@ static void* eNB_thread_rx_common( void* param ) ...@@ -767,96 +736,90 @@ static void* eNB_thread_rx_common( void* param )
LOG_E(HW,"Could not start the IF device\n"); LOG_E(HW,"Could not start the IF device\n");
} }
// This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
while (!oai_exit) { while (!oai_exit) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX, 0 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON, 0 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX, 0 ); start_meas( &softmodem_stats_rx_sf );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON, 0 );
start_meas( &softmodem_stats_rx_sf );
if (oai_exit) break; if (oai_exit) break;
if ((((fp->frame_type == TDD )&&(subframe_select(fp,proc->subframe_rx)==SF_UL)) || if ((((fp->frame_type == TDD )&&(subframe_select(fp,proc->subframe_rx)==SF_UL)) ||
(fp->frame_type == FDD))) { (fp->frame_type == FDD))) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON, 1 );
// this spawns the prach inside and updates the frame and subframe counters // this spawns the prach inside and updates the frame and subframe counters
phy_procedures_eNB_common_RX(eNB, 0); phy_procedures_eNB_common_RX(eNB, 0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON, 0 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON, 0 ); }
}
// choose even or odd thread for RXn-TXnp4 processing
// choose even or odd thread for RXn-TXnp4 processing eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[proc->subframe_rx&1];
eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[proc->subframe_rx&1];
// wake up TX for subframe n+4
// wake up TX for subframe n+4 // lock the TX mutex and make sure the thread is ready
// lock the TX mutex and make sure the thread is ready if (pthread_mutex_lock(&proc_rxtx->mutex_rxtx) != 0) {
if (pthread_mutex_lock(&proc_rxtx->mutex_rxtx) != 0) { LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n", proc_rxtx->instance_cnt_rxtx );
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n", proc_rxtx->instance_cnt_rxtx ); exit_fun( "error locking mutex_rxtx" );
exit_fun( "error locking mutex_rxtx" ); break;
break; }
} int cnt_rxtx = ++proc_rxtx->instance_cnt_rxtx;
int cnt_rxtx = ++proc_rxtx->instance_cnt_rxtx; // We have just received and processed the common part of a subframe, say n.
// We have just received and processed the common part of a subframe, say n. // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
// TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired // transmitted timestamp of the next TX slot (first).
// transmitted timestamp of the next TX slot (first). // The last (TS_rx mod samples_pexr_frame) was n*samples_per_tti,
// The last (TS_rx mod samples_pexr_frame) was n*samples_per_tti, // we want to generate subframe (n+3), so TS_tx = TX_rx+3*samples_per_tti,
// we want to generate subframe (n+3), so TS_tx = TX_rx+3*samples_per_tti, // and proc->subframe_tx = proc->subframe_rx+3
// and proc->subframe_tx = proc->subframe_rx+3 proc_rxtx->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti);
proc_rxtx->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti); proc_rxtx->frame_rx = proc->frame_rx;
proc_rxtx->frame_rx = proc->frame_rx; proc_rxtx->subframe_rx = proc->subframe_rx;
proc_rxtx->subframe_rx = proc->subframe_rx; proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > 5) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx;
proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > 5) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx; proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + 4)%10;
proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + 4)%10;
pthread_mutex_unlock( &proc_rxtx->mutex_rxtx ); pthread_mutex_unlock( &proc_rxtx->mutex_rxtx );
if (cnt_rxtx == 0){ if (cnt_rxtx == 0) {
// the thread was presumably waiting where it should and can now be woken up // the thread was presumably waiting where it should and can now be woken up
if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) { if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n"); LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n");
exit_fun( "ERROR pthread_cond_signal" ); exit_fun( "ERROR pthread_cond_signal" );
break; break;
} }
} else { } else {
LOG_W( PHY,"[eNB] Frame %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, cnt_rxtx ); LOG_W( PHY,"[eNB] Frame %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, cnt_rxtx );
exit_fun( "TX thread busy" ); exit_fun( "TX thread busy" );
break; break;
} }
stop_meas( &softmodem_stats_rxtx_sf ); stop_meas( &softmodem_stats_rxtx_sf );
#ifdef LOWLATENCY #ifdef LOWLATENCY
if (opp_enabled){ if (opp_enabled){
if(softmodem_stats_rxtx_sf.diff_now/(cpuf) > attr.sched_runtime){ if(softmodem_stats_rxtx_sf.diff_now/(cpuf) > attr.sched_runtime){
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_RXTX_ENB, (softmodem_stats_rxtx_sf.diff_now/cpuf - attr.sched_runtime)/1000000.0); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_RXTX_ENB, (softmodem_stats_rxtx_sf.diff_now/cpuf - attr.sched_runtime)/1000000.0);
} }
} }
#endif // LOWLATENCY #endif // LOWLATENCY
print_meas_now(&softmodem_stats_rx_sf,"eNB_RX_SF", rx_time_file);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
} print_meas_now(&softmodem_stats_rx_sf,"eNB_RX_SF", rx_time_file);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
}
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
printf( "Exiting eNB thread RXn-TXnp4\n"); printf( "Exiting eNB thread RXn-TXnp4\n");
#endif #endif
eNB_thread_rx_status = 0; eNB_thread_rx_status = 0;
return &eNB_thread_rx_status; return &eNB_thread_rx_status;
} }
/*! /*!
* \brief The prach receive thread of eNB. * \brief The prach receive thread of eNB.
* \param param is a \ref eNB_proc_t structure which contains the info what to process. * \param param is a \ref eNB_proc_t structure which contains the info what to process.
* \returns a pointer to an int. The storage is not on the heap and must not be freed. * \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/ */
static void* eNB_thread_prach( void* param ) static void* eNB_thread_prach( void* param ) {
{
static int eNB_thread_prach_status; static int eNB_thread_prach_status;
eNB_proc_t *proc = (eNB_proc_t*)param; eNB_proc_t *proc = (eNB_proc_t*)param;
...@@ -865,7 +828,6 @@ static void* eNB_thread_prach( void* param ) ...@@ -865,7 +828,6 @@ static void* eNB_thread_prach( void* param )
eNB_thread_prach_status = 0; eNB_thread_prach_status = 0;
MSC_START_USE(); MSC_START_USE();
#ifdef LOWLATENCY #ifdef LOWLATENCY
struct sched_attr attr; struct sched_attr attr;
...@@ -903,113 +865,102 @@ static void* eNB_thread_prach( void* param ) ...@@ -903,113 +865,102 @@ static void* eNB_thread_prach( void* param )
/* Set CPU Affinity only if number of CPUs >2 */ /* Set CPU Affinity only if number of CPUs >2 */
CPU_ZERO(&cpuset); CPU_ZERO(&cpuset);
#ifdef CPU_AFFINITY #ifdef CPU_AFFINITY
if (get_nprocs() >2) if (get_nprocs() >2) {
{
for (j = 1; j < get_nprocs(); j++) for (j = 1; j < get_nprocs(); j++)
CPU_SET(j, &cpuset); CPU_SET(j, &cpuset);
s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0) if (s != 0) {
{
perror( "pthread_setaffinity_np"); perror( "pthread_setaffinity_np");
exit_fun (" Error setting processor affinity :"); exit_fun (" Error setting processor affinity :");
} }
} }
#endif //CPU_AFFINITY #endif //CPU_AFFINITY
/* Check the actual affinity mask assigned to the thread */
/* Check the actual affinity mask assigned to the thread */
s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0) if (s != 0) {
{ perror ("pthread_getaffinity_np");
perror ("pthread_getaffinity_np"); exit_fun (" Error getting processor affinity :");
exit_fun (" Error getting processor affinity :");
} }
memset(cpu_affinity,0, sizeof(cpu_affinity)); memset(cpu_affinity,0, sizeof(cpu_affinity));
for (j = 0; j < CPU_SETSIZE; j++) for (j = 0; j < CPU_SETSIZE; j++)
if (CPU_ISSET(j, &cpuset)) if (CPU_ISSET(j, &cpuset)) {
{ char temp[1024];
char temp[1024]; sprintf (temp, " CPU_%d", j);
sprintf (temp, " CPU_%d", j); strcat(cpu_affinity, temp);
strcat(cpu_affinity, temp); }
}
memset(&sparam, 0 , sizeof (sparam)); memset(&sparam, 0 , sizeof (sparam));
sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-2; sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-2;
policy = SCHED_FIFO ; policy = SCHED_FIFO ;
s = pthread_setschedparam(pthread_self(), policy, &sparam); s = pthread_setschedparam(pthread_self(), policy, &sparam);
if (s != 0) if (s != 0) {
{ perror("pthread_setschedparam : ");
perror("pthread_setschedparam : "); exit_fun("Error setting thread priority");
exit_fun("Error setting thread priority"); }
}
memset(&sparam, 0 , sizeof (sparam)); memset(&sparam, 0 , sizeof (sparam));
s = pthread_getschedparam(pthread_self(), &policy, &sparam); s = pthread_getschedparam(pthread_self(), &policy, &sparam);
if (s != 0) if (s != 0) {
{ perror("pthread_getschedparam");
perror("pthread_getschedparam"); exit_fun("Error getting thread priority");
exit_fun("Error getting thread priority"); }
}
LOG_I( HW, "[SCHED][eNB] PRACH thread started on CPU %d TID %ld, sched_policy = %s, priority = %d, CPU Affinity = %s\n", sched_getcpu(),gettid(), LOG_I(HW, "[SCHED][eNB] PRACH thread started on CPU %d TID %ld, sched_policy = %s, priority = %d, CPU Affinity = %s\n", sched_getcpu(),gettid(),
(policy == SCHED_FIFO) ? "SCHED_FIFO" : (policy == SCHED_FIFO) ? "SCHED_FIFO" :
(policy == SCHED_RR) ? "SCHED_RR" : (policy == SCHED_RR) ? "SCHED_RR" :
(policy == SCHED_OTHER) ? "SCHED_OTHER" : (policy == SCHED_OTHER) ? "SCHED_OTHER" :
"???", "???",
sparam.sched_priority, cpu_affinity); sparam.sched_priority, cpu_affinity);
#endif // LOWLATENCY #endif // LOWLATENCY
mlockall(MCL_CURRENT | MCL_FUTURE); mlockall(MCL_CURRENT | MCL_FUTURE);
while (!oai_exit) { while (!oai_exit) {
if (oai_exit) break;
if (oai_exit) break;
if (pthread_mutex_lock(&proc->mutex_prach) != 0) { if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB PRACH\n"); LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB PRACH\n");
exit_fun( "error locking mutex" ); exit_fun( "error locking mutex" );
break; break;
} }
while (proc->instance_cnt_prach < 0) { while (proc->instance_cnt_prach < 0) {
// most of the time the thread is waiting here // most of the time the thread is waiting here
// proc->instance_cnt_prach is -1 // proc->instance_cnt_prach is -1
pthread_cond_wait( &proc->cond_prach, &proc->mutex_prach ); // this unlocks mutex_rxtx while waiting and then locks it again pthread_cond_wait( &proc->cond_prach, &proc->mutex_prach ); // this unlocks mutex_rxtx while waiting and then locks it again
} }
if (pthread_mutex_unlock(&proc->mutex_prach) != 0) { if (pthread_mutex_unlock(&proc->mutex_prach) != 0) {
LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for eNB PRACH\n"); LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for eNB PRACH\n");
exit_fun( "error unlocking mutex" ); exit_fun( "error unlocking mutex" );
break; break;
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1);
prach_procedures(eNB,0); prach_procedures(eNB,0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0);
if (pthread_mutex_lock(&proc->mutex_prach) != 0) { if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB PRACH proc %d\n"); LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB PRACH proc %d\n");
exit_fun( "error locking mutex" ); exit_fun( "error locking mutex" );
break; break;
} }
proc->instance_cnt_prach--;
if (pthread_mutex_unlock(&proc->mutex_prach) != 0) { proc->instance_cnt_prach--;
LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for eNB RX proc %d\n");
exit_fun( "error unlocking mutex" ); if (pthread_mutex_unlock(&proc->mutex_prach) != 0) {
break; LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for eNB RX proc %d\n");
} exit_fun( "error unlocking mutex" );
} break;
}
}
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
printf( "Exiting eNB thread PRACH\n"); printf( "Exiting eNB thread PRACH\n");
...@@ -1020,10 +971,8 @@ static void* eNB_thread_prach( void* param ) ...@@ -1020,10 +971,8 @@ static void* eNB_thread_prach( void* param )
} }
void init_eNB_proc(void) {
void init_eNB_proc(void)
{
int i; int i;
int CC_id; int CC_id;
PHY_VARS_eNB *eNB; PHY_VARS_eNB *eNB;
...@@ -1033,7 +982,6 @@ void init_eNB_proc(void) ...@@ -1033,7 +982,6 @@ void init_eNB_proc(void)
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
eNB = PHY_vars_eNB_g[0][CC_id]; eNB = PHY_vars_eNB_g[0][CC_id];
proc = &eNB->proc; proc = &eNB->proc;
proc_rxtx = proc->proc_rxtx; proc_rxtx = proc->proc_rxtx;
#ifndef LOWLATENCY #ifndef LOWLATENCY
...@@ -1097,7 +1045,6 @@ void init_eNB_proc(void) ...@@ -1097,7 +1045,6 @@ void init_eNB_proc(void)
pthread_setname_np( proc->pthread_rx, name ); pthread_setname_np( proc->pthread_rx, name );
} }
/* setup PHY proc TX sync mechanism */ /* setup PHY proc TX sync mechanism */
pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL); pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL);
pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL); pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL);
...@@ -1108,8 +1055,8 @@ void init_eNB_proc(void) ...@@ -1108,8 +1055,8 @@ void init_eNB_proc(void)
/*! /*!
* \brief Terminate eNB TX and RX threads. * \brief Terminate eNB TX and RX threads.
*/ */
void kill_eNB_proc(void) void kill_eNB_proc(void) {
{
int *status; int *status;
PHY_VARS_eNB *eNB; PHY_VARS_eNB *eNB;
eNB_proc_t *proc; eNB_proc_t *proc;
...@@ -1133,6 +1080,7 @@ void kill_eNB_proc(void) ...@@ -1133,6 +1080,7 @@ void kill_eNB_proc(void)
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
printf( "Joining eNB TX CC_id %d thread\n", CC_id); printf( "Joining eNB TX CC_id %d thread\n", CC_id);
#endif #endif
int result,i; int result,i;
for (i=0;i<1;i++) { for (i=0;i<1;i++) {
pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status ); pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status );
...@@ -1148,16 +1096,14 @@ void kill_eNB_proc(void) ...@@ -1148,16 +1096,14 @@ void kill_eNB_proc(void)
printf( "The thread was killed. No status available.\n" ); printf( "The thread was killed. No status available.\n" );
} }
} }
#else #else
UNUSED(result); UNUSED(result);
#endif #endif
pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx ); pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx );
pthread_cond_destroy( &proc_rxtx[i].cond_rxtx ); pthread_cond_destroy( &proc_rxtx[i].cond_rxtx );
} }
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
printf( "Killing RX CC_id %d thread\n", CC_id); printf( "Killing RX CC_id %d thread\n", CC_id);
#endif #endif
...@@ -1165,10 +1111,10 @@ void kill_eNB_proc(void) ...@@ -1165,10 +1111,10 @@ void kill_eNB_proc(void)
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
printf( "Joining eNB RX CC_id %d thread ...\n", CC_id); printf( "Joining eNB RX CC_id %d thread ...\n", CC_id);
#endif #endif
result = pthread_join( proc->pthread_rx, (void**)&status ); result = pthread_join( proc->pthread_rx, (void**)&status );
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
if (result != 0) { if (result != 0) {
printf( "Error joining thread.\n" ); printf( "Error joining thread.\n" );
} else { } else {
...@@ -1177,8 +1123,7 @@ void kill_eNB_proc(void) ...@@ -1177,8 +1123,7 @@ void kill_eNB_proc(void)
} else { } else {
printf( "The thread was killed. No status available.\n" ); printf( "The thread was killed. No status available.\n" );
} }
} }
#else #else
UNUSED(result); UNUSED(result);
#endif #endif
...@@ -1193,17 +1138,17 @@ void kill_eNB_proc(void) ...@@ -1193,17 +1138,17 @@ void kill_eNB_proc(void)
Each rf chain is is addressed by the card number and the chain on the card. The Each rf chain is is addressed by the card number and the chain on the card. The
rf_map specifies for each CC, on which rf chain the mapping should start. Multiple rf_map specifies for each CC, on which rf chain the mapping should start. Multiple
antennas are mapped to successive RF chains on the same card. */ antennas are mapped to successive RF chains on the same card. */
int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]) int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]) {
{
int i, CC_id; int i, CC_id;
#ifndef EXMIMO #ifndef EXMIMO
uint16_t N_TA_offset = 0; uint16_t N_TA_offset = 0;
#else #else
int j; int j;
#endif #endif
LTE_DL_FRAME_PARMS *frame_parms;
LTE_DL_FRAME_PARMS *frame_parms;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
if (phy_vars_eNB[CC_id]) { if (phy_vars_eNB[CC_id]) {
...@@ -1213,18 +1158,15 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c ...@@ -1213,18 +1158,15 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
printf("phy_vars_eNB[%d] not initialized\n", CC_id); printf("phy_vars_eNB[%d] not initialized\n", CC_id);
return(-1); return(-1);
} }
#ifndef EXMIMO #ifndef EXMIMO
if (frame_parms->frame_type == TDD) {
if (frame_parms->frame_type == TDD) { if (frame_parms->N_RB_DL == 100)
if (frame_parms->N_RB_DL == 100) N_TA_offset = 624;
N_TA_offset = 624; else if (frame_parms->N_RB_DL == 50)
else if (frame_parms->N_RB_DL == 50) N_TA_offset = 624/2;
N_TA_offset = 624/2; else if (frame_parms->N_RB_DL == 25)
else if (frame_parms->N_RB_DL == 25) N_TA_offset = 624/4;
N_TA_offset = 624/4; }
}
#endif #endif
// replace RX signal buffers with mmaped HW versions // replace RX signal buffers with mmaped HW versions
...@@ -1285,8 +1227,7 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c ...@@ -1285,8 +1227,7 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
rxdata[i] = (int32_t*)(32 + malloc16(32+openair0_cfg[rf_map[CC_id].card].samples_per_frame*sizeof(int32_t))); // FIXME broken memory allocation rxdata[i] = (int32_t*)(32 + malloc16(32+openair0_cfg[rf_map[CC_id].card].samples_per_frame*sizeof(int32_t))); // FIXME broken memory allocation
phy_vars_eNB[CC_id]->common_vars.rxdata[0][i] = rxdata[i]-N_TA_offset; // N_TA offset for TDD FIXME! N_TA_offset > 16 => access of unallocated memory phy_vars_eNB[CC_id]->common_vars.rxdata[0][i] = rxdata[i]-N_TA_offset; // N_TA offset for TDD FIXME! N_TA_offset > 16 => access of unallocated memory
memset(rxdata[i], 0, openair0_cfg[rf_map[CC_id].card].samples_per_frame*sizeof(int32_t)); memset(rxdata[i], 0, openair0_cfg[rf_map[CC_id].card].samples_per_frame*sizeof(int32_t));
printf("rxdata[%d] @ %p (%p) (N_TA_OFFSET %d)\n", i, phy_vars_eNB[CC_id]->common_vars.rxdata[0][i],rxdata[i],N_TA_offset); printf("rxdata[%d] @ %p (%p) (N_TA_OFFSET %d)\n", i, phy_vars_eNB[CC_id]->common_vars.rxdata[0][i],rxdata[i],N_TA_offset);
} }
for (i=0; i<frame_parms->nb_antennas_tx; i++) { for (i=0; i<frame_parms->nb_antennas_tx; i++) {
...@@ -1295,19 +1236,17 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c ...@@ -1295,19 +1236,17 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
phy_vars_eNB[CC_id]->common_vars.txdata[0][i] = txdata[i]; phy_vars_eNB[CC_id]->common_vars.txdata[0][i] = txdata[i];
memset(txdata[i],0, openair0_cfg[rf_map[CC_id].card].samples_per_frame*sizeof(int32_t)); memset(txdata[i],0, openair0_cfg[rf_map[CC_id].card].samples_per_frame*sizeof(int32_t));
printf("txdata[%d] @ %p\n", i, phy_vars_eNB[CC_id]->common_vars.txdata[0][i]); printf("txdata[%d] @ %p\n", i, phy_vars_eNB[CC_id]->common_vars.txdata[0][i]);
} }
#endif #endif
} }
return(0); return(0);
} }
void reset_opp_meas(void) { void reset_opp_meas(void) {
int sfn; int sfn;
reset_meas(&softmodem_stats_mt); reset_meas(&softmodem_stats_mt);
reset_meas(&softmodem_stats_hw); reset_meas(&softmodem_stats_hw);
...@@ -1318,6 +1257,7 @@ void reset_opp_meas(void) { ...@@ -1318,6 +1257,7 @@ void reset_opp_meas(void) {
} }
} }
void print_opp_meas(void) { void print_opp_meas(void) {
int sfn=0; int sfn=0;
...@@ -1333,7 +1273,6 @@ void print_opp_meas(void) { ...@@ -1333,7 +1273,6 @@ void print_opp_meas(void) {
void init_eNB(eNB_func_t node_function) { void init_eNB(eNB_func_t node_function) {
int CC_id; int CC_id;
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++)
...@@ -1363,11 +1302,11 @@ void stop_eNB() { ...@@ -1363,11 +1302,11 @@ void stop_eNB() {
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
printf("Joining eNB_thread ..."); printf("Joining eNB_thread ...");
#endif #endif
int *eNB_thread_status_p;
int result = pthread_join( main_eNB_thread, (void**)&eNB_thread_status_p ); int *eNB_thread_status_p;
int result = pthread_join( main_eNB_thread, (void**)&eNB_thread_status_p );
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
if (result != 0) { if (result != 0) {
printf( "\nError joining main_eNB_thread.\n" ); printf( "\nError joining main_eNB_thread.\n" );
} else { } else {
...@@ -1377,7 +1316,6 @@ void stop_eNB() { ...@@ -1377,7 +1316,6 @@ void stop_eNB() {
printf( "The thread was killed. No status available.\n"); printf( "The thread was killed. No status available.\n");
} }
} }
#else #else
UNUSED(result); UNUSED(result);
#endif // DEBUG_THREADS #endif // DEBUG_THREADS
......
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