From 22e7b1e6da306056819c5562e4c7d124455dfe8f Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Thu, 14 Dec 2017 15:29:05 +0100 Subject: [PATCH] extending dlsch_coding into four thread --- openair1/PHY/LTE_TRANSPORT/dlsch_coding.c | 172 +++++++++++++++++++++- openair1/PHY/defs.h | 14 +- openair1/SCHED/phy_procedures_lte_eNb.c | 10 ++ targets/RT/USER/lte-ru.c | 2 +- 4 files changed, 182 insertions(+), 16 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index dfedb97e9c..5438dd5f9f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -291,7 +291,7 @@ int dlsch_encoding_2threads0(te_params *tep) { if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet - for (r=0; rharq_processes[harq_pid]->C/3; r++) { + for (r=0; r<(dlsch->harq_processes[harq_pid]->C>>2); r++) { if (rharq_processes[harq_pid]->Cminus) Kr = dlsch->harq_processes[harq_pid]->Kminus; @@ -334,7 +334,7 @@ int dlsch_encoding_2threads0(te_params *tep) { // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the // outputs for each code segment, see Section 5.1.5 p.20 - for (r=0; rharq_processes[harq_pid]->C/3; r++) { + for (r=0; r<(dlsch->harq_processes[harq_pid]->C>>2); r++) { r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r], G, //G dlsch->harq_processes[harq_pid]->w[r], @@ -373,7 +373,7 @@ int dlsch_encoding_2threads1(te_params *tep) { if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet - for (r=dlsch->harq_processes[harq_pid]->C/3; rharq_processes[harq_pid]->C/3*2; r++) { + for (r=(dlsch->harq_processes[harq_pid]->C>>2); r<(dlsch->harq_processes[harq_pid]->C>>1); r++) { if (rharq_processes[harq_pid]->Cminus) Kr = dlsch->harq_processes[harq_pid]->Kminus; @@ -416,8 +416,103 @@ int dlsch_encoding_2threads1(te_params *tep) { // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the // outputs for each code segment, see Section 5.1.5 p.20 - for (r=0,r_offset=0; rharq_processes[harq_pid]->C/3*2; r++) { - if(r<(dlsch->harq_processes[harq_pid]->C/3)){ + for (r=0,r_offset=0; r<(dlsch->harq_processes[harq_pid]->C>>1); r++) { + if(r<(dlsch->harq_processes[harq_pid]->C>>2)){ + int Nl=dlsch->harq_processes[harq_pid]->Nl; + int Qm=dlsch->harq_processes[harq_pid]->Qm; + int C = dlsch->harq_processes[harq_pid]->C; + int Gp = G/Nl/Qm; + int GpmodC = Gp%C; + if (r < (C-(GpmodC))) + r_offset += Nl*Qm * (Gp/C); + else + r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C)); + } + else{ + r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r], + G, //G + dlsch->harq_processes[harq_pid]->w[r], + dlsch->harq_processes[harq_pid]->e+r_offset, + dlsch->harq_processes[harq_pid]->C, // C + dlsch->Nsoft, // Nsoft, + dlsch->Mdlharq, + dlsch->Kmimo, + dlsch->harq_processes[harq_pid]->rvidx, + dlsch->harq_processes[harq_pid]->Qm, + dlsch->harq_processes[harq_pid]->Nl, + r, + nb_rb); + // m); // r + } + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_OUT); + + return(0); +} + +int dlsch_encoding_2threads2(te_params *tep) { + + LTE_eNB_DLSCH_t *dlsch = tep->dlsch; + unsigned int G = tep->G; + unsigned char harq_pid = tep->harq_pid; + + unsigned short iind; + + unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb; + unsigned int Kr=0,Kr_bytes,r,r_offset=0; + // unsigned short m=dlsch->harq_processes[harq_pid]->mcs; + + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_IN); + + if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet + + for (r=(dlsch->harq_processes[harq_pid]->C>>1); r<(dlsch->harq_processes[harq_pid]->C>>2)*3; r++) { + + if (rharq_processes[harq_pid]->Cminus) + Kr = dlsch->harq_processes[harq_pid]->Kminus; + else + Kr = dlsch->harq_processes[harq_pid]->Kplus; + + Kr_bytes = Kr>>3; + + // get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14) + if (Kr_bytes<=64) + iind = (Kr_bytes-5); + else if (Kr_bytes <=128) + iind = 59 + ((Kr_bytes-64)>>1); + else if (Kr_bytes <= 256) + iind = 91 + ((Kr_bytes-128)>>2); + else if (Kr_bytes <= 768) + iind = 123 + ((Kr_bytes-256)>>3); + else { + printf("dlsch_coding: Illegal codeword size %d!!!\n",Kr_bytes); + return(-1); + } + + + + threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r], + Kr>>3, + &dlsch->harq_processes[harq_pid]->d[r][96], + (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, + f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) + f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) + ); + dlsch->harq_processes[harq_pid]->RTC[r] = + sub_block_interleaving_turbo(4+(Kr_bytes*8), + &dlsch->harq_processes[harq_pid]->d[r][96], + dlsch->harq_processes[harq_pid]->w[r]); + } + + } + + // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the + // outputs for each code segment, see Section 5.1.5 p.20 + + for (r=0,r_offset=0; r<(dlsch->harq_processes[harq_pid]->C>>2)*3; r++) { + if(r<(dlsch->harq_processes[harq_pid]->C>>1)){ int Nl=dlsch->harq_processes[harq_pid]->Nl; int Qm=dlsch->harq_processes[harq_pid]->Qm; int C = dlsch->harq_processes[harq_pid]->C; @@ -529,6 +624,41 @@ void *te_thread1(void *param) { return(NULL); } +void *te_thread2(void *param) { + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + + thread_top_init("te_thread2",1,200000,250000,500000); + pthread_setname_np( pthread_self(),"te processing 2"); + LOG_I(PHY,"thread te 2 created id=%ld\n", syscall(__NR_gettid)); + + //CPU_SET(7, &cpuset); + //pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + + PHY_VARS_eNB *eNB = ((te_params *)param)->eNB; + eNB_proc_t *proc = &eNB->proc; + time_stats_t *te_wakeup_stats1 = &eNB->dlsch_turbo_encoding_wakeup_stats1; + while (!oai_exit) { + + + if (wait_on_condition(&proc->mutex_te[2],&proc->cond_te[2],&proc->instance_cnt_te[2],"te thread 2")<0) break; + + //stop_meas(te_wakeup_stats1); + dlsch_encoding_2threads1((te_params*)param); + + + if (release_thread(&proc->mutex_te[2],&proc->instance_cnt_te[2],"te thread 2")<0) break; + + if (pthread_cond_signal(&proc->cond_te[2]) != 0) { + printf("[eNB] ERROR pthread_cond_signal for te thread 1 exit\n"); + exit_fun( "ERROR pthread_cond_signal" ); + return(NULL); + } + } + + return(NULL); +} + int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, unsigned char *a, uint8_t num_pdcch_symbols, @@ -611,7 +741,7 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, pthread_mutex_unlock( &proc->mutex_te[0] ); //////////////////////////////////////////////////////////////// - if (proc->instance_cnt_te[1]==0) { + if (proc->instance_cnt_te[1]==0) { printf("[eNB] TE thread busy\n"); exit_fun("TE thread busy"); pthread_mutex_unlock( &proc->mutex_te[1] ); @@ -635,7 +765,32 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, pthread_mutex_unlock( &proc->mutex_te[1] ); - for (r=dlsch->harq_processes[harq_pid]->C/3*2; rharq_processes[harq_pid]->C; r++) { +//////////////////////////////////////////////////////////////// + if (proc->instance_cnt_te[2]==0) { + printf("[eNB] TE thread busy\n"); + exit_fun("TE thread busy"); + pthread_mutex_unlock( &proc->mutex_te[2] ); + return(-1); + } + + ++proc->instance_cnt_te[2]; + + proc->tep[2].eNB = eNB; + proc->tep[2].dlsch = dlsch; + proc->tep[2].G = G; + proc->tep[2].harq_pid = harq_pid; + + // wakeup worker to do second half segments + if (pthread_cond_signal(&proc->cond_te[2]) != 0) { + printf("[eNB] ERROR pthread_cond_signal for te thread exit\n"); + exit_fun( "ERROR pthread_cond_signal" ); + return (-1); + } + + pthread_mutex_unlock( &proc->mutex_te[2] ); +//////////////////////////////////////////////////////////////// + + for (r=(dlsch->harq_processes[harq_pid]->C>>2)*3; rharq_processes[harq_pid]->C; r++) { if (rharq_processes[harq_pid]->Cminus) Kr = dlsch->harq_processes[harq_pid]->Kminus; @@ -707,7 +862,7 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, for (r=0,r_offset=0; rharq_processes[harq_pid]->C; r++) { // get information for E for the segments that are handled by the worker thread - if (r<(dlsch->harq_processes[harq_pid]->C/3*2)) { + if (r<(dlsch->harq_processes[harq_pid]->C>>2)*3) { int Nl=dlsch->harq_processes[harq_pid]->Nl; int Qm=dlsch->harq_processes[harq_pid]->Qm; int C = dlsch->harq_processes[harq_pid]->C; @@ -742,6 +897,7 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, start_meas(te_wait_stats); wait_on_busy_condition(&proc->mutex_te[0],&proc->cond_te[0],&proc->instance_cnt_te[0],"te thread"); wait_on_busy_condition(&proc->mutex_te[1],&proc->cond_te[1],&proc->instance_cnt_te[1],"te thread1"); + wait_on_busy_condition(&proc->mutex_te[2],&proc->cond_te[2],&proc->instance_cnt_te[2],"te thread2"); stop_meas(te_wait_stats); if(opp_enabled == 1 && te_wait_stats->diff_now>100*3000){ print_meas_now(te_wait_stats,"coding_wait",stderr); diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 4339d98b24..3e35705c01 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -471,7 +471,7 @@ typedef struct eNB_proc_t_s { /// \internal This variable is protected by \ref mutex_td. int instance_cnt_td; /// \internal This variable is protected by \ref mutex_te. - int instance_cnt_te[2]; + int instance_cnt_te[3]; /// \internal This variable is protected by \ref mutex_prach. int instance_cnt_prach; #ifdef Rel14 @@ -493,7 +493,7 @@ typedef struct eNB_proc_t_s { /// pthread attributes for parallel turbo-decoder thread pthread_attr_t attr_td; /// pthread attributes for parallel turbo-encoder thread - pthread_attr_t attr_te[2]; + pthread_attr_t attr_te[3]; /// pthread attributes for single eNB processing thread pthread_attr_t attr_single; /// pthread attributes for prach processing thread @@ -507,7 +507,7 @@ typedef struct eNB_proc_t_s { /// scheduling parameters for parallel turbo-decoder thread struct sched_param sched_param_td; /// scheduling parameters for parallel turbo-encoder thread - struct sched_param sched_param_te[2]; + struct sched_param sched_param_te[3]; /// scheduling parameters for single eNB thread struct sched_param sched_param_single; /// scheduling parameters for prach thread @@ -521,7 +521,7 @@ typedef struct eNB_proc_t_s { /// pthread structure for parallel turbo-decoder thread pthread_t pthread_td; /// pthread structure for parallel turbo-encoder thread - pthread_t pthread_te[2]; + pthread_t pthread_te[3]; /// pthread structure for PRACH thread pthread_t pthread_prach; #ifdef Rel14 @@ -531,7 +531,7 @@ typedef struct eNB_proc_t_s { /// condition variable for parallel turbo-decoder thread pthread_cond_t cond_td; /// condition variable for parallel turbo-encoder thread - pthread_cond_t cond_te[2]; + pthread_cond_t cond_te[3]; /// condition variable for PRACH processing thread; pthread_cond_t cond_prach; #ifdef Rel14 @@ -543,7 +543,7 @@ typedef struct eNB_proc_t_s { /// mutex for parallel turbo-decoder thread pthread_mutex_t mutex_td; /// mutex for parallel turbo-encoder thread - pthread_mutex_t mutex_te[2]; + pthread_mutex_t mutex_te[3]; /// mutex for PRACH thread pthread_mutex_t mutex_prach; #ifdef Rel14 @@ -569,7 +569,7 @@ typedef struct eNB_proc_t_s { /// parameters for turbo-decoding worker thread td_params tdp; /// parameters for turbo-encoding worker thread - te_params tep[2]; + te_params tep[3]; /// set of scheduling variables RXn-TXnp4 threads eNB_rxtx_proc_t proc_rxtx[2]; /// stats thread pthread descriptor diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 57e93fd6c2..838dc5d39e 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -1507,6 +1507,7 @@ void init_td_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_td) { extern void *te_thread(void*); extern void *te_thread1(void*); +extern void *te_thread2(void*); void init_te_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_te,pthread_attr_t *attr_te1) { @@ -1530,7 +1531,16 @@ void init_te_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_te,pthread_attr_t *at printf("Creating te_thread1\n"); pthread_create(&proc->pthread_te[1], attr_te1, te_thread1, (void*)&proc->tep[1]); + + ///////////////////////////////////////////////////////////////////////// + proc->tep[2].eNB = eNB; + proc->instance_cnt_te[2] = -1; + + pthread_mutex_init( &proc->mutex_te[2], NULL); + pthread_cond_init( &proc->cond_te[2], NULL); + printf("Creating te_thread2\n"); + pthread_create(&proc->pthread_te[2], attr_te1, te_thread2, (void*)&proc->tep[2]); } diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 8533b05001..926dc7bd1c 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1472,7 +1472,7 @@ static void* ru_thread( void* param ) { // set default return value - thread_top_init("ru_thread",0,400000,500000,500000); + thread_top_init("ru_thread",1,400000,500000,500000); //CPU_SET(1, &cpuset); //pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);