diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index d4e39b2b6ba2f497e4b963b1db3dfada8830cdab..eea3b55f6e3a598af7040f257233e843f87d6db7 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -83,15 +83,22 @@ int round_robin_dl(module_id_t Mod_id, const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); const int RBGsize = get_min_rb_unit(Mod_id, CC_id); const int RBGlastsize = get_rbg_size_last(Mod_id, CC_id); - int num_ue_req = 0; UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info; int rbg = 0; for (; !rbgalloc_mask[rbg]; rbg++) ; /* fast-forward to first allowed RBG */ - // Calculate the amount of RBs every UE wants to send. - for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + /* just start with the UE after the one we had last time. If it does not + * exist, this will start at the head */ + int g_start_ue_dl = data; + g_start_ue_dl = next_ue_list_looped(UE_list, g_start_ue_dl); + + int UE_id = g_start_ue_dl; + UE_list_t UE_sched; + int *cur_UE = &UE_sched.head; + // Allocate retransmissions, and mark UEs with new transmissions + do { // check whether there are HARQ retransmissions const COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; const uint8_t harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config, frame, subframe); @@ -100,14 +107,14 @@ int round_robin_dl(module_id_t Mod_id, if (round != 8) { // retransmission: allocate const int nb_rb = UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid]; if (nb_rb == 0) - continue; + goto skip_ue; int nb_rbg = (nb_rb + (nb_rb % RBGsize)) / RBGsize; // needs more RBGs than we can allocate if (nb_rbg > n_rbg_sched) { LOG_D(MAC, "retransmission of UE %d needs more RBGs (%d) than we have (%d)\n", UE_id, nb_rbg, n_rbg_sched); - continue; + goto skip_ue; } // ensure that the number of RBs can be contained by the RBGs (!), i.e. // if we allocate the last RBG this one should have the full RBGsize @@ -116,12 +123,12 @@ int round_robin_dl(module_id_t Mod_id, LOG_D(MAC, "retransmission of UE %d needs %d RBs, but the last RBG %d is too small (%d, normal %d)\n", UE_id, nb_rb, N_RBG - 1, RBGlastsize, RBGsize); - continue; + goto skip_ue; } const uint8_t cqi = ue_ctrl->dl_cqi[CC_id]; const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); if (idx < 0) - continue; // cannot allocate CCE + goto skip_ue; // cannot allocate CCE ue_ctrl->pre_dci_dl_pdu_idx = idx; // retransmissions: directly allocate n_rbg_sched -= nb_rbg; @@ -148,35 +155,32 @@ int round_robin_dl(module_id_t Mod_id, return n_rbg_sched; for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; } else { - if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total > 0) - num_ue_req++; + if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total > 0) { + *cur_UE = UE_id; + cur_UE = &UE_sched.next[UE_id]; + } } - } - if (num_ue_req == 0) - return n_rbg_sched; // no UE has a transmission +skip_ue: + UE_id = next_ue_list_looped(UE_list, UE_id); + } while (UE_id != g_start_ue_dl); + *cur_UE = -1; // mark end - // after allocating retransmissions: build list of UE to allocate. - // if start_UE does not exist anymore (detach etc), start at first UE - if (g_start_ue_dl == -1) - g_start_ue_dl = UE_list->head; - int UE_id = g_start_ue_dl; - UE_list_t UE_sched; - int *cur_UE = &UE_sched.head; + if (UE_sched.head < 0) + return n_rbg_sched; // no UE has a transmission - int num_ue_sched = 0; - max_num_ue = min(min(max_num_ue, num_ue_req), n_rbg_sched); + // after allocating retransmissions: pre-allocate CCE, compute number of + // requested RBGs + max_num_ue = min(max_num_ue, n_rbg_sched); int rb_required[MAX_MOBILES_PER_ENB]; // how much UEs request - while (num_ue_sched < max_num_ue) { - while (UE_info->UE_template[CC_id][UE_id].dl_buffer_total <= 0) - UE_id = next_ue_list_looped(UE_list, UE_id); + cur_UE = &UE_sched.head; + while (*cur_UE >= 0 && max_num_ue > 0) { + const int UE_id = *cur_UE; + cur_UE = &UE_sched.next[UE_id]; // go to next const uint8_t cqi = UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]; const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); if (idx < 0) { LOG_D(MAC, "cannot allocate CCE for UE %d, skipping\n", UE_id); - num_ue_req--; - max_num_ue = min(min(max_num_ue, num_ue_req), n_rbg_sched); - UE_id = next_ue_list_looped(UE_list, UE_id); // next candidate continue; } UE_info->UE_sched_ctrl[UE_id].pre_dci_dl_pdu_idx = idx; @@ -184,12 +188,9 @@ int round_robin_dl(module_id_t Mod_id, UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = mcs; const uint32_t B = UE_info->UE_template[CC_id][UE_id].dl_buffer_total; rb_required[UE_id] = find_nb_rb_DL(mcs, B, n_rbg_sched * RBGsize, RBGsize); - *cur_UE = UE_id; - cur_UE = &UE_sched.next[UE_id]; - num_ue_sched++; - UE_id = next_ue_list_looped(UE_list, UE_id); // next candidate + max_num_ue--; } - *cur_UE = -1; + *cur_UE = -1; // not all UEs might be allocated, mark end /* for one UE after the next: allocate resources */ cur_UE = &UE_sched.head; @@ -214,9 +215,6 @@ int round_robin_dl(module_id_t Mod_id, for (rbg++; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; } - /* just start with the next UE next time */ - g_start_ue_dl = next_ue_list_looped(UE_list, g_start_ue_dl); - return n_rbg_sched; }