From ac7c0df5208053e923f157c61530aac226228ad9 Mon Sep 17 00:00:00 2001 From: Cedric Roux <cedric.roux@eurecom.fr> Date: Fri, 17 Feb 2017 17:55:27 +0100 Subject: [PATCH] integration fix: let oaisim (S1) work again - some cleanup - thread names to include UE Mod_id - arg of UE_thread_rxn_txnp4 to be struct rx_tx_thread_data again - sync in UE_thread_rxn_txnp4 to use instance_cnt_rxtx again - UE_thread to call itti_send_msg_to_task with UE->Mod_id + NB_eNB_INST instead of INSTANCE_DEFAULT again This may break the softmodem UE, to be tested. The most problematic thing may be the synchronization. I don't think it will impact the processing at all, but I won't bet my shirt on it. --- targets/RT/USER/lte-softmodem.h | 6 +- targets/RT/USER/lte-ue.c | 117 +++++++++++++++++++++----------- targets/SIMU/USER/oaisim.c | 4 +- 3 files changed, 82 insertions(+), 45 deletions(-) diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index e499bd12be3..b438d9eee2f 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -67,11 +67,7 @@ extern volatile int start_eNB; extern volatile int start_UE; #endif -typedef struct threads_s { - int iq; - int odd; - int even; -} threads_t; +#include "threads_t.h" extern threads_t threads; extern void exit_fun(const char* s); diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 06ddcba0a71..d1ed039beb1 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -124,10 +124,6 @@ static const eutra_band_t eutra_bands[] = { {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, }; -pthread_t main_ue_thread; -pthread_attr_t attr_UE_thread; -struct sched_param sched_param_UE_thread; - void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char * name) { #ifdef DEADLINE_SCHEDULER @@ -177,24 +173,25 @@ void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_ printf("started %s as PID: %ld\n",name, gettid()); } -void init_UE(int nb_inst) { - - for (long long inst=0; inst<nb_inst; inst++) { - // UE->rfdevice.type = NONE_DEV; - PHY_VARS_UE *UE = PHY_vars_UE_g[inst][0]; - AssertFatal(0 == pthread_create(&UE->proc.pthread_ue, - &UE->proc.attr_ue, - UE_thread, - (void*)UE), ""); - } - - printf("UE threads created by %ld\n", gettid()); +void init_UE(int nb_inst) +{ + int inst; + for (inst=0; inst < nb_inst; inst++) { + // UE->rfdevice.type = NONE_DEV; + PHY_VARS_UE *UE = PHY_vars_UE_g[inst][0]; + AssertFatal(0 == pthread_create(&UE->proc.pthread_ue, + &UE->proc.attr_ue, + UE_thread, + (void*)UE), ""); + } + + printf("UE threads created by %ld\n", gettid()); #if 0 #if defined(ENABLE_USE_MME) - extern volatile int start_UE; - while (start_UE == 0) { - sleep(1); - } + extern volatile int start_UE; + while (start_UE == 0) { + sleep(1); + } #endif #endif } @@ -214,14 +211,15 @@ static void *UE_thread_synch(void *arg) { sync_mode_t sync_mode = pbch; int CC_id = UE->CC_id; int freq_offset=0; + char threadname[128]; cpu_set_t cpuset; CPU_ZERO(&cpuset); if ( threads.iq != -1 ) CPU_SET(threads.iq, &cpuset); // this thread priority must be lower that the main acquisition thread - init_thread(100000, 500000, FIFO_PRIORITY-1, &cpuset, - "sync UE"); + sprintf(threadname, "sync UE %d\n", UE->Mod_id); + init_thread(100000, 500000, FIFO_PRIORITY-1, &cpuset, threadname); UE->is_synchronized = 0; @@ -460,6 +458,13 @@ static void *UE_thread_synch(void *arg) { } +/* this structure is used to pass both UE phy vars and + * proc to the function UE_thread_rxn_txnp4 + */ +struct rx_tx_thread_data { + PHY_VARS_UE *UE; + UE_rxtx_proc_t *proc; +}; /*! * \brief This is the UE thread for RX subframe n and TX subframe n+4. @@ -471,15 +476,16 @@ static void *UE_thread_synch(void *arg) { static void *UE_thread_rxn_txnp4(void *arg) { static __thread int UE_thread_rxtx_retval; - UE_rxtx_proc_t *proc = (UE_rxtx_proc_t *)arg; + struct rx_tx_thread_data *rtd = arg; + UE_rxtx_proc_t *proc = rtd->proc; + PHY_VARS_UE *UE = rtd->UE; int ret; - PHY_VARS_UE *UE=PHY_vars_UE_g[0][proc->CC_id]; - static long long __thread instance_cnt_rxtx=-1; + proc->instance_cnt_rxtx=-1; proc->subframe_rx=proc->sub_frame_start; - char threadname[256]= {0}; - sprintf(threadname,"UE_proc_%d",proc->sub_frame_start); + char threadname[256]; + sprintf(threadname,"UE_%d_proc_%d", UE->Mod_id, proc->sub_frame_start); cpu_set_t cpuset; CPU_ZERO(&cpuset); if ( (proc->sub_frame_start+1)%2 == 0 && threads.even != -1 ) @@ -490,14 +496,18 @@ static void *UE_thread_rxn_txnp4(void *arg) { threadname); while (!oai_exit) { - // Wait Rx data to process are available - AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,""); - pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); - if ( (instance_cnt_rxtx+proc->sub_frame_step)%10 != proc->subframe_rx && instance_cnt_rxtx!=-1 ) - LOG_W(PHY,"REAL TIME NOT MATCHED: missed a sub-frame: expecting %lld, got %d\n", - (instance_cnt_rxtx+proc->sub_frame_step)%10, proc->subframe_rx); - instance_cnt_rxtx=proc->subframe_rx; - AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); + if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { + LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); + exit_fun("nothing to add"); + } + while (proc->instance_cnt_rxtx < 0) { + // most of the time, the thread is waiting here + pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); + } + if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { + LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); + exit_fun("nothing to add"); + } initRefTimes(t2); initRefTimes(t3); @@ -571,9 +581,19 @@ static void *UE_thread_rxn_txnp4(void *arg) { phy_procedures_UE_S_TX(UE,0,0,no_relay); updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)"); + if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { + LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); + exit_fun("noting to add"); + } + proc->instance_cnt_rxtx--; + if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { + LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" ); + exit_fun("noting to add"); + } } // thread finished + free(arg); return &UE_thread_rxtx_retval; } @@ -596,6 +616,7 @@ void *UE_thread(void *arg) { void* rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX]; int start_rx_stream = 0; int i; + char threadname[128]; cpu_set_t cpuset; CPU_ZERO(&cpuset); @@ -606,13 +627,14 @@ void *UE_thread(void *arg) { if (oaisim_flag == 0) AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), ""); UE->rfdevice.host_type = BBU_HOST; - pthread_setname_np( pthread_self(), "Main UE" ); + sprintf(threadname, "Main UE %d", UE->Mod_id); + pthread_setname_np(pthread_self(), threadname); init_UE_threads(UE); #ifdef NAS_UE MessageDef *message_p; message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); - itti_send_msg_to_task (TASK_NAS_UE, INSTANCE_DEFAULT, message_p); + itti_send_msg_to_task (TASK_NAS_UE, UE->Mod_id + NB_eNB_INST, message_p); #endif int sub_frame=-1; @@ -638,13 +660,13 @@ void *UE_thread(void *arg) { UE->frame_parms.nb_antennas_rx), ""); AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); instance_cnt_synch = ++UE->proc.instance_cnt_synch; - AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); if (instance_cnt_synch == 0) { AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), ""); } else { LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); exit_fun("nothing to add"); } + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); } else { // grab 10 ms of signal into dummy buffer if (UE->mode != loop_through_memory) { @@ -770,6 +792,18 @@ void *UE_thread(void *arg) { (4*UE->frame_parms.samples_per_tti)- UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0; + proc->instance_cnt_rxtx++; + if (proc->instance_cnt_rxtx == 0) { + if (pthread_cond_signal(&proc->cond_rxtx) != 0) { + LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id); + exit_fun("nothing to add"); + } + } else { + LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", UE->Mod_id, proc->instance_cnt_rxtx); + if (proc->instance_cnt_rxtx > 2) + exit_fun("instance_cnt_rxtx > 2"); + } + AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0 ,""); AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); initRefTimes(t1); @@ -797,6 +831,7 @@ void *UE_thread(void *arg) { * and the locking between them. */ void init_UE_threads(PHY_VARS_UE *UE) { + struct rx_tx_thread_data *rtd; pthread_attr_init (&UE->proc.attr_ue); pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); @@ -807,11 +842,15 @@ void init_UE_threads(PHY_VARS_UE *UE) { // the threads are not yet active, therefore access is allowed without locking int nb_threads=2; for (int i=0; i<nb_threads; i++) { + rtd = calloc(1, sizeof(struct rx_tx_thread_data)); + if (rtd == NULL) abort(); + rtd->UE = UE; + rtd->proc = &UE->proc.proc_rxtx[i]; pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); UE->proc.proc_rxtx[i].sub_frame_start=i; UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; - pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx,NULL,UE_thread_rxn_txnp4,(void*)&UE->proc.proc_rxtx[i]); + pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_thread_rxn_txnp4, rtd); } pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 02ccefed269..7f4a9920234 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -181,7 +181,9 @@ extern uint16_t Nid_cell; extern LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; - +double cpuf; +#include "threads_t.h" +threads_t threads= {-1,-1,-1}; //#ifdef XFORMS int otg_enabled; -- GitLab