diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index da52a8fedcdf9013f47df5231c3f2042fb6353bd..f283140403af5df5f6b0c8b3139dcf5da91c646e 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -80,6 +80,10 @@ float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; float total_slice_percentage = 0; float total_slice_percentage_current = 0; +// Frequency ranges for slice positioning +int slice_position[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX}; +int slice_position_current[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX}; + // MAX MCS for each slice for past and current time int slice_maxmcs[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; int slice_maxmcs_current[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; @@ -445,9 +449,7 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, //------------------------------------------------------------------------------ void -schedule_dlsch(module_id_t module_idP, - frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) -//------------------------------------------------------------------------------{ +schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) { int i = 0; @@ -462,7 +464,7 @@ schedule_dlsch(module_id_t module_idP, for (i = 0; i < n_active_slices; i++) { if (slice_percentage[i] < 0 ){ LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", - module_idP, frameP, subframeP, i, slice_percentage[i]); + module_idP, frameP, subframeP, i, slice_percentage[i]); slice_percentage[i]=0; } total_slice_percentage+=slice_percentage[i]; @@ -482,37 +484,38 @@ schedule_dlsch(module_id_t module_idP, // check if the number of slices has changed, and log if (n_active_slices_current != n_active_slices ){ - if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) { - LOG_I(MAC,"[eNB %d]frame %d subframe %d: number of active DL slices has changed: %d-->%d\n", - module_idP, frameP, subframeP, n_active_slices_current, n_active_slices); - - n_active_slices_current = n_active_slices; - - } else { - LOG_W(MAC,"invalid number of DL slices %d, revert to the previous value %d\n",n_active_slices, n_active_slices_current); - n_active_slices = n_active_slices_current; - } + if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) { + LOG_I(MAC, "[eNB %d]frame %d subframe %d: number of active DL slices has changed: %d-->%d\n", + module_idP, frameP, subframeP, n_active_slices_current, n_active_slices); + n_active_slices_current = n_active_slices; + } else { + LOG_W(MAC, "invalid number of DL slices %d, revert to the previous value %d\n", + n_active_slices, n_active_slices_current); + n_active_slices = n_active_slices_current; + } } // check if the slice rb share has changed, and log the console - if (slice_percentage_current[i] != slice_percentage[i]){ // new slice percentage - LOG_I(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", - module_idP, i, frameP, subframeP, total_slice_percentage_current, total_slice_percentage, slice_percentage_current[i], slice_percentage[i]); - total_slice_percentage_current= total_slice_percentage; - slice_percentage_current[i] = slice_percentage[i]; - + if (slice_percentage_current[i] != slice_percentage[i]) { // new slice percentage + LOG_I(MAC, + "[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", + module_idP, i, frameP, subframeP, total_slice_percentage_current, total_slice_percentage, + slice_percentage_current[i], slice_percentage[i]); + total_slice_percentage_current = total_slice_percentage; + slice_percentage_current[i] = slice_percentage[i]; } // check if the slice max MCS, and log the console - if (slice_maxmcs_current[i] != slice_maxmcs[i]){ - if ((slice_maxmcs[i] >= 0) && (slice_maxmcs[i] < 29)){ - LOG_I(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", - module_idP, i, frameP, subframeP, slice_maxmcs_current[i], slice_maxmcs[i]); - slice_maxmcs_current[i] = slice_maxmcs[i]; - } else { - LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid slice max mcs %d, revert the previous value %d\n",module_idP, i, slice_maxmcs[i],slice_maxmcs_current[i]); - slice_maxmcs[i]= slice_maxmcs_current[i]; - } + if (slice_maxmcs_current[i] != slice_maxmcs[i]) { + if ((slice_maxmcs[i] >= 0) && (slice_maxmcs[i] < 29)) { + LOG_I(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", + module_idP, i, frameP, subframeP, slice_maxmcs_current[i], slice_maxmcs[i]); + slice_maxmcs_current[i] = slice_maxmcs[i]; + } else { + LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid slice max mcs %d, revert the previous value %d\n", + module_idP, i, slice_maxmcs[i], slice_maxmcs_current[i]); + slice_maxmcs[i] = slice_maxmcs_current[i]; + } } // check if a new scheduler, and log the console @@ -541,6 +544,29 @@ schedule_dlsch(module_id_t module_idP, } } + // Check for new slice positions + if (slice_position[i*2] > slice_position[i*2 + 1] || + slice_position[i*2] < 0 || + slice_position[i*2 + 1] > N_RBG_MAX) { + LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid slicing position (%d-%d), using previous values (%d-%d)\n", + module_idP, i, + slice_position[i*2], slice_position[i*2 + 1], + slice_position_current[i*2], slice_position_current[i*2 + 1]); + slice_position[i*2] = slice_position_current[i*2]; + slice_position[i*2 + 1] = slice_position_current[i*2 + 1]; + } else { + if (slice_position_current[i*2] != slice_position[i*2]) { + LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: start frequency has changed (%d-->%d)\n", + module_idP, i, frameP, subframeP, slice_position_current[i*2], slice_position[i*2]); + slice_position_current[i*2] = slice_position[i*2]; + } + if (slice_position_current[i*2 + 1] != slice_position[i*2 + 1]) { + LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: end frequency has changed (%d-->%d)\n", + module_idP, i, frameP, subframeP, slice_position_current[i*2 + 1], slice_position[i*2 + 1]); + slice_position_current[i*2 + 1] = slice_position[i*2 + 1]; + } + } + // Check for new sorting policy if (sorting_policy_current[i] != sorting_policy[i]) { LOG_I(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index aba8c26d92042d55bfb8dcc0393d703f2e7a4323..ab3b535f225c27c0a2b186ac78f4c87fabd96622 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -242,10 +242,10 @@ void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, int N_RBG, int transmission_mode, int min_rb_unit, - uint8_t N_RB_DL, uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_required_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX], unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]); /* \brief Function to trigger the eNB scheduling procedure. It is called by PHY at the beginning of each subframe, \f$n$\f diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 16cbd3fc19cbfb26e811451e831ca606ff8880f3..c21241843142a268fe71c8dd96c3a449a81b3075 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -56,6 +56,7 @@ extern RAN_CONTEXT_t RC; extern float slice_percentage[MAX_NUM_SLICES]; extern float slice_percentage_uplink[MAX_NUM_SLICES]; +extern int slice_position[MAX_NUM_SLICES*2]; extern uint32_t sorting_policy[MAX_NUM_SLICES]; extern int slice_maxmcs[MAX_NUM_SLICES]; @@ -451,6 +452,28 @@ void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) { } } +void decode_slice_positioning(module_id_t Mod_idP, + slice_id_t slice_id, + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]) { + uint8_t CC_id; + int RBG, start_frequency, end_frequency; + + // Init slice_alloc_mask + for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { + for (RBG = 0; RBG < N_RBG_MAX; ++RBG) { + slice_allocation_mask[CC_id][RBG] = 0; + } + } + + start_frequency = slice_position[slice_id*2]; + end_frequency = slice_position[slice_id*2 + 1]; + for (CC_id = 0; CC_id < NFAPI_CC_MAX; ++CC_id) { + for (RBG = start_frequency; RBG <= end_frequency; ++RBG) { + slice_allocation_mask[CC_id][RBG] = 1; + } + } +} + // This fuction sorts the UE in order their dlsch buffer and CQI void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t subframeP) @@ -497,6 +520,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, int N_RBG[NFAPI_CC_MAX], int min_rb_unit[NFAPI_CC_MAX], uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX], uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX], uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]) { @@ -624,11 +648,9 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // control channel or retransmission /* TODO: do we have to check for retransmission? */ if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED || round != 8) { - nb_rbs_required_remaining_1[CC_id][UE_id] = - nb_rbs_required[CC_id][UE_id]; + nb_rbs_required_remaining_1[CC_id][UE_id] = nb_rbs_required[CC_id][UE_id]; } else { - nb_rbs_required_remaining_1[CC_id][UE_id] = - cmin(average_rbs_per_user[CC_id], nb_rbs_required[CC_id][UE_id]); + nb_rbs_required_remaining_1[CC_id][UE_id] = cmin(average_rbs_per_user[CC_id], nb_rbs_required[CC_id][UE_id]); } } } @@ -694,18 +716,17 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // retransmission in data channels // control channel in the 1st transmission // data channel for all TM - LOG_T(MAC, - "calling dlsch_scheduler_pre_processor_allocate .. \n "); - dlsch_scheduler_pre_processor_allocate(Mod_id, UE_id, + LOG_T(MAC, "calling dlsch_scheduler_pre_processor_allocate .. \n "); + dlsch_scheduler_pre_processor_allocate(Mod_id, + UE_id, CC_id, N_RBG[CC_id], transmission_mode, - min_rb_unit - [CC_id], - to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth), + min_rb_unit[CC_id], nb_rbs_required, nb_rbs_required_remaining, rballoc_sub, + slice_allocation_mask, MIMO_mode_indicator); #ifdef TM5 @@ -890,6 +911,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, uint16_t i, j; uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]; + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]; // If TM5 is revisited, we can move this inside accounting int min_rb_unit[NFAPI_CC_MAX]; @@ -947,7 +969,11 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, // Sorts the user on the basis of dlsch logical channel buffer and CQI sort_UEs(Mod_id, slice_id, frameP, subframeP); - // This function does the main allocation of the number of RBs + // TODO: When accounting() is revised, this will be moved inside positioning() + decode_slice_positioning(Mod_id, slice_id, slice_allocation_mask); + + // ACCOUNTING + // This function does the main allocation of the *number* of RBs dlsch_scheduler_pre_processor_accounting(Mod_id, slice_id, frameP, @@ -955,6 +981,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, N_RBG, min_rb_unit, rballoc_sub, + slice_allocation_mask, MIMO_mode_indicator, nb_rbs_required); @@ -1220,65 +1247,66 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, int N_RBG, int transmission_mode, int min_rb_unit, - uint8_t N_RB_DL, uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_required_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX], unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) { - int i; - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - - for (i = 0; i < N_RBG; i++) { - - if ((rballoc_sub[CC_id][i] == 0) && - (ue_sched_ctl->rballoc_sub_UE[CC_id][i] == 0) && - (nb_rbs_required_remaining[CC_id][UE_id] > 0) && - (ue_sched_ctl->pre_nb_available_rbs[CC_id] < - nb_rbs_required[CC_id][UE_id])) { - - // if this UE is not scheduled for TM5 - if (ue_sched_ctl->dl_pow_off[CC_id] != 0) { - - if ((i == N_RBG - 1) - && ((N_RB_DL == 25) || (N_RB_DL == 50))) { - if (nb_rbs_required_remaining[CC_id][UE_id] >= - min_rb_unit - 1) { - rballoc_sub[CC_id][i] = 1; - ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; - MIMO_mode_indicator[CC_id][i] = 1; - if (transmission_mode == 5) { - ue_sched_ctl->dl_pow_off[CC_id] = 1; - } - nb_rbs_required_remaining[CC_id][UE_id] = - nb_rbs_required_remaining[CC_id][UE_id] - - min_rb_unit + 1; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = - ue_sched_ctl->pre_nb_available_rbs[CC_id] + - min_rb_unit - 1; - } - } else { - if (nb_rbs_required_remaining[CC_id][UE_id] >= - min_rb_unit) { - rballoc_sub[CC_id][i] = 1; - ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; - MIMO_mode_indicator[CC_id][i] = 1; - if (transmission_mode == 5) { - ue_sched_ctl->dl_pow_off[CC_id] = 1; - } - nb_rbs_required_remaining[CC_id][UE_id] = - nb_rbs_required_remaining[CC_id][UE_id] - - min_rb_unit; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = - ue_sched_ctl->pre_nb_available_rbs[CC_id] + - min_rb_unit; - } - } - } // dl_pow_off[CC_id][UE_id] ! = 0 - } + int i; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + int N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); + + for (i = 0; i < N_RBG; i++) { + + if (rballoc_sub[CC_id][i] != 0) + continue; + if (ue_sched_ctl->rballoc_sub_UE[CC_id][i] != 0) + continue; + if (nb_rbs_required_remaining[CC_id][UE_id] <= 0) + continue; + if (ue_sched_ctl->pre_nb_available_rbs[CC_id] >= nb_rbs_required[CC_id][UE_id]) + continue; + if (ue_sched_ctl->dl_pow_off[CC_id] == 0) + continue; + if (slice_allocation_mask[CC_id][i] == 0) + continue; + +// if ((rballoc_sub[CC_id][i] == 0) && +// (ue_sched_ctl->rballoc_sub_UE[CC_id][i] == 0) && +// (nb_rbs_required_remaining[CC_id][UE_id] > 0) && +// (ue_sched_ctl->pre_nb_available_rbs[CC_id] < nb_rbs_required[CC_id][UE_id])) { +// // if this UE is not scheduled for TM5 +// if (ue_sched_ctl->dl_pow_off[CC_id] != 0) { + + if ((i == N_RBG - 1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) { + if (nb_rbs_required_remaining[CC_id][UE_id] >= min_rb_unit - 1) { + rballoc_sub[CC_id][i] = 1; + ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; + MIMO_mode_indicator[CC_id][i] = 1; + if (transmission_mode == 5) { + ue_sched_ctl->dl_pow_off[CC_id] = 1; + } + nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit + 1; + ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1; + } + } else { + if (nb_rbs_required_remaining[CC_id][UE_id] >= min_rb_unit) { + rballoc_sub[CC_id][i] = 1; + ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; + MIMO_mode_indicator[CC_id][i] = 1; + if (transmission_mode == 5) { + ue_sched_ctl->dl_pow_off[CC_id] = 1; + } + nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit; + ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit; + } } +// } // dl_pow_off[CC_id][UE_id] ! = 0 +// } + } }