From 13122a272e42014fcd48fec55a47fd6205d43924 Mon Sep 17 00:00:00 2001 From: laurent Date: Thu, 31 Oct 2019 17:28:21 +0100 Subject: [PATCH] ul in parallel monolithic case, ul in parallel memory leak fix --- common/utils/threadPool/thread-pool.c | 7 +- common/utils/threadPool/thread-pool.h | 39 ++- executables/main-fs6.c | 2 +- executables/main-ocp.c | 9 +- openair1/PHY/LTE_TRANSPORT/dlsch_coding.c | 1 + openair1/PHY/LTE_TRANSPORT/transport_eNB.h | 1 + openair1/PHY/LTE_TRANSPORT/transport_proto.h | 2 + openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c | 342 ++++++++----------- openair1/PHY/defs_eNB.h | 9 +- openair1/SCHED/phy_procedures_lte_eNb.c | 329 +++++------------- 10 files changed, 272 insertions(+), 469 deletions(-) diff --git a/common/utils/threadPool/thread-pool.c b/common/utils/threadPool/thread-pool.c index 4cc56fc9b8..1b7aa960ba 100644 --- a/common/utils/threadPool/thread-pool.c +++ b/common/utils/threadPool/thread-pool.c @@ -84,7 +84,7 @@ void *one_thread(void *arg) { delNotifiedFIFO_elt(elt); else pushNotifiedFIFO(elt->reponseFifo, elt); - + myThread->runningOnKey=-1; mutexunlock(tp->incomingFifo.lockF); } } while (true); @@ -116,7 +116,7 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) { pool->nbThreads=0; pool->restrictRNTI=false; curptr=strtok_r(params,",",&saveptr); - + struct one_thread * ptr; while ( curptr!=NULL ) { int c=toupper(curptr[0]); @@ -130,8 +130,9 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) { break; default: + ptr=pool->allthreads; pool->allthreads=(struct one_thread *)malloc(sizeof(struct one_thread)); - pool->allthreads->next=pool->allthreads; + pool->allthreads->next=ptr; printf("create a thread for core %d\n", atoi(curptr)); pool->allthreads->coreID=atoi(curptr); pool->allthreads->id=pool->nbThreads; diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h index 6f34508c5a..d68918a163 100644 --- a/common/utils/threadPool/thread-pool.h +++ b/common/utils/threadPool/thread-pool.h @@ -137,8 +137,9 @@ static inline notifiedFIFO_elt_t *pollNotifiedFIFO(notifiedFIFO_t *nf) { // This function aborts all messages matching the key // If the queue is used in thread pools, it doesn't cancels already running processing // because the message has already been picked -static inline void abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) { +static inline int abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) { mutexlock(nf->lockF); + int nbDeleted=0; notifiedFIFO_elt_t **start=&nf->outF; while(*start!=NULL) { @@ -146,13 +147,15 @@ static inline void abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) { notifiedFIFO_elt_t *request=*start; *start=(*start)->next; delNotifiedFIFO_elt(request); - } - - if (*start != NULL) + nbDeleted++; + } else start=&(*start)->next; } + if (nf->outF == NULL) + nf->inF=NULL; mutexunlock(nf->lockF); + return nbDeleted; } struct one_thread { @@ -181,8 +184,17 @@ typedef struct thread_pool { static inline void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) { if (t->measurePerf) msg->creationTime=rdtsc(); - - pushNotifiedFIFO(&t->incomingFifo, msg); + if ( t->activated) + pushNotifiedFIFO(&t->incomingFifo, msg); + else { + if (t->measurePerf) + msg->startProcessingTime=rdtsc(); + msg->processingFunc(NotifiedFifoData(msg)); + if (t->measurePerf) + msg->endProcessingTime=rdtsc(); + if (msg->reponseFifo) + pushNotifiedFIFO(msg->reponseFifo, msg); + } } static inline notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) { @@ -212,7 +224,8 @@ static inline notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpo return msg; } -static inline void abortTpool(tpool_t *t, uint64_t key) { +static inline int abortTpool(tpool_t *t, uint64_t key) { + int nbRemoved=0; notifiedFIFO_t *nf=&t->incomingFifo; mutexlock(nf->lockF); notifiedFIFO_elt_t **start=&nf->outF; @@ -222,22 +235,26 @@ static inline void abortTpool(tpool_t *t, uint64_t key) { notifiedFIFO_elt_t *request=*start; *start=(*start)->next; delNotifiedFIFO_elt(request); - } - - if (*start != NULL) + nbRemoved++; + } else start=&(*start)->next; } + if (t->incomingFifo.outF==NULL) + t->incomingFifo.inF=NULL; struct one_thread *ptr=t->allthreads; while(ptr!=NULL) { - if (ptr->runningOnKey==key) + if (ptr->runningOnKey==key) { ptr->abortFlag=true; + nbRemoved++; + } ptr=ptr->next; } mutexunlock(nf->lockF); + return nbRemoved; } void initTpool(char *params,tpool_t *pool, bool performanceMeas); diff --git a/executables/main-fs6.c b/executables/main-fs6.c index 1416572d76..f2c95f86d4 100644 --- a/executables/main-fs6.c +++ b/executables/main-fs6.c @@ -615,7 +615,7 @@ void pusch_procedures_fromsplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB * &ulsch_harq->Kplus, &ulsch_harq->Kminus, &ulsch_harq->F); - int ret = ulsch_decoding_data(eNB, i, harq_pid, + int ret = ulsch_decoding_data(eNB, proc, i, harq_pid, ulsch_harq->nb_rb>20 ? 1 : 0); stop_meas(&eNB->ulsch_decoding_stats); LOG_D(PHY, diff --git a/executables/main-ocp.c b/executables/main-ocp.c index 34cd950ce7..4e657e6d28 100644 --- a/executables/main-ocp.c +++ b/executables/main-ocp.c @@ -692,13 +692,14 @@ static void *ru_thread( void *param ) { L1_rxtx_proc_t L1proc; L1_rxtx_proc_t *proc=&L1proc; - if ( strlen(get_softmodem_params()->threadPoolConfig) > 0 ) { + if ( strlen(get_softmodem_params()->threadPoolConfig) > 0 ) initTpool(get_softmodem_params()->threadPoolConfig, &L1proc.threadPool, true); - initNotifiedFIFO(&L1proc.respEncode); - initNotifiedFIFO(&L1proc.respDecode); - } else + else initTpool("n", &L1proc.threadPool, true); + initNotifiedFIFO(&L1proc.respEncode); + initNotifiedFIFO(&L1proc.respDecode); + if (ru->if_south == LOCAL_RF) { // configure RF parameters only fill_rf_config(ru,ru->rf_config_file); init_frame_parms(&ru->frame_parms,1); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index ea6bf29ac7..5024650d62 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -398,6 +398,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, proc->nbEncode++; } else { TPencode(rdata); + delNotifiedFIFO_elt(req); } int Qm=hadlsch->Qm; diff --git a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h index 9e78eb75a0..0737d4c56a 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h @@ -288,6 +288,7 @@ typedef struct { uint8_t rvidx; /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) int16_t w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)]; + int16_t pusch_rep_buffer[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)]; /// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) //TBD int16_t *d[MAX_NUM_ULSCH_SEGMENTS]; diff --git a/openair1/PHY/LTE_TRANSPORT/transport_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_proto.h index a358df3ff3..0d8fcfa29e 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_proto.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_proto.h @@ -469,6 +469,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB, int ulsch_decoding_data_all(PHY_VARS_eNB *eNB, + L1_rxtx_proc_t *proc, int UE_id, int harq_pid, int llr8_flag); @@ -513,6 +514,7 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB, @returns 0 on success */ int ulsch_decoding_data(PHY_VARS_eNB *eNB, + L1_rxtx_proc_t *proc, int UE_id, int harq_pid, int llr8_flag); diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index 64b83c524a..4cfdcbdb41 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -213,72 +213,26 @@ uint8_t extract_cqi_crc(uint8_t *cqi,uint8_t CQI_LENGTH) { extern int oai_exit; -int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) { - unsigned int r,r_offset=0,Kr,Kr_bytes; - uint8_t crc_type; - int offset = 0; - int ret = 1; - int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)]; - LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id]; - LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid]; - int G = ulsch_harq->G; - unsigned int E; - decoder_if_t *tc; - static int32_t pusch_rep_buffer[3*(6144+64)]; - int max_Ncb; - - if (llr8_flag == 0) - tc = *decoder16; - else - tc = *decoder8; - - if(ulsch_harq->repetition_number == 1) { - memset(pusch_rep_buffer,0,(sizeof(int32_t)*3*(6144+64))) ; // reset the buffer every new repetitions - } - - for (r=0; rC; r++) { - // printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]); - // Get Turbo interleaver parameters - if (rCminus) - Kr = ulsch_harq->Kminus; - else - Kr = ulsch_harq->Kplus; - - Kr_bytes = Kr>>3; - memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short)); - ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8), - (uint8_t *)&dummy_w[r][0], +void processULSegment(void * arg) { + turboDecode_t* rdata=(turboDecode_t*) arg; + PHY_VARS_eNB *eNB=rdata->eNB; + LTE_UL_eNB_HARQ_t *ulsch_harq=rdata->ulsch_harq; + int r=rdata->segment_r; + int G=ulsch_harq->G; + int Kr_bytes=rdata->Kr>>3; + int16_t dummy_w[3*(6144+64)]; + + memset(&dummy_w[0],0,3*(6144+64)*sizeof(short)); + ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8), + (uint8_t *)&dummy_w[0], (r==0) ? ulsch_harq->F : 0); -#ifdef DEBUG_ULSCH_DECODING - printf("Rate Matching Segment %u (coded bits (G) %d,unpunctured/repeated bits %u, Q_m %d, Nl %d, r_offset %d)...\n", - r, G, - Kr*3, - ulsch_harq->Qm, - ulsch_harq->Nl, r_offset); -#endif - start_meas(&eNB->ulsch_rate_unmatching_stats); - #ifdef FS6 - if ( getenv("fs6") != NULL && strncasecmp( getenv("fs6"), "du", 2) == 0 ) { - int Gp=G/ulsch_harq->Qm; - int GpmodC = Gp%ulsch_harq->C; - - if (r < (ulsch_harq->C-(GpmodC))) - E = ulsch_harq->Qm * (Gp/ulsch_harq->C); - else - E = ulsch_harq->Qm * ((GpmodC==0?0:1) + (Gp/ulsch_harq->C)); - sendFs6Ul(eNB, UE_id, harq_pid, r, ulsch_harq->e+r_offset, E*sizeof(int16_t), r_offset); - - r_offset += E; - continue; - } - - #endif - - if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r], + start_meas(&eNB->ulsch_deinterleaving_stats); + unsigned int E; + if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r], G, ulsch_harq->w[r], - (uint8_t *) &dummy_w[r][0], - ulsch_harq->e+r_offset, + (uint8_t *) &dummy_w[0], + ulsch_harq->e+rdata->r_offset, ulsch_harq->C, NSOFT, 0, //Uplink @@ -290,157 +244,131 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) r, &E)==-1) { LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n"); - return(-1); + return; + } + stop_meas(&eNB->ulsch_rate_unmatching_stats); + int max_Ncb = 3*ulsch_harq->RTC[r]*32 ; + + if(ulsch_harq->repetition_number == 1) { + memset(ulsch_harq->pusch_rep_buffer[r],0,(sizeof(int32_t)*3*(6144+64))) ; // reset the buffer every new repetitions + } + if(ulsch_harq->total_number_of_repetitions > 1) { + if (ulsch_harq->rvidx==1) { + LOG_E(PHY,"Adding HARQ data for segment: %d\n", r); + // Store the result of HARQ combining in the last emtc repetitions of sequence 0,2,3,1 + for (int nn=0; nnpusch_rep_buffer[r][nn] += ulsch_harq->w[r][nn] ; } - stop_meas(&eNB->ulsch_rate_unmatching_stats); - max_Ncb = 3*ulsch_harq->RTC[r]*32 ; - - if(ulsch_harq->total_number_of_repetitions > 1) { - if (ulsch_harq->rvidx==1) { - // Store the result of HARQ combining in the last emtc repetitions of sequence 0,2,3,1 - for (int nn=0; nnw[r][nn] ; - } - } - - if (ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions) { - for (int nn=0; nnw[r][nn] = pusch_rep_buffer[nn] ; - } - } - } - - r_offset += E; - start_meas(&eNB->ulsch_deinterleaving_stats); - #if 0 - start_meas(&eNB->ulsch_deinterleaving_stats); - req=createRequest(DECODE,sizeof(turboDecode_t)); - req->startUELoop=eNB->proc.threadPool.startProcessingUE; - union turboReqUnion id= {.s={eNB->ulsch[UE_id]->rnti,frame,subframe,r,0}}; - req->id= id.p; - turboDecode_t * rdata=(turboDecode_t *) req->data; - #endif - sub_block_deinterleaving_turbo(4+Kr, - &ulsch_harq->d[r][96], - ulsch_harq->w[r]); - stop_meas(&eNB->ulsch_deinterleaving_stats); - - if (ulsch_harq->C == 1) - crc_type = CRC24_A; - else - crc_type = CRC24_B; - #if 0 - rdata->frame=frame; - rdata->subframe=subframe; - rdata->UEid=UE_id; - rdata->harq_pid=harq_pid; - rdata->Kr=Kr; - rdata->maxIterations=eNB->ulsch[UE_id]->max_turbo_iterations; - rdata->ulsch_harq=ulsch_harq; - rdata->eNB=eNB; - rdata->nbSegments=ulsch_harq->C; - rdata->segment_r=r; - rdata->Fbits=(r==0) ? ulsch_harq->F : 0; - rdata->offset=offset; - rdata->function=td; - int Fbytes=rdata->Fbits>>3; - int blockSize=Kr_bytes - Fbytes - (rdata->nbSegments>1?3:0); - if ( eNB->proc.threadPool.activated) { - add_request(req, &eNB->proc.threadPool); - req=NULL; - } else { - req->startProcessingTime=rdtsc(); - rdata->decodeIterations = td( rdata->soft_bits+96, - rdata->decoded_bytes, - rdata->Kr, - f1f2mat_old[rdata->iind*2], - f1f2mat_old[(rdata->iind*2)+1], - rdata->maxIterations, - rdata->nbSegments == 1 ? CRC24_A: CRC24_B, - rdata->Fbits, - &eNB->ulsch_tc_init_stats, - &eNB->ulsch_tc_alpha_stats, - &eNB->ulsch_tc_beta_stats, - &eNB->ulsch_tc_gamma_stats, - &eNB->ulsch_tc_ext_stats, - &eNB->ulsch_tc_intl1_stats, - &eNB->ulsch_tc_intl2_stats); - - stop_meas(&eNB->ulsch_turbo_decoding_stats); - req->returnTime=req->endProcessingTime=rdtsc(); - req->decodeIterations=rdata->decodeIterations; - req->coreId=0; - req->processedBy[0]=0; - req->next=eNB->proc.threadPool.doneRequests; - eNB->proc.threadPool.doneRequests=req; - - if (rdata->decodeIterations > eNB->ulsch[UE_id]->max_turbo_iterations ) - // Entire TPU need retransmission - break; - } -offset += blockSize; - eNB->proc.threadPool.startProcessingUE=rdtsc(); - #endif - start_meas(&eNB->ulsch_turbo_decoding_stats); - ret = tc(&ulsch_harq->d[r][96], - NULL, - ulsch_harq->c[r], - NULL, - Kr, - ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS, - crc_type, - (r==0) ? ulsch_harq->F : 0, - &eNB->ulsch_tc_init_stats, - &eNB->ulsch_tc_alpha_stats, - &eNB->ulsch_tc_beta_stats, - &eNB->ulsch_tc_gamma_stats, - &eNB->ulsch_tc_ext_stats, - &eNB->ulsch_tc_intl1_stats, - &eNB->ulsch_tc_intl2_stats); - stop_meas(&eNB->ulsch_turbo_decoding_stats); - LOG_D(PHY,"turbo decode in %d iter\n",ret); - - // Reassembly of Transport block here - - if (ret != (1+ulsch->max_turbo_iterations)) { - if (rCminus) - Kr = ulsch_harq->Kminus; - else - Kr = ulsch_harq->Kplus; - - Kr_bytes = Kr>>3; - - if (r==0) { - memcpy(ulsch_harq->b, - &ulsch_harq->c[0][(ulsch_harq->F>>3)], - Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0)); - offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0); - } else { - memcpy(ulsch_harq->b+offset, - ulsch_harq->c[r], - Kr_bytes - ((ulsch_harq->C>1)?3:0)); - offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0)); - } - } else { - break; + if (ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions) { + LOG_E(PHY,"Will use HARQ data sum up for segment: %d\n", r); + for (int nn=0; nnw[r][nn] = ulsch_harq->pusch_rep_buffer[r][nn] ; } } + int16_t soft_bits[3*8*6144+12+96] __attribute__((aligned(32))); + sub_block_deinterleaving_turbo(4+rdata->Kr, + soft_bits+96, + ulsch_harq->w[r]); + stop_meas(&eNB->ulsch_deinterleaving_stats); + rdata->decodeIterations = rdata->function( soft_bits+96, + NULL, + rdata->decoded_bytes, + NULL, + rdata->Kr, + rdata->maxIterations, + rdata->nbSegments == 1 ? CRC24_A: CRC24_B, + rdata->Fbits, + &eNB->ulsch_tc_init_stats, + &eNB->ulsch_tc_alpha_stats, + &eNB->ulsch_tc_beta_stats, + &eNB->ulsch_tc_gamma_stats, + &eNB->ulsch_tc_ext_stats, + &eNB->ulsch_tc_intl1_stats, + &eNB->ulsch_tc_intl2_stats); + stop_meas(&eNB->ulsch_turbo_decoding_stats); + +} +int ulsch_decoding_data(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, + int UE_id,int harq_pid,int llr8_flag) { + unsigned int r_offset=0; + int offset = 0; + LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id]; + LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid]; + int G = ulsch_harq->G; + unsigned int E; + int ret=0; + + decoder_if_t * td=llr8_flag == 0 ? + *decoder16 : *decoder8; + ulsch_harq->processedSegments=0; + + for (int r=0; rC; r++) { + // printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]); + // Get Turbo interleaver parameters + unsigned int Kr= rCminus ? + ulsch_harq->Kminus :ulsch_harq->Kplus; + unsigned int Kr_bytes = Kr>>3; + +#ifdef DEBUG_ULSCH_DECODING + printf("Rate Matching Segment %u (coded bits (G) %d,unpunctured/repeated bits %u, Q_m %d, Nl %d, r_offset %d)...\n", + r, G, + Kr*3, + ulsch_harq->Qm, + ulsch_harq->Nl, r_offset); +#endif + int Gp=G/ulsch_harq->Qm; + int GpmodC = Gp%ulsch_harq->C; + + if (r < (ulsch_harq->C-(GpmodC))) + E = ulsch_harq->Qm * (Gp/ulsch_harq->C); + else + E = ulsch_harq->Qm * ((GpmodC==0?0:1) + (Gp/ulsch_harq->C)); +#ifdef FS6 + if ( getenv("fs6") != NULL && strncasecmp( getenv("fs6"), "du", 2) == 0 ) { + + sendFs6Ul(eNB, UE_id, harq_pid, r, ulsch_harq->e+r_offset, E*sizeof(int16_t), r_offset); + + r_offset += E; + continue; + } + +#endif + + union turboReqUnion id= {.s={ulsch->rnti,proc->frame_rx,proc->subframe_rx,0,0}}; + notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(turboDecode_t), id.p, &proc->respDecode, processULSegment); + turboDecode_t * rdata=(turboDecode_t *) NotifiedFifoData(req); + + rdata->eNB=eNB; + rdata->frame=proc->frame_rx; + rdata->subframe=proc->subframe_rx; + rdata->UEid=UE_id; + rdata->harq_pid=harq_pid; + rdata->Kr=Kr; + rdata->maxIterations=eNB->ulsch[UE_id]->max_turbo_iterations; + rdata->ulsch_harq=ulsch_harq; + rdata->eNB=eNB; + rdata->nbSegments=ulsch_harq->C; + rdata->segment_r=r; + rdata->Fbits=(r==0) ? ulsch_harq->F : 0; + rdata->r_offset=r_offset; + rdata->offset=offset; + rdata->function=td; + int Fbytes=(r==0) ? rdata->Fbits>>3 : 0; + int sz=Kr_bytes - Fbytes - ((ulsch_harq->C>1)?3:0); + pushTpool(&proc->threadPool,req); + proc->nbDecode++; + LOG_D(PHY,"Added a block to decode, in pipe: %d\n",proc->nbDecode); + r_offset+=E; + offset+=sz; + } return(ret); } -int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) { - int ret = 0; - /*if(get_thread_worker_conf() == WORKER_ENABLE) - { - ret = ulsch_decoding_data_2thread(eNB,UE_id,harq_pid,llr8_flag); - } - else*/ - { - ret = ulsch_decoding_data(eNB,UE_id,harq_pid,llr8_flag); - } - return ret; +int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, + int UE_id,int harq_pid,int llr8_flag) { + return ulsch_decoding_data(eNB,proc,UE_id,harq_pid,llr8_flag); } static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline)); @@ -1158,7 +1086,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, LOG_D(PHY,"frame %d subframe %d O_ACK:%d o_ACK[]=%d:%d:%d:%d\n",frame,subframe,ulsch_harq->O_ACK,ulsch_harq->o_ACK[0],ulsch_harq->o_ACK[1],ulsch_harq->o_ACK[2],ulsch_harq->o_ACK[3]); // Do ULSCH Decoding for data portion - ret = ulsch_decoding_data_all(eNB,UE_id,harq_pid,llr8_flag); + ret = ulsch_decoding_data_all(eNB,proc, UE_id,harq_pid,llr8_flag); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,0); return(ret); } diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index 718ede5715..51b2e9c4ae 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -871,20 +871,19 @@ union turboReqUnion { }; typedef struct TurboDecode_s { - decoder_if_t *function; - int16_t soft_bits[3*8*6144+12+96] __attribute__((aligned(32))); - uint8_t decoded_bytes[3+768] __attribute__((aligned(32))); + PHY_VARS_eNB *eNB; + decoder_if_t *function; + uint8_t decoded_bytes[3+1768] __attribute__((aligned(32))); int UEid; int harq_pid; int frame; int subframe; - int iind; int Fbits; int Kr; LTE_UL_eNB_HARQ_t *ulsch_harq; - PHY_VARS_eNB *eNB; int nbSegments; int segment_r; + int r_offset; int offset; int maxIterations; int decodeIterations; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 94689ed246..2b032c208a 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -310,7 +310,7 @@ bool dlsch_procedures(PHY_VARS_eNB *eNB, if ( proc->threadPool.activated ) { // Wait all other threads finish to process while (proc->nbEncode) { - pullTpool(&proc->respEncode, &proc->threadPool); + delNotifiedFIFO_elt(pullTpool(&proc->respEncode, &proc->threadPool)); proc->nbEncode--; } } @@ -1165,86 +1165,92 @@ uci_procedures(PHY_VARS_eNB *eNB, } // end loop for (int i = 0; i < NUMBER_OF_UE_MAX; i++) { } -#if 0 -void post_decode(request_t* decodeResult) { - turboDecode_t * rdata=(turboDecode_t *) decodeResult->data; - LTE_eNB_ULSCH_t *ulsch = rdata->eNB->ulsch[rdata->UEid]; - LTE_UL_eNB_HARQ_t *ulsch_harq = rdata->ulsch_harq; - PHY_VARS_eNB *eNB=rdata->eNB; - bool decodeSucess=rdata->decodeIterations <= rdata->maxIterations; - ulsch_harq->processedSegments++; - if (decodeSucess) { - int Fbytes=rdata->Fbits>>3; - int Kr=rdata->segment_r < ulsch_harq->Cminus? - ulsch_harq->Kminus: - ulsch_harq->Kplus; - int Kr_bytes = Kr>>3; - int blockSize=Kr_bytes - Fbytes - (rdata->nbSegments>1?3:0); - memcpy(ulsch_harq->b+rdata->offset, - rdata->decoded_bytes+Fbytes, - blockSize); +void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) { + turboDecode_t * rdata=(turboDecode_t *) NotifiedFifoData(req); - } else { - if (rdata->nbSegments > 1 ) { - // Purge pending decoding of the same TDU - union turboReqUnion idInFailure= {.p=decodeResult->id}; - rnti_t rntiInFailure=idInFailure.s.rnti; - tpool_t * tp=&proc->threadPool; - mutexlock(tp->lockRequests); - request_t* pending=NULL; - while ( (pending=searchRNTI(tp, rntiInFailure)) != NULL) { - LOG_W(MAC,"removing a CB belonging to a bad TPU"); - freeRequest(pending); - mutexlock(tp->lockReportDone); - tp->notFinishedJobs--; - mutexunlock(tp->lockReportDone); - } - mutexunlock(tp->lockRequests); - } + LTE_eNB_ULSCH_t *ulsch = rdata->eNB->ulsch[rdata->UEid]; + LTE_UL_eNB_HARQ_t *ulsch_harq = rdata->ulsch_harq; + PHY_VARS_eNB *eNB=rdata->eNB; + + bool decodeSucess=rdata->decodeIterations <= rdata->maxIterations; + ulsch_harq->processedSegments++; + LOG_D(PHY, "processing result of segment: %d, ue %d, processed %d/%d\n", + rdata->segment_r, rdata->UEid, ulsch_harq->processedSegments, rdata->nbSegments); + proc->nbDecode--; + LOG_D(PHY,"remain to decoded in subframe: %d\n", proc->nbDecode); + if (decodeSucess) { + int Fbytes=(rdata->segment_r==0) ? rdata->Fbits>>3 : 0; + int sz=(rdata->Kr>>3) - Fbytes - ((ulsch_harq->C>1)?3:0); + memcpy(ulsch_harq->b+rdata->offset, + rdata->decoded_bytes+Fbytes, + sz); + } else { + if ( rdata->nbSegments != ulsch_harq->processedSegments ) { + int nb=abortTpool(&proc->threadPool, req->key); + printf("nb1:%d\n", nb); + nb+=abortNotifiedFIFO(&proc->respDecode, req->key); + printf("nb2:%d\n", nb); + proc->nbDecode-=nb; + LOG_I(PHY,"uplink segment error %d/%d, aborted %d segments",rdata->segment_r,rdata->nbSegments, nb); + AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n", + ulsch_harq->processedSegments, nb, rdata->nbSegments); + ulsch_harq->processedSegments=rdata->nbSegments; } + } - // Check if TDU is complete: either we have all blocks in success - // either at least one block can't be decoded - // Maybe we receive decoded block alter a first failure, - // so we protect ourselves against multiple executions - if ( (rdata->nbSegments == ulsch_harq->processedSegments || decodeSucess==false) && - ulsch_harq->processedBadSegment == 0 ) { - //compute the expected ULSCH RX power (for the stats) - ulsch_harq->delta_TF = get_hundred_times_delta_IF_eNB(eNB,rdata->UEid,rdata->harq_pid, 0); // 0 means bw_factor is not considered - - if (ulsch_harq->cqi_crc_status == 1) - fill_ulsch_cqi_indication(eNB,rdata->frame,rdata->subframe, - ulsch_harq, - ulsch->rnti); - - fill_crc_indication(eNB,rdata->UEid,rdata->frame,rdata->subframe,decodeSucess?0:1); // indicate result to MAC - fill_rx_indication(eNB,rdata->UEid,rdata->frame,rdata->subframe); // indicate SDU to MAC - - if (!decodeSucess) { - ulsch_harq->processedBadSegment =1; - if (ulsch_harq->round >= 3) { - ulsch_harq->status = SCH_IDLE; - ulsch_harq->handled = 0; - ulsch->harq_mask &= ~(1 << rdata->harq_pid); - ulsch_harq->round = 0; - } - - /* Mark the HARQ process to release it later if max transmission reached - * (see below). - * MAC does not send the max transmission count, we have to deal with it - * locally in PHY. - */ - ulsch_harq->handled = 1; - } else { - ulsch_harq->status = SCH_IDLE; - ulsch->harq_mask &= ~(1 << rdata->harq_pid); - } // ulsch not in error - - if (ulsch_harq->O_ACK>0) - fill_ulsch_harq_indication(eNB,ulsch_harq,ulsch->rnti,rdata->frame,rdata->subframe,ulsch->bundling); - } + // if this UE segments are all done + if ( rdata->nbSegments == ulsch_harq->processedSegments) { + //compute the expected ULSCH RX power (for the stats) + int i=rdata->UEid; + ulsch_harq->delta_TF = get_hundred_times_delta_IF_eNB(eNB,i,rdata->harq_pid, 0); // 0 means bw_factor is not considered + if (RC.mac != NULL) { /* ulsim does not use RC.mac context. */ + if (ulsch_harq->cqi_crc_status == 1) { + fill_ulsch_cqi_indication(eNB,rdata->frame,rdata->subframe,ulsch_harq,ulsch->rnti); + RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << rdata->subframe)); + } else { + if(RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag & (1 << rdata->subframe) ) { + RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << rdata->subframe)); + RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_timer=30; + LOG_D(PHY,"Frame %d,Subframe %d, We're supposed to get a cqi here. Set cqi_req_timer to 30.\n",rdata->frame,rdata->subframe); + } + } + } + + if (!decodeSucess) { + fill_crc_indication(eNB,i,rdata->frame,rdata->subframe,1); // indicate NAK to MAC + fill_rx_indication(eNB,i,rdata->frame,rdata->subframe); // indicate SDU to MAC + LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n", + eNB->Mod_id,rdata->harq_pid, + rdata->frame,rdata->subframe, i, + ulsch_harq->round, + ulsch->Mlimit, + ulsch_harq->o_ACK[0], + ulsch_harq->o_ACK[1]); + + if (ulsch_harq->round >= 3) { + ulsch_harq->status = SCH_IDLE; + ulsch_harq->handled = 0; + ulsch->harq_mask &= ~(1 << rdata->harq_pid); + ulsch_harq->round = 0; + } + /* Mark the HARQ process to release it later if max transmission reached + * (see below). + * MAC does not send the max transmission count, we have to deal with it + * locally in PHY. + */ + ulsch_harq->handled = 1; + } // ulsch in error + else if(ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions){ + fill_crc_indication(eNB,i,rdata->frame,rdata->subframe,0); // indicate ACK to MAC + fill_rx_indication(eNB,i,rdata->frame,rdata->subframe); // indicate SDU to MAC + ulsch_harq->status = SCH_IDLE; + ulsch->harq_mask &= ~(1 << rdata->harq_pid); + } // ulsch not in error + + if (ulsch_harq->O_ACK>0) + fill_ulsch_harq_indication(eNB,ulsch_harq,ulsch->rnti,rdata->frame,rdata->subframe,ulsch->bundling); + } } -#endif void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { uint32_t ret=0,i; @@ -1316,121 +1322,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { ulsch_harq->V_UL_DAI, ulsch_harq->nb_rb>20 ? 1 : 0); stop_meas(&eNB->ulsch_decoding_stats); - LOG_D(PHY, - "[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d ulsch_harq->cqi_crc_status:%d ackBits:%d ulsch_decoding_stats[t:%lld max:%lld]\n", - eNB->Mod_id,harq_pid, - frame,subframe, - ulsch->rnti, - dB_fixed(eNB->pusch_vars[i]->ulsch_power[0]), - dB_fixed(eNB->pusch_vars[i]->ulsch_power[1]), - 30,//eNB->measurements.n0_power_dB[0], - 30,//eNB->measurements.n0_power_dB[1], - ulsch_harq->o_ACK[0], - ulsch_harq->o_ACK[1], - ret, - ulsch_harq->cqi_crc_status, - ulsch_harq->O_ACK, - eNB->ulsch_decoding_stats.p_time, eNB->ulsch_decoding_stats.max); - if (ulsch_harq->repetition_number < ulsch_harq->total_number_of_repetitions){ - ulsch_harq->rvidx = rvidx_tab[(ulsch_harq->repetition_number%4)] ; // Set the correct rvidx for the next emtc repetitions - ulsch_harq->repetition_number +=1 ; // Increment repetition_number for the next ULSCH allocation - } - //compute the expected ULSCH RX power (for the stats) - ulsch_harq->delta_TF = get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered - - if (RC.mac != NULL) { /* ulsim does not use RC.mac context. */ - if (ulsch_harq->cqi_crc_status == 1) { -#ifdef DEBUG_PHY_PROC - //if (((frame%10) == 0) || (frame < 50)) - print_CQI(ulsch_harq->o,ulsch_harq->uci_format,0,fp->N_RB_DL); -#endif - fill_ulsch_cqi_indication(eNB,frame,subframe,ulsch_harq,ulsch->rnti); - RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << subframe)); - } else { - if(RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag & (1 << subframe) ) { - RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << subframe)); - RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_timer=30; - LOG_D(PHY,"Frame %d,Subframe %d, We're supposed to get a cqi here. Set cqi_req_timer to 30.\n",frame,subframe); - } - } - } - - if (ret == (1+MAX_TURBO_ITERATIONS)) { - T(T_ENB_PHY_ULSCH_UE_NACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(ulsch->rnti), - T_INT(harq_pid)); - fill_crc_indication(eNB,i,frame,subframe,1); // indicate NAK to MAC - fill_rx_indication(eNB,i,frame,subframe); // indicate SDU to MAC - LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n", - eNB->Mod_id,harq_pid, - frame,subframe, i, - ulsch_harq->round, - ulsch->Mlimit, - ulsch_harq->o_ACK[0], - ulsch_harq->o_ACK[1]); - - if (ulsch_harq->round >= 3) { - ulsch_harq->status = SCH_IDLE; - ulsch_harq->handled = 0; - ulsch->harq_mask &= ~(1 << harq_pid); - ulsch_harq->round = 0; - } - - MSC_LOG_RX_DISCARDED_MESSAGE( - MSC_PHY_ENB,MSC_PHY_UE, - NULL,0, - "%05u:%02u ULSCH received rnti %x harq id %u round %d", - frame,subframe, - ulsch->rnti,harq_pid, - ulsch_harq->round-1 - ); - /* Mark the HARQ process to release it later if max transmission reached - * (see below). - * MAC does not send the max transmission count, we have to deal with it - * locally in PHY. - */ - ulsch_harq->handled = 1; - } // ulsch in error - else if(ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions){ - fill_crc_indication(eNB,i,frame,subframe,0); // indicate ACK to MAC - fill_rx_indication(eNB,i,frame,subframe); // indicate SDU to MAC - ulsch_harq->status = SCH_IDLE; - ulsch->harq_mask &= ~(1 << harq_pid); - T (T_ENB_PHY_ULSCH_UE_ACK, T_INT (eNB->Mod_id), T_INT (frame), T_INT (subframe), T_INT (ulsch->rnti), T_INT (harq_pid)); - MSC_LOG_RX_MESSAGE( - MSC_PHY_ENB,MSC_PHY_UE, - NULL,0, - "%05u:%02u ULSCH received rnti %x harq id %u", - frame,subframe, - ulsch->rnti,harq_pid - ); -#ifdef DEBUG_PHY_PROC -#ifdef DEBUG_ULSCH - LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",frame,subframe, - harq_pid,ulsch_harq->TBS>>3); - - for (j=0; jTBS>>3; j++) - LOG_T(PHY,"%x.",ulsch->harq_processes[harq_pid]->b[j]); - - LOG_T(PHY,"\n"); -#endif -#endif - } // ulsch not in error - - if (ulsch_harq->O_ACK>0) fill_ulsch_harq_indication(eNB,ulsch_harq,ulsch->rnti,frame,subframe,ulsch->bundling); - - LOG_D(PHY,"[eNB %d] Frame %d subframe %d: received ULSCH harq_pid %d for UE %d, ret = %d, CQI CRC Status %d, ACK %d,%d, ulsch_errors %d/%d\n", - eNB->Mod_id,frame,subframe, - harq_pid, - i, - ret, - ulsch_harq->cqi_crc_status, - ulsch_harq->o_ACK[0], - ulsch_harq->o_ACK[1], - eNB->UE_stats[i].ulsch_errors[harq_pid], - eNB->UE_stats[i].ulsch_decoding_attempts[harq_pid][0]); - } // if ((ulsch) && - // (ulsch->rnti>0) && - // (ulsch_harq->status == ACTIVE)) + } else if ((ulsch) && (ulsch->rnti>0) && (ulsch_harq->status == ACTIVE) && @@ -1444,56 +1336,17 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { LOG_W (PHY, "Removing stale ULSCH config for UE %x harq_pid %d (harq_mask is now 0x%2.2x)\n", ulsch->rnti, harq_pid, ulsch->harq_mask); } } // for (i=0; ithreadPool.activated ) { - // Wait all other threads finish to process - //printf("%s:%d:%d\n", __FILE__,__LINE__,eNB->proc->threadPool.notFinishedJobs); - int rr=0; - mutexlock(proc->threadPool.lockReportDone); - while ( proc->threadPool.notFinishedJobs > 0 ) { - //printf("%s:%d:%d\n", __FILE__,__LINE__,eNB->proc->threadPool.notFinishedJobs); - struct timespec t; - clock_gettime(CLOCK_REALTIME,&t); - t.tv_nsec+=1*1000*1000; - if ( t.tv_nsec >= 1000*1000*1000 ) { - t.tv_nsec -= 1000*1000*1000; - t.tv_sec++; - } - if ((rr=pthread_cond_timedwait(&proc->threadPool.notifDone,&proc.threadPool.lockReportDone, &t))!=0) { - LOG_E(PHY,"timedwait1:%s,%p,%p,%p,%d\n", rr==ETIMEDOUT?"ETIMEDOUT":"other", - proc->threadPool.oldestRequests, - proc->threadPool.newestRequests, - proc->threadPool.doneRequests, - proc->threadPool.notFinishedJobs); - proc->threadPool.oldestRequests=NULL; - proc->threadPool.newestRequests=NULL; - proc->threadPool.doneRequests=NULL; - proc->threadPool.notFinishedJobs=0; - } - } - mutexunlock(proc->threadPool.lockReportDone); - } - - request_t* tmp; - while ((tmp=proc->threadPool.doneRequests)!=NULL) { - turboDecode_t * rdata=(turboDecode_t *) tmp->data; - tmp->decodeIterations=rdata->decodeIterations; - post_decode(tmp); - tmp->returnTime=rdtsc(); - tmp->cumulSubframe=tmp->returnTime-startTime; - // Ignore write error (if no trace listner) - if (write(proc->threadPool.traceFd, tmp, sizeof(request_t)- 2*sizeof(void*))) {}; - proc->threadPool.doneRequests=tmp->next; - freeRequest(tmp); - } - #endif + + while (proc->nbDecode > 0) { + notifiedFIFO_elt_t *req=pullTpool(&proc->respDecode, &proc->threadPool); + postDecode(proc, req); + delNotifiedFIFO_elt(req); + } } + extern int oai_exit; -extern void *td_thread (void *); - -extern void *te_thread (void *); void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) { nfapi_rx_indication_pdu_t *pdu;