From e2c322280296d18f9afa33fe3e27f1c4c2309acf Mon Sep 17 00:00:00 2001 From: Raymond Knopp <raymond.knopp@eurecom.fr> Date: Mon, 9 May 2016 23:40:36 -0700 Subject: [PATCH] removal of EXPRESSMIMO #ifdef's in lte-ue. move UE-specific code from lte-softmodem.c to lte-ue.c --- cmake_targets/CMakeLists.txt | 13 - targets/RT/USER/lte-softmodem.c | 54 +-- targets/RT/USER/lte-ue.c | 669 ++++--------------------------- targets/RT/USER/sched_dlsch.c | 354 ---------------- targets/RT/USER/sched_rx_pdsch.c | 321 --------------- targets/RT/USER/sched_ulsch.c | 255 ------------ 6 files changed, 96 insertions(+), 1570 deletions(-) delete mode 100644 targets/RT/USER/sched_dlsch.c delete mode 100644 targets/RT/USER/sched_rx_pdsch.c delete mode 100644 targets/RT/USER/sched_ulsch.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 166da4a48d..966ef6e085 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -259,15 +259,6 @@ if (${ENABLE_ITTI}) endif (${ENABLE_ITTI}) add_boolean_option(RTAI False "Use RTAI") -if (${RTAI}) - set(LOWLATENCY False) - set(CPU_AFFINITY False) - add_definitions("-DENABLE_RTAI_CLOCK") - add_definitions("-DCONFIG_RTAI_LXRT_INLINE") - include_directories ("/usr/realtime/include") - include_directories ("/usr/realtime/include/asm") - set(RTAI_SOURCE sched_dlsch.c sched_rx_pdsch.c rt_wrapper.c vcd_signal_dumper.c log.c) -endif (${RTAI}) ############################# # ASN.1 grammar C code generation & dependancies @@ -1574,8 +1565,6 @@ add_executable(lte-softmodem ${rrc_h} ${s1ap_h} ${OPENAIR_BIN_DIR}/messages_xml.h - ${OPENAIR_TARGETS}/RT/USER/sched_dlsch.c - ${OPENAIR_TARGETS}/RT/USER/sched_rx_pdsch.c ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c ${OPENAIR_TARGETS}/RT/USER/lte-ue.c ${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c @@ -1611,8 +1600,6 @@ add_executable(lte-softmodem-nos1 ${rrc_h} ${s1ap_h} ${OPENAIR_BIN_DIR}/messages_xml.h - ${OPENAIR_TARGETS}/RT/USER/sched_dlsch.c - ${OPENAIR_TARGETS}/RT/USER/sched_rx_pdsch.c ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c ${OPENAIR_TARGETS}/RT/USER/lte-ue.c ${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 4664b0aa21..822409f302 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -113,12 +113,18 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "stats.h" #endif +// In lte-enb.c 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_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]); + extern void init_eNB(void); extern void stop_eNB(void); +extern void kill_eNB_proc(void); +// In lte-ue.c +int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]); void fill_ue_band_info(void); +extern void init_UE(void); + #ifdef XFORMS // current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) // at eNB 0, an UL scope for every UE @@ -130,9 +136,6 @@ unsigned char scope_enb_num_ue = 2; #endif //XFORMS -pthread_t main_ue_thread; - -pthread_attr_t attr_UE_thread; @@ -144,7 +147,6 @@ int sync_var=-1; //!< protected by mutex \ref sync_mutex. -struct sched_param sched_param_UE_thread; #ifdef XFORMS @@ -284,9 +286,8 @@ openair0_config_t openair0_cfg[MAX_CARDS]; double cpuf; char uecap_xer[1024],uecap_xer_in=0; -extern void *UE_thread(void *arg); -extern void init_UE_threads(void); -extern void kill_eNB_proc(void); + + /*---------------------BMC: timespec helpers -----------------------------*/ @@ -1120,7 +1121,6 @@ int main( int argc, char **argv ) uint16_t Nid_cell = 0; uint8_t cooperation_flag=0, abstraction_flag=0; uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; - int error_code; #if defined (XFORMS) int ret; @@ -1752,43 +1752,11 @@ int main( int argc, char **argv ) rt_sleep_ns(10*100000000ULL); - pthread_attr_init (&attr_UE_thread); - pthread_attr_setstacksize(&attr_UE_thread,8192);//5*PTHREAD_STACK_MIN); -#ifndef LOWLATENCY - sched_param_UE_thread.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_attr_setschedparam(&attr_UE_thread,&sched_param_UE_thread); -#endif // start the main thread - if (UE_flag == 1) { - printf("Intializing UE Threads ...\n"); - init_UE_threads(); - sleep(1); - error_code = pthread_create(&main_ue_thread, &attr_UE_thread, UE_thread, NULL); - - if (error_code!= 0) { - LOG_D(HW,"[lte-softmodem.c] Could not allocate UE_thread, error %d\n",error_code); - return(error_code); - } else { - LOG_D( HW, "[lte-softmodem.c] Allocate UE_thread successful\n" ); - pthread_setname_np( main_ue_thread, "main UE" ); - } - - printf("UE threads created\n"); -#ifdef USE_MME - - while (start_UE == 0) { - sleep(1); - } - -#endif - - - - } else { - init_eNB(); - } + if (UE_flag == 1) init_UE(); + else init_eNB(); // Sleep to allow all threads to setup sleep(1); diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 561554516c..3049fd4e02 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -69,11 +69,7 @@ #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all -#ifdef EXMIMO -#include "openair0_lib.h" -#else #include "../../ARCH/COMMON/common_lib.h" -#endif #include "PHY/extern.h" #include "SCHED/extern.h" @@ -96,10 +92,9 @@ typedef enum { si=2 } sync_mode_t; -int init_dlsch_threads(void); -void cleanup_dlsch_threads(void); -int32_t init_rx_pdsch_thread(void); -void cleanup_rx_pdsch_thread(void); +void init_UE_threads(void); +void *UE_thread(void *arg); +void init_UE(void); extern pthread_cond_t sync_cond; extern pthread_mutex_t sync_mutex; @@ -125,19 +120,6 @@ extern uint64_t num_missed_slots; // counter for the number of missed slots extern void exit_fun(const char* s); -#ifdef EXMIMO - -extern unsigned int rxg_max[4]; -extern unsigned int rxg_med[4]; -extern unsigned int rxg_byp[4]; -extern unsigned int nf_max[4]; -extern unsigned int nf_med[4]; -extern unsigned int nf_byp[4]; -extern rx_gain_t rx_gain_mode[MAX_NUM_CCs][4]; - -extern double tx_gain[MAX_NUM_CCs][4]; -extern double rx_gain[MAX_NUM_CCs][4]; -#endif #define KHz (1000UL) #define MHz (1000 * KHz) @@ -189,6 +171,38 @@ 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_UE() { + + int error_code; + + printf("Intializing UE Threads ...\n"); + init_UE_threads(); + sleep(1); + error_code = pthread_create(&main_ue_thread, &attr_UE_thread, UE_thread, NULL); + + if (error_code!= 0) { + LOG_D(HW,"[lte-softmodem.c] Could not allocate UE_thread, error %d\n",error_code); + return; + } else { + LOG_D( HW, "[lte-softmodem.c] Allocate UE_thread successful\n" ); + pthread_setname_np( main_ue_thread, "main UE" ); + } + + printf("UE threads created\n"); +#ifdef USE_MME + + while (start_UE == 0) { + sleep(1); + } + +#endif + +} + /*! * \brief This is the UE synchronize thread. * It performs band scanning and synchonization. @@ -512,15 +526,10 @@ static void *UE_thread_synch(void *arg) // openair0_cfg[0].rx_gain[0] -= 0; break; } -#ifndef EXMIMO + openair0.trx_set_freq_func(&openair0,&openair0_cfg[0],0); //openair0.trx_set_gains_func(&openair0,&openair0_cfg[0]); //openair0.trx_stop_func(0); -#else - openair0_set_frequencies(&openair0,&openair0_cfg[0],0); - openair0_set_gains(&openair0,&openair0_cfg[0]); - openair0_stop(0); -#endif sleep(1); init_frame_parms(&UE->lte_frame_parms,1); } @@ -550,13 +559,9 @@ static void *UE_thread_synch(void *arg) } -#ifndef EXMIMO + UE->slot_rx = 0; UE->slot_tx = 4; -#else - UE->slot_rx = 18; - UE->slot_tx = 2; -#endif } } else { // initial sync failed @@ -598,42 +603,13 @@ static void *UE_thread_synch(void *arg) for (i=0; i<openair0_cfg[card].rx_num_channels; i++) { openair0_cfg[card].rx_freq[i] = downlink_frequency[card][i]+freq_offset; openair0_cfg[card].tx_freq[i] = downlink_frequency[card][i]+uplink_frequency_offset[card][i]+freq_offset; -#ifndef EXMIMO + openair0.trx_set_freq_func(&openair0,&openair0_cfg[0],0); -#else - openair0_set_frequencies(&openair0,&openair0_cfg[0],0); - -#endif -#if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) openair0_cfg[card].rx_gain[i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; -#if 0 - switch(UE->lte_frame_parms.N_RB_DL) { - case 6: - openair0_cfg[card].rx_gain[i] -= 12; - break; - - case 25: - openair0_cfg[card].rx_gain[i] -= 6; - break; - - case 50: - openair0_cfg[card].rx_gain[i] -= 0;//3; - break; - - case 100: - openair0_cfg[card].rx_gain[i] -= 0; - break; - - default: - printf("Unknown number of RBs %d\n",UE->lte_frame_parms.N_RB_DL); - break; - } -#endif -#endif } } if (UE->UE_scan_carrier==1) { @@ -690,17 +666,6 @@ static void *UE_thread_tx(void *arg) UE->instance_cnt_tx=-1; -#ifdef RTAI - RT_TASK *task = rt_task_init_schmod(nam2num("UE TX Thread"), 0, 0, 0, SCHED_FIFO, 0xF); - - if (task==NULL) { - LOG_E(PHY,"[SCHED][UE] Problem starting UE TX thread!!!!\n"); - return 0; - } - - LOG_D(HW,"Started UE TX thread (id %p)\n",task); -#else - #ifdef LOWLATENCY struct sched_attr attr; unsigned int flags = 0; @@ -745,7 +710,7 @@ static void *UE_thread_tx(void *arg) exit_fun("Error setting processor affinity"); } } - #endif +#endif /* Check the actual affinity mask assigned to the thread */ @@ -790,7 +755,6 @@ static void *UE_thread_tx(void *arg) (int) sparam.sched_priority, cpu_affinity); -#endif #endif printf("waiting for sync (UE_thread_tx)\n"); @@ -909,17 +873,6 @@ static void *UE_thread_rx(void *arg) UE->instance_cnt_rx=-1; -#ifdef RTAI - RT_TASK *task = rt_task_init_schmod(nam2num("UE RX Thread"), 0, 0, 0, SCHED_FIFO, 0xF); - - if (task==NULL) { - LOG_E(PHY,"[SCHED][UE] Problem starting UE RX thread!!!!\n"); - return &UE_thread_rx_retval; - } - - LOG_D(HW,"Started UE RX thread (id %p)\n",task); -#else - #ifdef LOWLATENCY struct sched_attr attr; unsigned int flags = 0; @@ -1008,7 +961,6 @@ static void *UE_thread_rx(void *arg) (int) sparam.sched_priority, cpu_affinity); -#endif #endif // Lock memory from swapping. This is a process wide call (not constraint to this thread). @@ -1186,7 +1138,7 @@ static void *UE_thread_rx(void *arg) -#ifndef EXMIMO + #define RX_OFF_MAX 10 #define RX_OFF_MIN 5 #define RX_OFF_MID ((RX_OFF_MAX+RX_OFF_MIN)/2) @@ -1227,16 +1179,6 @@ void *UE_thread(void *arg) MessageDef *message_p; #endif -#ifdef RTAI - RT_TASK *task = rt_task_init_schmod(nam2num("UE thread"), 0, 0, 0, SCHED_FIFO, 0xF); - - if (task==NULL) { - LOG_E(PHY,"[SCHED][UE] Problem starting UE thread!!!!\n"); - return 0; - } - -#else - #ifdef LOWLATENCY struct sched_attr attr; unsigned int flags = 0; @@ -1264,7 +1206,6 @@ void *UE_thread(void *arg) struct sched_param sp; sp.sched_priority = sched_get_priority_max(SCHED_FIFO); pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp); -#endif #endif // Lock memory from swapping. This is a process wide call (not constraint to this thread). @@ -1591,409 +1532,8 @@ void *UE_thread(void *arg) return &UE_thread_retval; } -#endif - - - -#ifdef EXMIMO -/* This is the main UE thread. Initially it is doing a periodic get_frame. One synchronized it gets woken up by the kernel driver using the RTAI message mechanism (rt_send and rt_receive). */ -void *UE_thread(void *arg) -{ - PHY_VARS_UE *UE=PHY_vars_UE_g[0][0]; -#ifdef RTAI - RT_TASK *task; -#endif - // RTIME in, out, diff; - int slot=0,frame=0,hw_slot; - // unsigned int aa; - int delay_cnt; - RTIME time_in; - int /* hw_slot_offset=0, */ rx_offset_mbox=0,mbox_target=0,mbox_current=0; - int diff2; - int /* i, */ ret; - int /* CC_id, */ card; - volatile unsigned int *DAQ_MBOX = openair0_daq_cnt(); - - int wait_sync_cnt = 0; - int first_synch = 1; -#ifdef LOWLATENCY - struct sched_attr attr; - unsigned int flags = 0; - // unsigned long mask = 1; // processor 0 -#endif - int freq_offset; - - -#ifdef RTAI - task = rt_task_init_schmod(nam2num("UE thread"), 0, 0, 0, SCHED_FIFO, 0xF); - - if (task==NULL) { - LOG_E(PHY,"[SCHED][UE] Problem starting UE thread!!!!\n"); - return 0; - } - -#endif - - -#ifdef HARD_RT - rt_make_hard_real_time(); -#endif - - -#ifdef LOWLATENCY - attr.size = sizeof(attr); - attr.sched_flags = 0; - attr.sched_nice = 0; - attr.sched_priority = 0; - - // This creates a .25 ms reservation - attr.sched_policy = SCHED_DEADLINE; - attr.sched_runtime = (0.1 * 100) * 10000; - attr.sched_deadline = (0.25 * 100) * 10000; - attr.sched_period = (0.5 * 100) * 10000; - - // 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 ) { - perror("[SCHED] main UE thread: sched_setattr failed\n"); - exit_fun("Nothing to add"); - } else { - LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %ld started on CPU %d\n", - gettid(),sched_getcpu()); - } - -#endif - - - mlockall(MCL_CURRENT | MCL_FUTURE); - - printf("waiting for sync (UE_thread)\n"); - - pthread_mutex_lock(&sync_mutex); - printf("Locked sync_mutex, waiting (UE_thread)\n"); - - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - - pthread_mutex_unlock(&sync_mutex); - printf("unlocked sync_mutex, waiting (UE_thread)\n"); - - printf("starting UE thread\n"); - - freq_offset = 0; //-7500; - - first_synch = 1; - - while (!oai_exit) { - - hw_slot = (((((volatile unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15; //the slot the hw is about to store - - - if (UE->is_synchronized) { - - if (first_synch == 1) { - first_synch = 0; - - for (card=0; card<openair0_num_detected_cards; card++) - openair0_start_rt_acquisition(card); - - rt_sleep_ns(FRAME_PERIOD/10); - } - - //this is the mbox counter that indicates the start of the frame - rx_offset_mbox = (UE->rx_offset * 150) / (10*UE->lte_frame_parms.samples_per_tti); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_RX_OFFSET, UE->rx_offset); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_OFFSET_MBOX, rx_offset_mbox); - //this is the mbox counter where we should be - mbox_target = (((((slot+1)%20)*15+1)>>1) + rx_offset_mbox + 1)%150; - // round up to the next multiple of two (mbox counter from express MIMO gives only even numbers) - mbox_target = ((mbox_target+1)-((mbox_target-1)%2))%150; - //this is the mbox counter where we are - mbox_current = ((volatile unsigned int *)DAQ_MBOX)[0]; - - //this is the time we need to sleep in order to synchronize with the hw (in multiples of DAQ_PERIOD) - if ((mbox_current>=120) && (mbox_target<30)) //handle the frame wrap-arround - diff2 = 150-mbox_current+mbox_target; - else if ((mbox_current<30) && (mbox_target>=120)) - diff2 = -150+mbox_target-mbox_current; - else - diff2 = mbox_target - mbox_current; - - if (diff2 <(-7)) { - LOG_D(HW,"UE Frame %d: missed slot, proceeding with next one (slot %d, hw_slot %d, diff %d)\n",frame, slot, hw_slot, diff2); - - if (frame>0) { - if (exit_missed_slots==1) - exit_fun("[HW][UE] missed slot"); - else { - num_missed_slots++; - LOG_W(HW,"[UE] just missed slot (total missed slots %ld)\n", num_missed_slots); - } - } - - slot++; - - if (slot==20) { - slot=0; - frame++; - } - - // update thread slot/frame counters because of skipped slot - UE->slot_rx++; - UE->slot_tx++; - - if (UE->slot_rx == 20) { - UE->slot_rx = 0; - UE->frame_rx++; - } - - if (UE->slot_tx == 20) { - UE->slot_tx = 0; - UE->frame_tx++; - } - - continue; - } - - if (diff2>8) - LOG_D(HW,"UE Frame %d: skipped slot, waiting for hw to catch up (slot %d, hw_slot %d, mbox_current %d, mbox_target %d, diff %d)\n",frame, slot, hw_slot, mbox_current, mbox_target, diff2); - - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *DAQ_MBOX); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DIFF, diff2); - - - - // This loop implements the delay of 1 slot to allow for processing - delay_cnt = 0; - - while ((diff2>0) && (!oai_exit) ) { - time_in = rt_get_time_ns(); - //LOG_D(HW,"eNB Frame %d delaycnt %d : hw_slot %d (%d), slot %d (%d), diff %d, time %llu\n",frame,delay_cnt,hw_slot,((volatile unsigned int *)DAQ_MBOX)[0],slot,mbox_target,diff2,time_in); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *DAQ_MBOX); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RT_SLEEP,1); - ret = rt_sleep_ns(diff2*DAQ_PERIOD); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RT_SLEEP,0); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *DAQ_MBOX); - - if (ret) - LOG_D(HW,"eNB Frame %d, time %llu: rt_sleep_ns returned %d\n",frame, time_in); - - hw_slot = (((((volatile unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15; - //LOG_D(HW,"eNB Frame %d : hw_slot %d, time %llu\n",frame,hw_slot,rt_get_time_ns()); - delay_cnt++; - - if (delay_cnt == 30) { - LOG_D(HW,"UE frame %d: HW stopped ... \n",frame); - exit_fun("[HW][UE] HW stopped"); - } - - mbox_current = ((volatile unsigned int *)DAQ_MBOX)[0]; - - if ((mbox_current>=135) && (mbox_target<15)) //handle the frame wrap-arround - diff2 = 150-mbox_current+mbox_target; - else if ((mbox_current<15) && (mbox_target>=135)) - diff2 = -150+mbox_target-mbox_current; - else - diff2 = mbox_target - mbox_current; - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *DAQ_MBOX); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DIFF, diff2); - } - - // on even slots, schedule processing of entire subframe - if ((slot&1) == 0) { - - if (pthread_mutex_lock(&UE->mutex_rx) != 0) { - LOG_E(PHY,"[SCHED][UE] error locking mutex for UE RX thread\n"); - exit_fun("nothing to add"); - } else { - - int instance_cnt_rx = ++UE->instance_cnt_rx; - - pthread_mutex_unlock(&UE->mutex_rx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_RX, instance_cnt_rx); - - - if (instance_cnt_rx == 0) { - LOG_D(HW,"Scheduling UE RX for frame %d (hw frame %d), subframe %d (%d), mode %d\n",UE->frame_rx,frame,slot>>1,UE->slot_rx>>1,UE->mode); - - if (pthread_cond_signal(&UE->cond_rx) != 0) { - LOG_E(PHY,"[SCHED][UE] ERROR pthread_cond_signal for UE RX thread\n"); - 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 (frame == 10) { - LOG_D(PHY, - "[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", - UE->lte_frame_parms.N_RB_DL, - UE->lte_frame_parms.phich_config_common.phich_duration, - UE->lte_frame_parms.phich_config_common.phich_resource, - UE->lte_frame_parms.Nid_cell, - UE->lte_frame_parms.nb_antennas_tx_eNB, - 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"); - } - } - } else { - LOG_E(PHY,"[SCHED][UE] UE RX thread busy!!\n"); - exit_fun("nothing to add"); - } - } - - if (pthread_mutex_lock(&UE->mutex_tx) != 0) { - LOG_E(PHY,"[SCHED][UE] error locking mutex for UE TX thread\n"); - exit_fun("nothing to add"); - } else { - - int instance_cnt_tx = ++UE->instance_cnt_tx; - - pthread_mutex_unlock(&UE->mutex_tx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_TX, instance_cnt_tx); - - if (instance_cnt_tx == 0) { - LOG_D(HW,"Scheduling UE TX for frame %d (hw frame %d), subframe %d (%d), mode %d\n",UE->frame_tx,frame,slot>>1,UE->slot_tx>>1,UE->mode); - - if (pthread_cond_signal(&UE->cond_tx) != 0) { - LOG_E(PHY,"[SCHED][UE] ERROR pthread_cond_signal for UE TX thread\n"); - 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); - } - } else { - LOG_E(PHY,"[SCHED][UE] UE TX thread busy!!\n"); - exit_fun("nothing to add"); - } - } - } - - /* - if ((slot%2000)<10) - LOG_D(HW,"fun0: doing very hard work\n"); - */ - // now increment slot and frame counters - slot++; - - if (slot==20) { - slot=0; - frame++; - } - } else if (UE->is_synchronized == 0) { // we are not yet synchronized - //hw_slot_offset = 0; - first_synch = 1; - slot = 0; - - - // wait until we can lock mutex_synch - //printf("Locking mutex_synch (UE_thread)\n"); - if (pthread_mutex_lock(&UE->mutex_synch) != 0) { - LOG_E(PHY,"[SCHED][UE] error locking mutex for UE initial synch thread\n"); - exit_fun("noting to add"); - } else { - - if (UE->instance_cnt_synch < 0) { - - wait_sync_cnt=0; - openair0_config(&openair0_cfg[0],1); - // openair0_set_gains(&openair0,&openair0_cfg[0]); - - printf("Getting frame\n"); - openair0_get_frame(0); - rt_sleep_ns(FRAME_PERIOD); - // increment instance count for sync thread - UE->instance_cnt_synch++; - pthread_mutex_unlock(&UE->mutex_synch); - - 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"); - } - } else { - wait_sync_cnt++; - pthread_mutex_unlock(&UE->mutex_synch); - - if (wait_sync_cnt>1000) - exit_fun("waiting to long for synch thread"); - else - rt_sleep_ns(FRAME_PERIOD); - } - } - - - /* - if (initial_sync(UE,mode)==0) { - - if (mode == rx_calib_ue) { - exit_fun("[HW][UE] UE in RX calibration mode"); - } - else { - is_synchronized = 1; - //start the streaming DMA transfers - for (card=0;card<openair0_num_detected_cards;card++) - openair0_start_rt_acquisition(card); - - hw_slot_offset = (UE->rx_offset<<1) / UE->lte_frame_parms.samples_per_tti; - } - } - else { - if (freq_offset >= 0) { - freq_offset += 100; - freq_offset *= -1; - } - else { - freq_offset *= -1; - } - if (abs(freq_offset) > 7500) { - LOG_I(PHY,"[initial_sync] No cell synchronization found, abondoning\n"); - mac_xface->macphy_exit("No cell synchronization found, abondoning"); - } - else { - // LOG_I(PHY,"[initial_sync] trying carrier off %d Hz\n",freq_offset); - #ifndef USRP - for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { - for (i=0; i<openair0_cfg[rf_map[CC_id].card].rx_num_channels; i++) - openair0_cfg[rf_map[CC_id].card].rx_freq[rf_map[CC_id].chain+i] = downlink_frequency[CC_id][i]+freq_offset; - for (i=0; i<openair0_cfg[rf_map[CC_id].card].tx_num_channels; i++) - openair0_cfg[rf_map[CC_id].card].tx_freq[rf_map[CC_id].chain+i] = downlink_frequency[CC_id][i]+freq_offset; - } - openair0_config(&openair0_cfg[0],UE_flag); - #endif - rt_sleep_ns(FRAME_PERIOD); - } - } - */ - } - } - - LOG_D(HW,"UE_thread: finished, ran %d times.\n",frame); - -#ifdef HARD_RT - rt_make_soft_real_time(); -#endif - - // clean task -#ifdef RTAI - rt_task_delete(task); -#endif - LOG_D(HW,"Task deleted. returning\n"); - return 0; -} -#else // This is for USRP or ETHERNET targets -#endif /*! @@ -2008,6 +1548,14 @@ void init_UE_threads(void) { PHY_VARS_UE *UE = PHY_vars_UE_g[0][0]; + pthread_attr_init (&attr_UE_thread); + pthread_attr_setstacksize(&attr_UE_thread,8192);//5*PTHREAD_STACK_MIN); + +#ifndef LOWLATENCY + sched_param_UE_thread.sched_priority = sched_get_priority_max(SCHED_FIFO); + pthread_attr_setschedparam(&attr_UE_thread,&sched_param_UE_thread); +#endif + // the threads are not yet active, therefore access is allowed without locking UE->instance_cnt_tx = -1; UE->instance_cnt_rx = -1; @@ -2063,97 +1611,50 @@ void fill_ue_band_info(void) int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]) { - //#ifndef EXMIMO - // uint16_t N_TA_offset = 0; - //#endif - int i, CC_id; LTE_DL_FRAME_PARMS *frame_parms; - + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - if (phy_vars_ue[CC_id]) { - frame_parms = &(phy_vars_ue[CC_id]->lte_frame_parms); - } else { - printf("phy_vars_UE[%d] not initialized\n", CC_id); - return(-1); - } - - - //#ifndef EXMIMO - // if (frame_parms->frame_type == TDD) { - // if (frame_parms->N_RB_DL == 100) - // N_TA_offset = 624; - // else if (frame_parms->N_RB_DL == 50) - // N_TA_offset = 624/2; - // else if (frame_parms->N_RB_DL == 25) - // N_TA_offset = 624/4; - // } - //#endif - -#ifdef EXMIMO - openair0_cfg[CC_id].tx_num_channels = 0; - openair0_cfg[CC_id].rx_num_channels = 0; - - // replace RX signal buffers with mmaped HW versions - for (i=0; i<frame_parms->nb_antennas_rx; i++) { - printf("Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n",CC_id,i,downlink_frequency[CC_id][i],rf_map[CC_id].card,rf_map[CC_id].chain+i); - free(phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i]); - phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i] = (int32_t*) openair0_exmimo_pci[rf_map[CC_id].card].adc_head[rf_map[CC_id].chain+i]; - - if (openair0_cfg[rf_map[CC_id].card].rx_freq[rf_map[CC_id].chain+i]) { - printf("Error with rf_map! A channel has already been allocated!\n"); - return(-1); - } else { - openair0_cfg[rf_map[CC_id].card].rx_freq[rf_map[CC_id].chain+i] = downlink_frequency[CC_id][i]; - openair0_cfg[rf_map[CC_id].card].rx_gain[rf_map[CC_id].chain+i] = rx_gain[CC_id][i]; - openair0_cfg[rf_map[CC_id].card].rxg_mode[rf_map[CC_id].chain+i] = rx_gain_mode[CC_id][i]; - openair0_cfg[rf_map[CC_id].card].rx_num_channels++; - } - - printf("rxdata[%d] @ %p\n",i,phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i]); - } - - for (i=0; i<frame_parms->nb_antennas_tx; i++) { - printf("Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n",CC_id,i,downlink_frequency[CC_id][i],rf_map[CC_id].card,rf_map[CC_id].chain+i); - free(phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i]); - phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i] = (int32_t*) openair0_exmimo_pci[rf_map[CC_id].card].dac_head[rf_map[CC_id].chain+i]; + if (phy_vars_ue[CC_id]) { + frame_parms = &(phy_vars_ue[CC_id]->lte_frame_parms); + } else { + printf("phy_vars_UE[%d] not initialized\n", CC_id); + return(-1); + } - if (openair0_cfg[rf_map[CC_id].card].tx_freq[rf_map[CC_id].chain+i]) { - printf("Error with rf_map! A channel has already been allocated!\n"); - return(-1); - } else { - openair0_cfg[rf_map[CC_id].card].tx_freq[rf_map[CC_id].chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; - openair0_cfg[rf_map[CC_id].card].tx_gain[rf_map[CC_id].chain+i] = tx_gain[CC_id][i]; - openair0_cfg[rf_map[CC_id].card].tx_num_channels++; - } - printf("txdata[%d] @ %p\n",i,phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i]); - } + if (frame_parms->frame_type == TDD) { + if (frame_parms->N_RB_DL == 100) + N_TA_offset = 624; + else if (frame_parms->N_RB_DL == 50) + N_TA_offset = 624/2; + else if (frame_parms->N_RB_DL == 25) + N_TA_offset = 624/4; + } + -#else // replace RX signal buffers with mmaped HW versions - rxdata = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) ); - txdata = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) ); - - for (i=0; i<frame_parms->nb_antennas_rx; i++) { - printf( "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n", CC_id, i, downlink_frequency[CC_id][i], rf_map[CC_id].card, rf_map[CC_id].chain+i ); - free( phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i] ); - rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); - phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD - } - - for (i=0; i<frame_parms->nb_antennas_tx; i++) { - printf( "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n", CC_id, i, downlink_frequency[CC_id][i], rf_map[CC_id].card, rf_map[CC_id].chain+i ); - free( phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i] ); - txdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); - phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i] = txdata[i]; - } - - // rxdata[x] points now to the same memory region as phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[x] - // txdata[x] points now to the same memory region as phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[x] - // be careful when releasing memory! - // because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes) -#endif + rxdata = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) ); + txdata = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) ); + + for (i=0; i<frame_parms->nb_antennas_rx; i++) { + printf( "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n", CC_id, i, downlink_frequency[CC_id][i], rf_map[CC_id].card, rf_map[CC_id].chain+i ); + free( phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i] ); + rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); + phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD + } + + for (i=0; i<frame_parms->nb_antennas_tx; i++) { + printf( "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n", CC_id, i, downlink_frequency[CC_id][i], rf_map[CC_id].card, rf_map[CC_id].chain+i ); + free( phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i] ); + txdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); + phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[i] = txdata[i]; + } + + // rxdata[x] points now to the same memory region as phy_vars_ue[CC_id]->lte_ue_common_vars.rxdata[x] + // txdata[x] points now to the same memory region as phy_vars_ue[CC_id]->lte_ue_common_vars.txdata[x] + // be careful when releasing memory! + // because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes) } diff --git a/targets/RT/USER/sched_dlsch.c b/targets/RT/USER/sched_dlsch.c deleted file mode 100644 index 48fac642a9..0000000000 --- a/targets/RT/USER/sched_dlsch.c +++ /dev/null @@ -1,354 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -/*! \file sched_dlsch.c -* \brief DLSCH decoding thread (RTAI) -* \author R. Knopp, F. Kaltenberger -* \date 2011 -* \version 0.1 -* \company Eurecom -* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr -* \note -* \warning -*/ -#include <stdio.h> -#include <stdlib.h> -#include <sched.h> - -#include "rt_wrapper.h" - -#include <sys/mman.h> - -#include "PHY/types.h" -#include "PHY/defs.h" -#include "PHY/extern.h" - -#include "SCHED/defs.h" - -#include "UTIL/LOG/vcd_signal_dumper.h" - -#define DEBUG_PHY - -/// Mutex for instance count on dlsch scheduling -pthread_mutex_t dlsch_mutex[8]; -/// Condition variable for dlsch thread -pthread_cond_t dlsch_cond[8]; - -pthread_t dlsch_threads[8]; -pthread_attr_t attr_dlsch_threads; -unsigned char dlsch_thread_indices[8]; - -// activity indicators for harq_pid's -int dlsch_instance_cnt[8]; -// process ids for cpu -int dlsch_cpuid[8]; -// subframe number for each harq_pid (needed to store ack in right place for UL) -int dlsch_subframe[8]; - -extern int oai_exit; - -/* -extern int dlsch_errors; -extern int dlsch_received; -extern int dlsch_errors_last; -extern int dlsch_received_last; -extern int dlsch_fer; -extern int current_dlsch_cqi; -*/ - -/** DLSCH Decoding Thread */ -static void * dlsch_thread(void *param) -{ - - //unsigned long cpuid; - unsigned char dlsch_thread_index = *((unsigned char *)param); - unsigned int ret=0; - uint8_t harq_pid; - - -#ifdef RTAI - RT_TASK *task; - char task_name[8]; -#endif - - int eNB_id = 0, UE_id = 0, CC_id=0; - PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[UE_id][CC_id]; - - if ((dlsch_thread_index <0) || (dlsch_thread_index>7)) { - LOG_E(PHY,"[SCHED][DLSCH] Illegal dlsch_thread_index %d (%p)!!!!\n",dlsch_thread_index,param); - return 0; - } - -#ifdef RTAI - sprintf(task_name,"DLSCH%d",dlsch_thread_index); - task = rt_task_init_schmod(nam2num(task_name), 0, 0, 0, SCHED_FIFO, 0xF); - - if (task==NULL) { - LOG_E(PHY,"[SCHED][DLSCH] Problem starting dlsch_thread_index %d (%s)!!!!\n",dlsch_thread_index,task_name); - return 0; - } else { - LOG_I(PHY,"[SCHED][DLSCH] dlsch_thread for process %d started with id %p\n", - dlsch_thread_index, - task); - } - -#endif - - mlockall(MCL_CURRENT | MCL_FUTURE); - - //rt_set_runnable_on_cpuid(task,1); - //cpuid = rtai_cpuid(); - -#ifdef HARD_RT - rt_make_hard_real_time(); -#endif - - //dlsch_cpuid[dlsch_thread_index] = cpuid; - - while (!oai_exit) { - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_THREAD0+dlsch_thread_index,0); - - if (pthread_mutex_lock(&dlsch_mutex[dlsch_thread_index]) != 0) { - LOG_E(PHY,"[SCHED][DLSCH] error locking mutex.\n"); - } else { - - while (dlsch_instance_cnt[dlsch_thread_index] < 0) { - pthread_cond_wait(&dlsch_cond[dlsch_thread_index],&dlsch_mutex[dlsch_thread_index]); - } - - if (pthread_mutex_unlock(&dlsch_mutex[dlsch_thread_index]) != 0) { - LOG_E(PHY,"[SCHED][DLSCH] error unlocking mutex.\n"); - } - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_THREAD0+dlsch_thread_index,1); - - if (oai_exit) break; - - LOG_I(PHY,"[SCHED][DLSCH] Frame %d: Calling dlsch_decoding with dlsch_thread_index = %d\n",phy_vars_ue->frame_rx,dlsch_thread_index); - - - - if (phy_vars_ue->frame_rx < phy_vars_ue->dlsch_errors[eNB_id]) { - phy_vars_ue->dlsch_errors[eNB_id]=0; - phy_vars_ue->dlsch_received[eNB_id] = 0; - } - - harq_pid = dlsch_thread_index; - - if (phy_vars_ue->dlsch_ue[eNB_id][0]) { - - // rt_printk("[SCHED][DLSCH] Frame %d, slot %d, start %llu, end %llu, proc time: %llu ns\n",phy_vars_ue->frame,last_slot,time0,time1,(time1-time0)); - - dlsch_unscrambling(&phy_vars_ue->lte_frame_parms, - 0, - phy_vars_ue->dlsch_ue[eNB_id][0], - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->G, - phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->llr[0], - 0, - dlsch_subframe[dlsch_thread_index]<<1); - - LOG_I(PHY,"[UE %d] PDSCH Calling dlsch_decoding for subframe %d, harq_pid %d, G%d\n", phy_vars_ue->Mod_id,dlsch_subframe[dlsch_thread_index], harq_pid, - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->G); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0+dlsch_thread_index,1); - ret = dlsch_decoding(phy_vars_ue, - phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->llr[0], - &phy_vars_ue->lte_frame_parms, - phy_vars_ue->dlsch_ue[eNB_id][0], - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid], - dlsch_subframe[dlsch_thread_index], - harq_pid, - 1, // is_crnti - 0); // llr8_flag - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0+dlsch_thread_index,0); - - LOG_D(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: PDSCH/DLSCH decoding iter %d (mcs %d, rv %d, TBS %d)\n", - phy_vars_ue->Mod_id, - phy_vars_ue->dlsch_ue[eNB_id][0]->rnti,harq_pid, - phy_vars_ue->frame_rx,dlsch_subframe[dlsch_thread_index],ret, - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->mcs, - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->rvidx, - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->TBS); - - - if (ret == (1+MAX_TURBO_ITERATIONS)) { - phy_vars_ue->dlsch_errors[eNB_id]++; - -#ifdef DEBUG_PHY - LOG_I(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d DLSCH in error (rv %d,mcs %d)\n", - phy_vars_ue->Mod_id,phy_vars_ue->dlsch_ue[eNB_id][0]->rnti, - harq_pid,phy_vars_ue->frame_rx,dlsch_subframe[dlsch_thread_index], - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->rvidx, - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->mcs); -#endif - } else { - LOG_I(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH (rv %d,mcs %d)\n", - phy_vars_ue->Mod_id,phy_vars_ue->dlsch_ue[eNB_id][0]->rnti, - harq_pid,phy_vars_ue->frame_rx,dlsch_subframe[dlsch_thread_index], - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->rvidx, - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->mcs); - -#ifdef OPENAIR2 - mac_xface->ue_send_sdu(phy_vars_ue->Mod_id, - 0, // CC_id - phy_vars_ue->frame_rx, - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->b, - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->TBS>>3, - eNB_id); -#endif - phy_vars_ue->total_TBS[eNB_id] = phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->TBS + phy_vars_ue->total_TBS[eNB_id]; - phy_vars_ue->total_received_bits[eNB_id] = phy_vars_ue->total_received_bits[eNB_id] + phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->TBS; - } - } - - // this is done in main thread - /* - if (phy_vars_ue->frame % 100 == 0) { - if ((phy_vars_ue->dlsch_received[eNB_id] - phy_vars_ue->dlsch_received_last[eNB_id]) != 0) - phy_vars_ue->dlsch_fer[eNB_id] = (100*(phy_vars_ue->dlsch_errors[eNB_id] - phy_vars_ue->dlsch_errors_last[eNB_id]))/(phy_vars_ue->dlsch_received[eNB_id] - phy_vars_ue->dlsch_received_last[eNB_id]); - phy_vars_ue->dlsch_errors_last[eNB_id] = phy_vars_ue->dlsch_errors[eNB_id]; - phy_vars_ue->dlsch_received_last[eNB_id] = phy_vars_ue->dlsch_received[eNB_id]; - } - */ - - -#ifdef DEBUG_PHY - - if (phy_vars_ue->dlsch_ue[eNB_id][0]) { - LOG_I(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: PDSCH/DLSCH decoding iter %d (mcs %d, rv %d, TBS %d)\n", - phy_vars_ue->Mod_id, - phy_vars_ue->dlsch_ue[eNB_id][0]->rnti,harq_pid, - phy_vars_ue->frame_rx,dlsch_subframe[dlsch_thread_index],ret, - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->mcs, - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->rvidx, - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->TBS); - - if (phy_vars_ue->frame_rx%100==0) { - LOG_D(PHY,"[UE %d][PDSCH %x] Frame %d subframe %d dlsch_errors %d, dlsch_received %d, dlsch_fer %d, current_dlsch_cqi %d\n", - phy_vars_ue->Mod_id,phy_vars_ue->dlsch_ue[eNB_id][0]->rnti, - phy_vars_ue->frame_rx,dlsch_subframe[dlsch_thread_index], - phy_vars_ue->dlsch_errors[eNB_id], - phy_vars_ue->dlsch_received[eNB_id], - phy_vars_ue->dlsch_fer[eNB_id], - phy_vars_ue->PHY_measurements.wideband_cqi_tot[eNB_id]); - } - } else { - LOG_I( PHY,"[UE %d][PDSCH ?/%d] Frame %d subframe %d: PDSCH/DLSCH decoding iter %d (phy_vars_ue->dlsch_ue[eNB_id][0] == 0)\n", - phy_vars_ue->Mod_id, - harq_pid, - phy_vars_ue->frame_rx, dlsch_subframe[dlsch_thread_index], ret ); - } - -#endif - - if (pthread_mutex_lock(&dlsch_mutex[dlsch_thread_index]) != 0) { - msg("[openair][SCHED][DLSCH] error locking mutex.\n"); - } else { - dlsch_instance_cnt[dlsch_thread_index]--; - - if (pthread_mutex_unlock(&dlsch_mutex[dlsch_thread_index]) != 0) { - msg("[openair][SCHED][DLSCH] error unlocking mutex.\n"); - } - } - - } - -#ifdef HARD_RT - rt_make_soft_real_time(); -#endif - - msg("[openair][SCHED][DLSCH] DLSCH thread %d exiting\n",dlsch_thread_index); - - return 0; -} - -int init_dlsch_threads(void) -{ - - int error_code; - struct sched_param p; - unsigned char dlsch_thread_index; - - pthread_attr_init (&attr_dlsch_threads); - pthread_attr_setstacksize(&attr_dlsch_threads,OPENAIR_THREAD_STACK_SIZE); - //attr_dlsch_threads.priority = 1; - - p.sched_priority = OPENAIR_THREAD_PRIORITY; - pthread_attr_setschedparam (&attr_dlsch_threads, &p); -#ifndef RTAI_ISNT_POSIX - pthread_attr_setschedpolicy (&attr_dlsch_threads, SCHED_FIFO); -#endif - - for(dlsch_thread_index=0; dlsch_thread_index<8; dlsch_thread_index++) { - - pthread_mutex_init(&dlsch_mutex[dlsch_thread_index],NULL); - pthread_cond_init(&dlsch_cond[dlsch_thread_index],NULL); - - dlsch_instance_cnt[dlsch_thread_index] = -1; - dlsch_thread_indices[dlsch_thread_index] = dlsch_thread_index; - rt_printk("[openair][SCHED][DLSCH][INIT] Allocating DLSCH thread for dlsch_thread_index %d (%p)\n",dlsch_thread_index,&dlsch_thread_indices[dlsch_thread_index]); - error_code = pthread_create(&dlsch_threads[dlsch_thread_index], - &attr_dlsch_threads, - dlsch_thread, - (void *)&dlsch_thread_indices[dlsch_thread_index]); - - if (error_code!= 0) { - rt_printk("[openair][SCHED][DLSCH][INIT] Could not allocate dlsch_thread %d, error %d\n",dlsch_thread_index,error_code); - return(error_code); - } else { - rt_printk("[openair][SCHED][DLSCH][INIT] Allocate dlsch_thread %d successful\n",dlsch_thread_index); - } - } - - return(0); -} - -void cleanup_dlsch_threads(void) -{ - - unsigned char dlsch_thread_index; - - for(dlsch_thread_index=0; dlsch_thread_index<8; dlsch_thread_index++) { - // pthread_exit(&dlsch_threads[dlsch_thread_index]); - rt_printk("[openair][SCHED][DLSCH] Scheduling dlsch_thread %d to exit\n",dlsch_thread_index); - - dlsch_instance_cnt[dlsch_thread_index] = 0; - - if (pthread_cond_signal(&dlsch_cond[dlsch_thread_index]) != 0) - rt_printk("[openair][SCHED][DLSCH] ERROR pthread_cond_signal\n"); - else - rt_printk("[openair][SCHED][DLSCH] Signalled dlsch_thread %d to exit\n",dlsch_thread_index); - - rt_printk("[openair][SCHED][DLSCH] Exiting ...\n"); - pthread_cond_destroy(&dlsch_cond[dlsch_thread_index]); - pthread_mutex_destroy(&dlsch_mutex[dlsch_thread_index]); - } -} diff --git a/targets/RT/USER/sched_rx_pdsch.c b/targets/RT/USER/sched_rx_pdsch.c deleted file mode 100644 index e792fe737d..0000000000 --- a/targets/RT/USER/sched_rx_pdsch.c +++ /dev/null @@ -1,321 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -/*! \file sched_dlsch.c -* \brief DLSCH decoding thread (RTAI) -* \author R. Knopp, F. Kaltenberger -* \date 2011 -* \version 0.1 -* \company Eurecom -* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr -* \note -* \warning -*/ -#include <stdio.h> -#include <stdlib.h> -#include <sched.h> - -#include "rt_wrapper.h" - -#include <sys/mman.h> - -#include "PHY/types.h" -#include "PHY/defs.h" -#include "PHY/extern.h" -#include "SCHED/defs.h" -#include "SCHED/extern.h" - -#include "UTIL/LOG/vcd_signal_dumper.h" - -RTIME time0,time1; - -#define DEBUG_PHY - -/// Mutex for instance count on rx_pdsch scheduling -pthread_mutex_t rx_pdsch_mutex; -/// Condition variable for rx_pdsch thread -pthread_cond_t rx_pdsch_cond; - -pthread_t rx_pdsch_thread_var; -pthread_attr_t attr_rx_pdsch_thread; - -// activity indicators for harq_pid's -int rx_pdsch_instance_cnt; -// process ids for cpu -int rx_pdsch_cpuid; -// subframe number for each harq_pid (needed to store ack in right place for UL) -int rx_pdsch_slot; - -extern int oai_exit; -extern pthread_mutex_t dlsch_mutex[8]; -extern int dlsch_instance_cnt[8]; -extern int dlsch_subframe[8]; -extern pthread_cond_t dlsch_cond[8]; - -/** RX_PDSCH Decoding Thread */ -static void * rx_pdsch_thread(void *param) -{ - - //unsigned long cpuid; - uint8_t dlsch_thread_index = 0; - uint8_t pilot2,harq_pid,subframe; - // uint8_t last_slot; - - uint8_t dual_stream_UE = 0; - uint8_t i_mod = 0; - - -#ifdef RTAI - RT_TASK *task; -#endif - - int m,eNB_id = 0; - int eNB_id_i = 1; - PHY_VARS_UE *UE = PHY_vars_UE_g[0][0]; - -#ifdef RTAI - task = rt_task_init_schmod(nam2num("RX_PDSCH_THREAD"), 0, 0, 0, SCHED_FIFO, 0xF); - - if (task==NULL) { - LOG_E(PHY,"[SCHED][RX_PDSCH] Problem starting rx_pdsch thread!!!!\n"); - return 0; - } else { - LOG_I(PHY,"[SCHED][RX_PDSCH] rx_pdsch_thread started for with id %p\n",task); - } - -#endif - - mlockall(MCL_CURRENT | MCL_FUTURE); - - //rt_set_runnable_on_cpuid(task,1); - //cpuid = rtai_cpuid(); - -#ifdef HARD_RT - rt_make_hard_real_time(); -#endif - - if (UE->lte_frame_parms.Ncp == NORMAL) { // normal prefix - pilot2 = 7; - } else { // extended prefix - pilot2 = 6; - } - - - while (!oai_exit) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_THREAD, 0); - - if (pthread_mutex_lock(&rx_pdsch_mutex) != 0) { - LOG_E(PHY,"[SCHED][RX_PDSCH] error locking mutex.\n"); - } else { - while (rx_pdsch_instance_cnt < 0) { - pthread_cond_wait(&rx_pdsch_cond,&rx_pdsch_mutex); - } - - if (pthread_mutex_unlock(&rx_pdsch_mutex) != 0) { - LOG_E(PHY,"[SCHED][RX_PDSCH] error unlocking mutex.\n"); - } - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_THREAD, 1); - - // last_slot = rx_pdsch_slot; - subframe = UE->slot_rx>>1; - // Important! assumption that PDCCH procedure of next SF is not called yet - harq_pid = UE->dlsch_ue[eNB_id][0]->current_harq_pid; - UE->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->G = get_G(&UE->lte_frame_parms, - UE->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->nb_rb, - UE->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, - get_Qm(UE->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->mcs), - UE->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->Nl, - UE->lte_ue_pdcch_vars[eNB_id]->num_pdcch_symbols, - UE->frame_rx,subframe); - - if ((UE->transmission_mode[eNB_id] == 5) && - (UE->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->dl_power_off==0) && - (openair_daq_vars.use_ia_receiver > 0)) { - dual_stream_UE = 1; - eNB_id_i = UE->n_connected_eNB; - - if (openair_daq_vars.use_ia_receiver == 2) { - i_mod = get_Qm(((UE->frame_rx%1024)/3)%28); - } else { - i_mod = get_Qm(UE->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->mcs); - } - } else { - dual_stream_UE = 0; - eNB_id_i = eNB_id+1; - i_mod = 0; - } - - if (oai_exit) break; - - LOG_D(PHY,"[SCHED][RX_PDSCH] Frame %d, slot %d: Calling rx_pdsch_decoding with harq_pid %d\n",UE->frame_rx,UE->slot_rx,harq_pid); - - - // Check if we are in even or odd slot - if (UE->slot_rx%2) { // odd slots - - // measure time - //time0 = rt_get_time_ns(); - // rt_printk("[SCHED][RX_PDSCH][before rx_pdsch] Frame %d, slot %d, time %llu\n",UE->frame,last_slot,rt_get_time_ns()); - for (m=pilot2; m<UE->lte_frame_parms.symbols_per_tti; m++) { - - rx_pdsch(UE, - PDSCH, - eNB_id, - eNB_id_i, - subframe, - m, - 0, - dual_stream_UE, - i_mod, - harq_pid); - - } - - // time1 = rt_get_time_ns(); - // rt_printk("[SCHED][RX_PDSCH] Frame %d, slot %d, start %llu, end %llu, proc time: %llu ns\n",UE->frame_rx,last_slot,time0,time1,(time1-time0)); - - dlsch_thread_index = harq_pid; - - if (pthread_mutex_lock (&dlsch_mutex[dlsch_thread_index]) != 0) { // Signal MAC_PHY Scheduler - LOG_E(PHY,"[UE %d] ERROR pthread_mutex_lock\n",UE->Mod_id); // lock before accessing shared resource - // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); - //return(-1); - } - - dlsch_instance_cnt[dlsch_thread_index]++; - dlsch_subframe[dlsch_thread_index] = subframe; - pthread_mutex_unlock (&dlsch_mutex[dlsch_thread_index]); - - if (dlsch_instance_cnt[dlsch_thread_index] == 0) { - if (pthread_cond_signal(&dlsch_cond[dlsch_thread_index]) != 0) { - LOG_E(PHY,"[UE %d] ERROR pthread_cond_signal for dlsch_cond[%d]\n",UE->Mod_id,dlsch_thread_index); - // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); - //return(-1); - } - } else { - LOG_W(PHY,"[UE %d] DLSCH thread for dlsch_thread_index %d busy!!!\n",UE->Mod_id,dlsch_thread_index); - // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); - //return(-1); - } - - } else { // even slots - - for (m=UE->lte_ue_pdcch_vars[eNB_id]->num_pdcch_symbols; m<pilot2; m++) { - - rx_pdsch(UE, - PDSCH, - eNB_id, - eNB_id_i, - subframe, - m, - (m==UE->lte_ue_pdcch_vars[eNB_id]->num_pdcch_symbols)?1:0, // first_symbol_flag - dual_stream_UE, - i_mod, - harq_pid); - } - } - - - if (pthread_mutex_lock(&rx_pdsch_mutex) != 0) { - msg("[openair][SCHED][RX_PDSCH] error locking mutex.\n"); - } else { - rx_pdsch_instance_cnt--; - - if (pthread_mutex_unlock(&rx_pdsch_mutex) != 0) { - msg("[openair][SCHED][RX_PDSCH] error unlocking mutex.\n"); - } - } - - } - -#ifdef HARD_RT - rt_make_soft_real_time(); -#endif - - LOG_D(PHY,"[openair][SCHED][RX_PDSCH] RX_PDSCH thread exiting\n"); - - return 0; -} - -int init_rx_pdsch_thread(void) -{ - - int error_code; - struct sched_param p; - - pthread_mutex_init(&rx_pdsch_mutex,NULL); - - pthread_cond_init(&rx_pdsch_cond,NULL); - - pthread_attr_init (&attr_rx_pdsch_thread); - pthread_attr_setstacksize(&attr_rx_pdsch_thread,OPENAIR_THREAD_STACK_SIZE); - - //attr_rx_pdsch_thread.priority = 1; - - p.sched_priority = OPENAIR_THREAD_PRIORITY; - pthread_attr_setschedparam (&attr_rx_pdsch_thread, &p); -#ifndef RTAI_ISNT_POSIX - pthread_attr_setschedpolicy (&attr_rx_pdsch_thread, SCHED_FIFO); -#endif - - rx_pdsch_instance_cnt = -1; - rt_printk("[openair][SCHED][RX_PDSCH][INIT] Allocating RX_PDSCH thread\n"); - error_code = pthread_create(&rx_pdsch_thread_var, - &attr_rx_pdsch_thread, - rx_pdsch_thread, - 0); - - if (error_code!= 0) { - rt_printk("[openair][SCHED][RX_PDSCH][INIT] Could not allocate rx_pdsch_thread, error %d\n",error_code); - return(error_code); - } else { - rt_printk("[openair][SCHED][RX_PDSCH][INIT] Allocate rx_pdsch_thread successful\n"); - return(0); - } - -} - -void cleanup_rx_pdsch_thread(void) -{ - - rt_printk("[openair][SCHED][RX_PDSCH] Scheduling rx_pdsch_thread to exit\n"); - - rx_pdsch_instance_cnt = 0; - - if (pthread_cond_signal(&rx_pdsch_cond) != 0) - rt_printk("[openair][SCHED][RX_PDSCH] ERROR pthread_cond_signal\n"); - else - rt_printk("[openair][SCHED][RX_PDSCH] Signalled rx_pdsch_thread to exit\n"); - - rt_printk("[openair][SCHED][RX_PDSCH] Exiting ...\n"); - pthread_cond_destroy(&rx_pdsch_cond); - pthread_mutex_destroy(&rx_pdsch_mutex); -} diff --git a/targets/RT/USER/sched_ulsch.c b/targets/RT/USER/sched_ulsch.c deleted file mode 100644 index 3ab0c312f5..0000000000 --- a/targets/RT/USER/sched_ulsch.c +++ /dev/null @@ -1,255 +0,0 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ - -/*! \file sched_ulsch.c -* \brief ULSCH decoding thread (RTAI) -* \author R. Knopp, F. Kaltenberger -* \date 2011 -* \version 0.1 -* \company Eurecom -* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr -* \note -* \warning -*/ -#include <stdio.h> -#include <stdlib.h> -#include <sched.h> - -#include "rt_wrapper.h" - -#include <sys/mman.h> - -#include "PHY/types.h" -#include "PHY/defs.h" -#include "PHY/extern.h" - -#include "SCHED/defs.h" - -#include "MAC_INTERFACE/extern.h" - -#ifdef CBMIMO1 -#include "ARCH/CBMIMO1/DEVICE_DRIVER/cbmimo1_device.h" -#include "ARCH/CBMIMO1/DEVICE_DRIVER/extern.h" -#include "ARCH/CBMIMO1/DEVICE_DRIVER/defs.h" -#endif // CBMIMO1 - - - -#define DEBUG_PHY - -/// Mutex for instance count on ulsch scheduling -pthread_mutex_t ulsch_mutex[NUMBER_OF_UE_MAX]; -/// Condition variable for ulsch thread -pthread_cond_t ulsch_cond[NUMBER_OF_UE_MAX]; - -pthread_t ulsch_threads[NUMBER_OF_UE_MAX]; -pthread_attr_t attr_ulsch_threads; - -// activity indicators for harq_pid's -int ulsch_instance_cnt[NUMBER_OF_UE_MAX]; -// process ids for cpu -int ulsch_cpuid[NUMBER_OF_UE_MAX]; -// subframe number for each harq_pid (needed to store ack in right place for UL) -int ulsch_subframe[NUMBER_OF_UE_MAX]; - -extern int oai_exit; - -/* -extern int ulsch_errors; -extern int ulsch_received; -extern int ulsch_errors_last; -extern int ulsch_received_last; -extern int ulsch_fer; -extern int current_ulsch_cqi; -*/ - -/** ULSCH Decoding Thread */ -static void * ulsch_thread(void *param) -{ - - //unsigned long cpuid; - unsigned int ulsch_thread_index = (unsigned int)param; - - RTIME time_in,time_out; -#ifdef RTAI - RT_TASK *task; - char ulsch_thread_name[64]; -#endif - - int eNB_id = 0, UE_id = 0; - PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[eNB_id]; - - if ((ulsch_thread_index <0) || (ulsch_thread_index>NUMBER_OF_UE_MAX)) { - LOG_E(PHY,"[SCHED][ULSCH] Illegal ulsch_thread_index %d!!!!\n",ulsch_thread_index); - return 0; - } - -#ifdef RTAI - sprintf(ulsch_thread_name,"ULSCH_THREAD%d",ulsch_thread_index); - - LOG_I(PHY,"[SCHED][ULSCH] starting ulsch_thread %s for process %d\n", - ulsch_thread_name, - ulsch_thread_index); - - task = rt_task_init_schmod(nam2num(ulsch_thread_name), 0, 0, 0, SCHED_FIFO, 0xF); - - if (task==NULL) { - LOG_E(PHY,"[SCHED][ULSCH] Problem starting ulsch_thread_index %d!!!!\n",ulsch_thread_index); - return 0; - } else { - LOG_I(PHY,"[SCHED][ULSCH] ulsch_thread for process %d started with id %p\n", - ulsch_thread_index, - task); - } - -#endif - - mlockall(MCL_CURRENT | MCL_FUTURE); - - //rt_set_runnable_on_cpuid(task,1); - //cpuid = rtai_cpuid(); - -#ifdef HARD_RT - rt_make_hard_real_time(); -#endif - - //ulsch_cpuid[ulsch_thread_index] = cpuid; - - while (!oai_exit) { - - if (pthread_mutex_lock(&ulsch_mutex[ulsch_thread_index]) != 0) { - LOG_E(PHY,"[SCHED][ULSCH] error locking mutex.\n"); - } else { - - while (ulsch_instance_cnt[ulsch_thread_index] < 0) { - pthread_cond_wait(&ulsch_cond[ulsch_thread_index],&ulsch_mutex[ulsch_thread_index]); - } - - if (pthread_mutex_unlock(&ulsch_mutex[ulsch_thread_index]) != 0) { - LOG_E(PHY,"[SCHED][ULSCH] error unlocking mutex.\n"); - } - } - - if (oai_exit) break; - - LOG_D(PHY,"[SCHED][ULSCH] Frame %d: Calling ulsch_decoding with ulsch_thread_index = %d\n",phy_vars_eNB->proc[0].frame_tx,ulsch_thread_index); - - time_in = rt_get_time_ns(); - - ulsch_decoding_procedures(ulsch_subframe[ulsch_thread_index]<<1,ulsch_thread_index,phy_vars_eNB,0); - - time_out = rt_get_time_ns(); - - if (pthread_mutex_lock(&ulsch_mutex[ulsch_thread_index]) != 0) { - msg("[openair][SCHED][ULSCH] error locking mutex.\n"); - } else { - ulsch_instance_cnt[ulsch_thread_index]--; - - if (pthread_mutex_unlock(&ulsch_mutex[ulsch_thread_index]) != 0) { - msg("[openair][SCHED][ULSCH] error unlocking mutex.\n"); - } - } - } - -#ifdef HARD_RT - rt_make_soft_real_time(); -#endif - - msg("[openair][SCHED][ULSCH] ULSCH thread %d exiting\n",ulsch_thread_index); - - return 0; -} - -int init_ulsch_threads(void) -{ - - int error_code, return_code=0; - struct sched_param p; - int ulsch_thread_index; - - // later loop on all harq_pids, do 0 for now - for (ulsch_thread_index=0; ulsch_thread_index<NUMBER_OF_UE_MAX; ulsch_thread_index++) { - - pthread_mutex_init(&ulsch_mutex[ulsch_thread_index],NULL); - - pthread_cond_init(&ulsch_cond[ulsch_thread_index],NULL); - - pthread_attr_init (&attr_ulsch_threads); - pthread_attr_setstacksize(&attr_ulsch_threads,OPENAIR_THREAD_STACK_SIZE); - - //attr_ulsch_threads.priority = 1; - - p.sched_priority = OPENAIR_THREAD_PRIORITY; - pthread_attr_setschedparam (&attr_ulsch_threads, &p); -#ifndef RTAI_ISNT_POSIX - pthread_attr_setschedpolicy (&attr_ulsch_threads, SCHED_FIFO); -#endif - - ulsch_instance_cnt[ulsch_thread_index] = -1; - rt_printk("[openair][SCHED][ULSCH][INIT] Allocating ULSCH thread for ulsch_thread_index %d\n",ulsch_thread_index); - error_code = pthread_create(&ulsch_threads[ulsch_thread_index], - &attr_ulsch_threads, - ulsch_thread, - (void *)ulsch_thread_index); - - if (error_code!= 0) { - rt_printk("[openair][SCHED][ULSCH][INIT] Could not allocate ulsch_thread %d, error %d\n",ulsch_thread_index,error_code); - return_code+=error_code; - //return(error_code); - } else { - rt_printk("[openair][SCHED][ULSCH][INIT] Allocate ulsch_thread %d successful\n",ulsch_thread_index); - //return(0); - } - } - - return(return_code); -} - -void cleanup_ulsch_threads(void) -{ - - int ulsch_thread_index; - - for (ulsch_thread_index=0; ulsch_thread_index<NUMBER_OF_UE_MAX; ulsch_thread_index++) { - - // pthread_exit(&ulsch_threads[ulsch_thread_index]); - rt_printk("[openair][SCHED][ULSCH] Scheduling ulsch_thread %d to exit\n",ulsch_thread_index); - - ulsch_instance_cnt[ulsch_thread_index] = 0; - - if (pthread_cond_signal(&ulsch_cond[ulsch_thread_index]) != 0) - rt_printk("[openair][SCHED][ULSCH] ERROR pthread_cond_signal\n"); - else - rt_printk("[openair][SCHED][ULSCH] Signalled ulsch_thread %d to exit\n",ulsch_thread_index); - - rt_printk("[openair][SCHED][ULSCH] Exiting ...\n"); - pthread_cond_destroy(&ulsch_cond[ulsch_thread_index]); - pthread_mutex_destroy(&ulsch_mutex[ulsch_thread_index]); - } -} -- GitLab