Commit 6333fa20 authored by Lionel Gauthier's avatar Lionel Gauthier

Sebastian Held patches15/0011-cleanup-UE_thread-fix-data-races.patch

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7313 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent dd6acf0d
...@@ -195,7 +195,7 @@ static const eutra_band_t eutra_bands[] = { ...@@ -195,7 +195,7 @@ static const eutra_band_t eutra_bands[] = {
/*! /*!
* \brief This is the UE synchronize thread. * \brief This is the UE synchronize thread.
* It performs band scanning. * It performs band scanning and synchonization.
* \param arg is a pointer to a \ref PHY_VARS_UE structure. * \param arg is a pointer to a \ref PHY_VARS_UE structure.
* \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.
*/ */
...@@ -313,6 +313,7 @@ static void *UE_thread_synch(void *arg) ...@@ -313,6 +313,7 @@ static void *UE_thread_synch(void *arg)
} }
while (UE->instance_cnt_synch < 0) { while (UE->instance_cnt_synch < 0) {
// the thread waits here most of the time
pthread_cond_wait( &UE->cond_synch, &UE->mutex_synch ); pthread_cond_wait( &UE->cond_synch, &UE->mutex_synch );
} }
...@@ -473,6 +474,7 @@ static void *UE_thread_synch(void *arg) ...@@ -473,6 +474,7 @@ static void *UE_thread_synch(void *arg)
return &UE_thread_synch_retval; return &UE_thread_synch_retval;
} }
// indicate readiness
UE->instance_cnt_synch--; UE->instance_cnt_synch--;
if (pthread_mutex_unlock(&UE->mutex_synch) != 0) { if (pthread_mutex_unlock(&UE->mutex_synch) != 0) {
...@@ -795,42 +797,35 @@ static void *UE_thread_rx(void *arg) ...@@ -795,42 +797,35 @@ static void *UE_thread_rx(void *arg)
#define RX_OFF_MIN 5 #define RX_OFF_MIN 5
#define RX_OFF_MID ((RX_OFF_MAX+RX_OFF_MIN)/2) #define RX_OFF_MID ((RX_OFF_MAX+RX_OFF_MIN)/2)
/*!
* \brief This is the main UE thread.
* This thread controls the other three UE threads:
* - UE_thread_rx
* - UE_thread_tx
* - UE_thread_synch
* \param arg unused
* \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/
void *UE_thread(void *arg) void *UE_thread(void *arg)
{ {
UNUSED(arg)
PHY_VARS_UE *UE=PHY_vars_UE_g[0][0]; static int UE_thread_retval;
LTE_DL_FRAME_PARMS *frame_parms=&UE->lte_frame_parms; PHY_VARS_UE *UE = PHY_vars_UE_g[0][0];
int spp = openair0_cfg[0].samples_per_packet; int spp = openair0_cfg[0].samples_per_packet;
int slot=1, frame=0, hw_subframe=0, rxpos=0, txpos=0;
int slot=1,frame=0,hw_subframe=0,rxpos=0,txpos=0;
// unsigned int aa;
int dummy[2][spp]; int dummy[2][spp];
int dummy_dump = 0; int dummy_dump = 0;
int tx_enabled=0; int tx_enabled = 0;
int start_rx_stream=0; int start_rx_stream = 0;
int rx_off_diff = 0; int rx_off_diff = 0;
int rx_correction_timer = 0; int rx_correction_timer = 0;
int i; int first_rx = 0;
int first_rx=0;
RTIME T0; RTIME T0;
#ifdef RTAI
RT_TASK *task;
#endif
unsigned int rxs;
void *rxp[2],*txp[2];
openair0_timestamp timestamp; openair0_timestamp timestamp;
#ifdef LOWLATENCY
struct sched_attr attr;
unsigned int flags = 0;
#endif
#ifdef RTAI #ifdef RTAI
task = rt_task_init_schmod(nam2num("UE thread"), 0, 0, 0, SCHED_FIFO, 0xF); RT_TASK *task = rt_task_init_schmod(nam2num("UE thread"), 0, 0, 0, SCHED_FIFO, 0xF);
if (task==NULL) { if (task==NULL) {
LOG_E(PHY,"[SCHED][UE] Problem starting UE thread!!!!\n"); LOG_E(PHY,"[SCHED][UE] Problem starting UE thread!!!!\n");
...@@ -840,6 +835,9 @@ void *UE_thread(void *arg) ...@@ -840,6 +835,9 @@ void *UE_thread(void *arg)
#else #else
#ifdef LOWLATENCY #ifdef LOWLATENCY
struct sched_attr attr;
unsigned int flags = 0;
attr.size = sizeof(attr); attr.size = sizeof(attr);
attr.sched_flags = 0; attr.sched_flags = 0;
attr.sched_nice = 0; attr.sched_nice = 0;
...@@ -851,22 +849,19 @@ void *UE_thread(void *arg) ...@@ -851,22 +849,19 @@ void *UE_thread(void *arg)
attr.sched_deadline = 0.25 * 1000000; attr.sched_deadline = 0.25 * 1000000;
attr.sched_period = 0.5 * 1000000; attr.sched_period = 0.5 * 1000000;
// pin the UE main thread to CPU0
// if (pthread_setaffinity_np(pthread_self(), sizeof(mask),&mask) <0) {
// perror("[MAIN_ENB_THREAD] pthread_setaffinity_np failed\n");
// }
if (sched_setattr(0, &attr, flags) < 0 ) { if (sched_setattr(0, &attr, flags) < 0 ) {
perror("[SCHED] main eNB thread: sched_setattr failed\n"); perror("[SCHED] main eNB thread: sched_setattr failed\n");
exit_fun("Nothing to add"); exit_fun("Nothing to add");
} else { return &UE_thread_retval;
LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %ld started on CPU %d\n",
gettid(),sched_getcpu());
} }
LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %lu started on CPU %d\n",
(unsigned long)gettid(), sched_getcpu());
#endif #endif
#endif #endif
// Lock memory from swapping. This is a process wide call (not constraint to this thread).
mlockall(MCL_CURRENT | MCL_FUTURE); mlockall(MCL_CURRENT | MCL_FUTURE);
printf("waiting for sync (UE_thread)\n"); printf("waiting for sync (UE_thread)\n");
...@@ -881,43 +876,45 @@ void *UE_thread(void *arg) ...@@ -881,43 +876,45 @@ void *UE_thread(void *arg)
printf("starting UE thread\n"); printf("starting UE thread\n");
T0 = rt_get_time_ns(); T0 = rt_get_time_ns();
first_rx = 1; first_rx = 1;
rxpos=0; rxpos=0;
while (!oai_exit) { while (!oai_exit) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME, hw_subframe); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME, hw_subframe );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, frame); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, frame );
while (rxpos < (1+hw_subframe)*UE->lte_frame_parms.samples_per_tti) { while (rxpos < (1+hw_subframe)*UE->lte_frame_parms.samples_per_tti) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
#ifndef USRP_DEBUG #ifndef USRP_DEBUG
for (i=0; i<UE->lte_frame_parms.nb_antennas_rx; i++) DevAssert( UE->lte_frame_parms.nb_antennas_rx <= 2 );
void* rxp[2];
for (int i=0; i<UE->lte_frame_parms.nb_antennas_rx; i++)
rxp[i] = (dummy_dump==0) ? (void*)&rxdata[i][rxpos] : (void*)dummy[i]; rxp[i] = (dummy_dump==0) ? (void*)&rxdata[i][rxpos] : (void*)dummy[i];
rxs = openair0.trx_read_func(&openair0, unsigned int rxs = openair0.trx_read_func(&openair0,
&timestamp, &timestamp,
rxp, rxp,
spp - ((first_rx==1) ? rx_off_diff : 0), spp - ((first_rx==1) ? rx_off_diff : 0),
UE->lte_frame_parms.nb_antennas_rx); UE->lte_frame_parms.nb_antennas_rx);
if (rxs != (spp- ((first_rx==1) ? rx_off_diff : 0))) if (rxs != (spp- ((first_rx==1) ? rx_off_diff : 0))) {
exit_fun("problem in rx"); exit_fun("problem in rx");
return &UE_thread_retval;
}
rx_off_diff = 0; rx_off_diff = 0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
// Transmit TX buffer based on timestamp from RX // Transmit TX buffer based on timestamp from RX
if (tx_enabled) { if (tx_enabled) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
for (i=0; i<UE->lte_frame_parms.nb_antennas_tx; i++) DevAssert( UE->lte_frame_parms.nb_antennas_tx <= 2 );
void* txp[2];
for (int i=0; i<UE->lte_frame_parms.nb_antennas_tx; i++)
txp[i] = (void*)&txdata[i][txpos]; txp[i] = (void*)&txdata[i][txpos];
openair0.trx_write_func(&openair0, openair0.trx_write_func(&openair0,
...@@ -927,115 +924,134 @@ void *UE_thread(void *arg) ...@@ -927,115 +924,134 @@ void *UE_thread(void *arg)
UE->lte_frame_parms.nb_antennas_tx, UE->lte_frame_parms.nb_antennas_tx,
1); 1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
} }
#else #else
// define USRP_DEBUG is active
rt_sleep_ns(1000000); rt_sleep_ns(1000000);
#endif #endif
rxpos+=spp;
txpos+=spp;
if(txpos >= 10*PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti) rxpos += spp;
txpos += spp;
if (txpos >= 10*PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti)
txpos -= 10*PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti; txpos -= 10*PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti;
} }
if(rxpos >= 10*PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti) if (rxpos >= 10*PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti)
rxpos -= 10*PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti; rxpos -= 10*PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti;
if (UE->is_synchronized==1) { if (UE->is_synchronized == 1) {
LOG_D(HW,"UE_thread: hw_frame %d, hw_subframe %d (time %llu)\n",frame,hw_subframe,rt_get_time_ns()-T0); LOG_D( HW, "UE_thread: hw_frame %d, hw_subframe %d (time %lli)\n", frame, hw_subframe, rt_get_time_ns()-T0 );
if (start_rx_stream==1) { if (start_rx_stream == 1) {
// printf("UE_thread: locking UE mutex_rx\n");
if (pthread_mutex_lock(&UE->mutex_rx) != 0) { if (pthread_mutex_lock(&UE->mutex_rx) != 0) {
LOG_E(PHY,"[SCHED][UE] error locking mutex for UE RX thread\n"); LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RX thread\n" );
exit_fun("nothing to add"); exit_fun("nothing to add");
} else { return &UE_thread_retval;
}
UE->instance_cnt_rx++; int instance_cnt_rx = ++UE->instance_cnt_rx;
// printf("UE_thread: Unlocking UE mutex_rx\n");
pthread_mutex_unlock(&UE->mutex_rx);
if (UE->instance_cnt_rx == 0) { if (pthread_mutex_unlock(&UE->mutex_rx) != 0) {
// LOG_D(HW,"Scheduling UE RX for frame %d (hw frame %d), subframe %d (%d), mode %d\n",UE->frame_rx,frame,hw_subframe,UE->slot_rx>>1,mode); LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RX thread\n" );
if (pthread_cond_signal(&UE->cond_rx) != 0) { exit_fun("nothing to add");
LOG_E(PHY,"[SCHED][UE] ERROR pthread_cond_signal for UE RX thread\n"); return &UE_thread_retval;
exit_fun("nothing to add"); }
} else {
// printf("UE_thread: cond_signal for RX ok (%p) @ %llu\n",(void*)&UE->cond_rx,rt_get_time_ns()-T0);
}
if (UE->mode == rx_calib_ue) { if (instance_cnt_rx == 0) {
if (frame == 10) { if (pthread_cond_signal(&UE->cond_rx) != 0) {
LOG_D(PHY, LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE RX thread\n" );
"[SCHED][UE] Found cell with N_RB_DL %d, PHICH CONFIG (%d,%d), Nid_cell %d, NB_ANTENNAS_TX %d, initial frequency offset %d Hz, frequency offset %d Hz, RSSI (digital) %d dB, measured Gain %d dB, total_rx_gain %d dB, USRP rx gain %f dB\n", exit_fun("nothing to add");
UE->lte_frame_parms.N_RB_DL, return &UE_thread_retval;
UE->lte_frame_parms.phich_config_common.phich_duration, }
UE->lte_frame_parms.phich_config_common.phich_resource,
UE->lte_frame_parms.Nid_cell, if (UE->mode == rx_calib_ue) {
UE->lte_frame_parms.nb_antennas_tx_eNB, if (frame == 10) {
openair_daq_vars.freq_offset, LOG_D(PHY,
UE->lte_ue_common_vars.freq_offset, "[SCHED][UE] Found cell with N_RB_DL %"PRIu8", PHICH CONFIG (%d,%d), Nid_cell %"PRIu16", NB_ANTENNAS_TX %"PRIu8", initial frequency offset %"PRIi32" Hz, frequency offset "PRIi32" Hz, RSSI (digital) %hu dB, measured Gain %d dB, total_rx_gain %"PRIu32" dB, USRP rx gain %f dB\n",
UE->PHY_measurements.rx_power_avg_dB[0], UE->lte_frame_parms.N_RB_DL,
UE->PHY_measurements.rx_power_avg_dB[0] - rx_input_level_dBm, UE->lte_frame_parms.phich_config_common.phich_duration,
UE->rx_total_gain_dB, UE->lte_frame_parms.phich_config_common.phich_resource,
openair0_cfg[0].rx_gain[0] UE->lte_frame_parms.Nid_cell,
UE->lte_frame_parms.nb_antennas_tx_eNB,
openair_daq_vars.freq_offset,
UE->lte_ue_common_vars.freq_offset,
UE->PHY_measurements.rx_power_avg_dB[0],
UE->PHY_measurements.rx_power_avg_dB[0] - rx_input_level_dBm,
UE->rx_total_gain_dB,
openair0_cfg[0].rx_gain[0]
); );
exit_fun("[HW][UE] UE in RX calibration mode, exiting"); exit_fun("[HW][UE] UE in RX calibration mode, exiting");
} return &UE_thread_retval;
} }
} else {
LOG_E(PHY,"[SCHED][UE] UE RX thread busy!!\n");
exit_fun("nothing to add");
} }
} else {
LOG_E( PHY, "[SCHED][UE] UE RX thread busy!!\n" );
exit_fun("nothing to add");
return &UE_thread_retval;
} }
if (pthread_mutex_lock(&UE->mutex_tx) != 0) { if (pthread_mutex_lock(&UE->mutex_tx) != 0) {
LOG_E(PHY,"[SCHED][UE] error locking mutex for UE TX thread\n"); LOG_E( PHY, "[SCHED][UE] error locking mutex for UE TX thread\n" );
exit_fun("nothing to add"); exit_fun("nothing to add");
} else { return &UE_thread_retval;
}
if (tx_enabled == 1) { if (tx_enabled) {
UE->instance_cnt_tx++; int instance_cnt_tx = ++UE->instance_cnt_tx;
//printf("UE_thread: Unlocking UE mutex_rx\n");
pthread_mutex_unlock(&UE->mutex_tx); if (pthread_mutex_unlock(&UE->mutex_tx) != 0) {
LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE TX thread\n" );
if (UE->instance_cnt_tx == 0) { exit_fun("nothing to add");
if (pthread_cond_signal(&UE->cond_tx) != 0) { return &UE_thread_retval;
LOG_E(PHY,"[SCHED][UE] ERROR pthread_cond_signal for UE TX thread\n"); }
exit_fun("nothing to add");
} else { if (instance_cnt_tx == 0) {
// printf("UE_thread: cond_signal for RX ok (%p) @ %llu\n",(void*)&UE->cond_rx,rt_get_time_ns()-T0); if (pthread_cond_signal(&UE->cond_tx) != 0) {
} LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE TX thread\n" );
} else {
LOG_E(PHY,"[SCHED][UE] UE TX thread busy!!\n");
exit_fun("nothing to add"); exit_fun("nothing to add");
return &UE_thread_retval;
} }
} else {
LOG_E( PHY, "[SCHED][UE] UE TX thread busy!!\n" );
exit_fun("nothing to add");
return &UE_thread_retval;
} }
} }
} }
} else { // we are not yet synchronized } else {
if ((hw_subframe == 9)&&(dummy_dump == 0)) { // we are not yet synchronized
if ((hw_subframe == 9) && (dummy_dump == 0)) {
// Wake up initial synch thread // Wake up initial synch thread
if (pthread_mutex_lock(&UE->mutex_synch) != 0) { if (pthread_mutex_lock(&UE->mutex_synch) != 0) {
LOG_E(PHY,"[SCHED][UE] error locking mutex for UE initial synch thread\n"); LOG_E( PHY, "[SCHED][UE] error locking mutex for UE initial synch thread\n" );
exit_fun("nothing to add"); exit_fun("nothing to add");
} else { return &UE_thread_retval;
}
UE->instance_cnt_synch++; int instance_cnt_synch = ++UE->instance_cnt_synch;
pthread_mutex_unlock(&UE->mutex_synch);
dummy_dump = 1;
if (UE->instance_cnt_synch == 0) { if (pthread_mutex_unlock(&UE->mutex_synch) != 0) {
if (pthread_cond_signal(&UE->cond_synch) != 0) { LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE initial synch thread\n" );
LOG_E(PHY,"[SCHED][UE] ERROR pthread_cond_signal for UE sync thread\n"); exit_fun("nothing to add");
exit_fun("nothing to add"); return &UE_thread_retval;
} }
} else {
LOG_E(PHY,"[SCHED][UE] UE sync thread busy!!\n"); dummy_dump = 1;
if (instance_cnt_synch == 0) {
if (pthread_cond_signal(&UE->cond_synch) != 0) {
LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE sync thread\n" );
exit_fun("nothing to add"); exit_fun("nothing to add");
return &UE_thread_retval;
} }
} else {
LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" );
exit_fun("nothing to add");
return &UE_thread_retval;
} }
} }
} }
...@@ -1043,47 +1059,53 @@ void *UE_thread(void *arg) ...@@ -1043,47 +1059,53 @@ void *UE_thread(void *arg)
hw_subframe++; hw_subframe++;
slot+=2; slot+=2;
if(hw_subframe==10) { if (hw_subframe==10) {
hw_subframe = 0; hw_subframe = 0;
first_rx = 1; first_rx = 1;
frame++; frame++;
slot = 1; slot = 1;
if (UE->instance_cnt_synch < 0) { int fail = pthread_mutex_lock(&UE->mutex_synch);
int instance_cnt_synch = UE->instance_cnt_synch;
fail = fail || pthread_mutex_unlock(&UE->mutex_synch);
if (fail) {
LOG_E( PHY, "[SCHED][UE] error (un-)locking mutex for UE synch\n" );
exit_fun("noting to add");
return &UE_thread_retval;
}
if (instance_cnt_synch < 0) {
// the UE_thread_synch is ready
if (UE->is_synchronized == 1) { if (UE->is_synchronized == 1) {
// openair0_set_gains(&openair0,&openair0_cfg[0]);
rx_off_diff = 0; rx_off_diff = 0;
LTE_DL_FRAME_PARMS *frame_parms = &UE->lte_frame_parms; // for macro FRAME_LENGTH_COMPLEX_SAMPLES
// LOG_D(PHY,"HW RESYNC: hw_frame %d: rx_offset = %d\n",frame,UE->rx_offset); if ((UE->rx_offset > RX_OFF_MAX) && (start_rx_stream == 0)) {
if ((UE->rx_offset > RX_OFF_MAX)&&(start_rx_stream==0)) {
start_rx_stream=1; start_rx_stream=1;
//LOG_D(PHY,"HW RESYNC: hw_frame %d: Resynchronizing sample stream\n");
frame=0; frame=0;
// dump ahead in time to start of frame // dump ahead in time to start of frame
#ifndef USRP_DEBUG #ifndef USRP_DEBUG
rxs = openair0.trx_read_func(&openair0, unsigned int rxs = openair0.trx_read_func(&openair0,
&timestamp, &timestamp,
(void**)rxdata, (void**)rxdata,
UE->rx_offset, UE->rx_offset,
UE->lte_frame_parms.nb_antennas_rx); UE->lte_frame_parms.nb_antennas_rx);
#else #else
rt_sleep_ns(10000000); rt_sleep_ns(10000000);
#endif #endif
UE->rx_offset=0; UE->rx_offset=0;
tx_enabled=1; tx_enabled = 1;
} else if ((UE->rx_offset < RX_OFF_MIN)&&(start_rx_stream==1) && (rx_correction_timer == 0)) { } else if ((UE->rx_offset < RX_OFF_MIN) && (start_rx_stream==1) && (rx_correction_timer == 0)) {
rx_off_diff = -UE->rx_offset + RX_OFF_MIN; rx_off_diff = -UE->rx_offset + RX_OFF_MIN;
rx_correction_timer = 5; rx_correction_timer = 5;
} else if ((UE->rx_offset > (FRAME_LENGTH_COMPLEX_SAMPLES-RX_OFF_MAX)) &&(start_rx_stream==1) && (rx_correction_timer == 0)) { } else if ((UE->rx_offset > (FRAME_LENGTH_COMPLEX_SAMPLES-RX_OFF_MAX)) && (start_rx_stream==1) && (rx_correction_timer == 0)) {
rx_off_diff = FRAME_LENGTH_COMPLEX_SAMPLES-UE->rx_offset; rx_off_diff = FRAME_LENGTH_COMPLEX_SAMPLES-UE->rx_offset;
rx_correction_timer = 5; rx_correction_timer = 5;
} }
if (rx_correction_timer>0) if (rx_correction_timer>0)
rx_correction_timer--; rx_correction_timer--;
// LOG_D(PHY,"HW RESYNC: hw_frame %d: (rx_offset %d) Correction: rx_off_diff %d (timer %d)\n",frame,UE->rx_offset,rx_off_diff,rx_correction_timer);
} }
dummy_dump=0; dummy_dump=0;
...@@ -1095,7 +1117,7 @@ void *UE_thread(void *arg) ...@@ -1095,7 +1117,7 @@ void *UE_thread(void *arg)
#endif #endif
} }
return(0); return &UE_thread_retval;
} }
#endif #endif
...@@ -1496,13 +1518,22 @@ void *UE_thread(void *arg) ...@@ -1496,13 +1518,22 @@ void *UE_thread(void *arg)
#endif #endif
/*!
* \brief Initialize the UE theads.
* Creates the UE threads:
* - UE_thread_tx
* - UE_thread_rx
* - UE_thread_synch
* and the locking between them.
*/
void init_UE_threads(void) void init_UE_threads(void)
{ {
PHY_VARS_UE *UE=PHY_vars_UE_g[0][0]; PHY_VARS_UE *UE = PHY_vars_UE_g[0][0];
UE->instance_cnt_tx=-1; // the threads are not yet active, therefore access is allowed without locking
UE->instance_cnt_rx=-1; UE->instance_cnt_tx = -1;
UE->instance_cnt_synch=-1; UE->instance_cnt_rx = -1;
UE->instance_cnt_synch = -1;
pthread_mutex_init(&UE->mutex_tx,NULL); pthread_mutex_init(&UE->mutex_tx,NULL);
pthread_mutex_init(&UE->mutex_rx,NULL); pthread_mutex_init(&UE->mutex_rx,NULL);
pthread_mutex_init(&UE->mutex_synch,NULL); pthread_mutex_init(&UE->mutex_synch,NULL);
......
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