Commit 7efd511d authored by Niccolò Iardella's avatar Niccolò Iardella Committed by Robert Schmidt

Bugfix: value of available RBs per slice could be negative

parent ddce5a1f
...@@ -417,8 +417,8 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in ...@@ -417,8 +417,8 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in
int i = 0; int i = 0;
total_slice_percentage=0; slice_percentage_total=0;
avg_slice_percentage=1.0/n_active_slices; slice_percentage_avg=1.0/n_active_slices;
// reset the slice percentage for inactive slices // reset the slice percentage for inactive slices
for (i = n_active_slices; i< MAX_NUM_SLICES; i++) { for (i = n_active_slices; i< MAX_NUM_SLICES; i++) {
...@@ -430,7 +430,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in ...@@ -430,7 +430,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in
module_idP, frameP, subframeP, i, slice_percentage[i]); module_idP, frameP, subframeP, i, slice_percentage[i]);
slice_percentage[i]=0; slice_percentage[i]=0;
} }
total_slice_percentage+=slice_percentage[i]; slice_percentage_total+=slice_percentage[i];
} }
for (i = 0; i < n_active_slices; i++) { for (i = 0; i < n_active_slices; i++) {
...@@ -443,7 +443,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in ...@@ -443,7 +443,7 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in
LOG_I(MAC,"update dl scheduler slice %d\n", i); LOG_I(MAC,"update dl scheduler slice %d\n", i);
} }
if (total_slice_percentage <= 1.0){ // the new total RB share is within the range if (slice_percentage_total <= 1.0){ // the new total RB share is within the range
// check if the number of slices has changed, and log // check if the number of slices has changed, and log
if (n_active_slices_current != n_active_slices ){ if (n_active_slices_current != n_active_slices ){
...@@ -462,9 +462,9 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in ...@@ -462,9 +462,9 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in
if (slice_percentage_current[i] != slice_percentage[i]) { // new slice percentage if (slice_percentage_current[i] != slice_percentage[i]) { // new slice percentage
LOG_I(MAC, LOG_I(MAC,
"[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", "[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, module_idP, i, frameP, subframeP, slice_percentage_total_current, slice_percentage_total,
slice_percentage_current[i], slice_percentage[i]); slice_percentage_current[i], slice_percentage[i]);
total_slice_percentage_current = total_slice_percentage; slice_percentage_total_current = slice_percentage_total;
slice_percentage_current[i] = slice_percentage[i]; slice_percentage_current[i] = slice_percentage[i];
} }
...@@ -493,14 +493,14 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in ...@@ -493,14 +493,14 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in
if (n_active_slices == n_active_slices_current){ if (n_active_slices == n_active_slices_current){
LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n",
module_idP, i, total_slice_percentage_current, total_slice_percentage); module_idP, i, slice_percentage_total_current, slice_percentage_total);
if (slice_percentage[i] >= avg_slice_percentage){ if (slice_percentage[i] >= slice_percentage_avg){
slice_percentage[i]-=0.1; slice_percentage[i]-=0.1;
total_slice_percentage-=0.1; slice_percentage_total-=0.1;
} }
} else { } else {
LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n",
module_idP, i, total_slice_percentage_current, total_slice_percentage, module_idP, i, slice_percentage_total_current, slice_percentage_total,
n_active_slices, n_active_slices_current ); n_active_slices, n_active_slices_current );
n_active_slices = n_active_slices_current; n_active_slices = n_active_slices_current;
slice_percentage[i] = slice_percentage_current[i]; slice_percentage[i] = slice_percentage_current[i];
...@@ -531,22 +531,22 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in ...@@ -531,22 +531,22 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in
} }
// Check for new sorting policy // Check for new sorting policy
if (sorting_policy_current[i] != sorting_policy[i]) { if (slice_sorting_policy_current[i] != slice_sorting_policy[i]) {
LOG_I(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", LOG_I(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n",
module_idP, i, frameP, subframeP, sorting_policy_current[i], sorting_policy[i]); module_idP, i, frameP, subframeP, slice_sorting_policy_current[i], slice_sorting_policy[i]);
sorting_policy_current[i] = sorting_policy[i]; slice_sorting_policy_current[i] = slice_sorting_policy[i];
} }
// Check for new accounting policy // Check for new accounting policy
if (accounting_policy_current[i] != accounting_policy[i]) { if (slice_accounting_policy_current[i] != slice_accounting_policy[i]) {
if (accounting_policy[i] > 1 || accounting_policy[i] < 0) { if (slice_accounting_policy[i] > 1 || slice_accounting_policy[i] < 0) {
LOG_W(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid accounting policy (%d), revert to its previous value (%d)\n", LOG_W(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid accounting policy (%d), revert to its previous value (%d)\n",
module_idP, i, frameP, subframeP, accounting_policy[i], accounting_policy_current[i]); module_idP, i, frameP, subframeP, slice_accounting_policy[i], slice_accounting_policy_current[i]);
accounting_policy[i] = accounting_policy_current[i]; slice_accounting_policy[i] = slice_accounting_policy_current[i];
} else { } else {
LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n",
module_idP, i, frameP, subframeP, accounting_policy_current[i], accounting_policy[i]); module_idP, i, frameP, subframeP, slice_accounting_policy_current[i], slice_accounting_policy[i]);
accounting_policy_current[i] = accounting_policy[i]; slice_accounting_policy_current[i] = slice_accounting_policy[i];
} }
} }
......
...@@ -38,26 +38,34 @@ ...@@ -38,26 +38,34 @@
#define __LAYER2_MAC_ENB_SCHEDULER_DLSCH_H__ #define __LAYER2_MAC_ENB_SCHEDULER_DLSCH_H__
// number of active slices for past and current time // number of active slices for past and current time
int n_active_slices = 1; int n_active_slices = 1;
int n_active_slices_current = 1; int n_active_slices_current = 1;
// RB share for each slice for past and current time // RB share for each slice for past and current time
float avg_slice_percentage=0.25; float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0};
float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0};
float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; float slice_percentage_total = 0;
float total_slice_percentage = 0; float slice_percentage_total_current = 0;
float total_slice_percentage_current = 0; float slice_percentage_avg = 0.25;
// Frequency ranges for slice positioning // 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[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}; 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 // MAX MCS for each slice for past and current time
int slice_maxmcs[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; int slice_maxmcs[MAX_NUM_SLICES] = { 28, 28, 28, 28 };
int slice_maxmcs_current[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; int slice_maxmcs_current[MAX_NUM_SLICES] = { 28, 28, 28, 28 };
int update_dl_scheduler[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; // The lists of criteria that enforce the sorting policies of the slices
int update_dl_scheduler_current[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; uint32_t slice_sorting_policy[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234};
uint32_t slice_sorting_policy_current[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234};
// Accounting policy (just greedy(1) or fair(0) setting for now)
int slice_accounting_policy[MAX_NUM_SLICES] = {0, 0, 0, 0};
int slice_accounting_policy_current[MAX_NUM_SLICES] = {0, 0, 0, 0};
int update_dl_scheduler[MAX_NUM_SLICES] = { 1, 1, 1, 1 };
int update_dl_scheduler_current[MAX_NUM_SLICES] = { 1, 1, 1, 1 };
// name of available scheduler // name of available scheduler
char *dl_scheduler_type[MAX_NUM_SLICES] = char *dl_scheduler_type[MAX_NUM_SLICES] =
...@@ -67,14 +75,6 @@ char *dl_scheduler_type[MAX_NUM_SLICES] = ...@@ -67,14 +75,6 @@ char *dl_scheduler_type[MAX_NUM_SLICES] =
"schedule_ue_spec" "schedule_ue_spec"
}; };
// The lists of criteria that enforce the sorting policies of the slices
uint32_t sorting_policy[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234};
uint32_t sorting_policy_current[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234};
// Accounting policy (just greedy(1) or fair(0) setting for now)
int accounting_policy[MAX_NUM_SLICES] = {0, 0, 0, 0};
int accounting_policy_current[MAX_NUM_SLICES] = {0, 0, 0, 0};
// pointer to the slice specific scheduler // pointer to the slice specific scheduler
slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0}; slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0};
......
...@@ -54,14 +54,13 @@ extern RAN_CONTEXT_t RC; ...@@ -54,14 +54,13 @@ extern RAN_CONTEXT_t RC;
#define DEBUG_HEADER_PARSING 1 #define DEBUG_HEADER_PARSING 1
//#define DEBUG_PACKET_TRACE 1 //#define DEBUG_PACKET_TRACE 1
extern float slice_percentage[MAX_NUM_SLICES]; extern float slice_percentage[MAX_NUM_SLICES];
extern float slice_percentage_uplink[MAX_NUM_SLICES]; extern float slice_percentage_uplink[MAX_NUM_SLICES];
extern int slice_position[MAX_NUM_SLICES*2]; extern int slice_position[MAX_NUM_SLICES*2];
extern uint32_t sorting_policy[MAX_NUM_SLICES]; extern uint32_t slice_sorting_policy[MAX_NUM_SLICES];
extern int accounting_policy[MAX_NUM_SLICES]; extern int slice_accounting_policy[MAX_NUM_SLICES];
extern int slice_maxmcs[MAX_NUM_SLICES];
extern int slice_maxmcs[MAX_NUM_SLICES]; extern int slice_maxmcs_uplink[MAX_NUM_SLICES];
extern int slice_maxmcs_uplink[MAX_NUM_SLICES];
//#define ICIC 0 //#define ICIC 0
...@@ -97,95 +96,89 @@ int phy_stats_exist(module_id_t Mod_id, int rnti) ...@@ -97,95 +96,89 @@ int phy_stats_exist(module_id_t Mod_id, int rnti)
// This function stores the downlink buffer for all the logical channels // This function stores the downlink buffer for all the logical channels
void void
store_dlsch_buffer(module_id_t Mod_id, slice_id_t slice_id, frame_t frameP, store_dlsch_buffer(module_id_t Mod_id,
sub_frame_t subframeP) slice_id_t slice_id,
{ frame_t frameP,
sub_frame_t subframeP) {
int UE_id, i;
rnti_t rnti;
mac_rlc_status_resp_t rlc_status;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
UE_TEMPLATE *UE_template;
for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { int UE_id, i;
if (UE_list->active[UE_id] != TRUE) rnti_t rnti;
continue; mac_rlc_status_resp_t rlc_status;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
UE_TEMPLATE *UE_template;
if (!ue_slice_membership(UE_id, slice_id)) for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) {
if (UE_list->active[UE_id] != TRUE)
continue; continue;
UE_template = if (!ue_slice_membership(UE_id, slice_id))
&UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id]; continue;
// clear logical channel interface variables UE_template =
UE_template->dl_buffer_total = 0; &UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id];
UE_template->dl_pdus_total = 0;
for (i = 0; i < MAX_NUM_LCID; i++) { // clear logical channel interface variables
UE_template->dl_buffer_info[i] = 0; UE_template->dl_buffer_total = 0;
UE_template->dl_pdus_in_buffer[i] = 0; UE_template->dl_pdus_total = 0;
UE_template->dl_buffer_head_sdu_creation_time[i] = 0;
UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = 0;
}
for (i = 0; i < MAX_NUM_LCID; i++) {
UE_template->dl_buffer_info[i] = 0;
UE_template->dl_pdus_in_buffer[i] = 0;
UE_template->dl_buffer_head_sdu_creation_time[i] = 0;
UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = 0;
}
rnti = UE_RNTI(Mod_id, UE_id); rnti = UE_RNTI(Mod_id, UE_id);
for (i = 0; i < MAX_NUM_LCID; i++) { // loop over all the logical channels for (i = 0; i < MAX_NUM_LCID; i++) { // loop over all the logical channels
rlc_status = rlc_status = mac_rlc_status_ind(Mod_id, rnti, Mod_id, frameP, subframeP,
mac_rlc_status_ind(Mod_id, rnti, Mod_id, frameP, subframeP,
ENB_FLAG_YES, MBMS_FLAG_NO, i, 0 ENB_FLAG_YES, MBMS_FLAG_NO, i, 0
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
,0, 0 ,0, 0
#endif #endif
); );
UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel
UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer;
UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer; UE_template->dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time;
UE_template->dl_buffer_head_sdu_creation_time[i] = UE_template->dl_buffer_head_sdu_creation_time_max =
rlc_status.head_sdu_creation_time; cmax(UE_template->dl_buffer_head_sdu_creation_time_max, rlc_status.head_sdu_creation_time);
UE_template->dl_buffer_head_sdu_creation_time_max = UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] =
cmax(UE_template->dl_buffer_head_sdu_creation_time_max, rlc_status.head_sdu_remaining_size_to_send;
rlc_status.head_sdu_creation_time); UE_template->dl_buffer_head_sdu_is_segmented[i] =
UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = rlc_status.head_sdu_is_segmented;
rlc_status.head_sdu_remaining_size_to_send; UE_template->dl_buffer_total += UE_template->dl_buffer_info[i]; //storing the total dlsch buffer
UE_template->dl_buffer_head_sdu_is_segmented[i] = UE_template->dl_pdus_total += UE_template->dl_pdus_in_buffer[i];
rlc_status.head_sdu_is_segmented;
UE_template->dl_buffer_total += UE_template->dl_buffer_info[i]; //storing the total dlsch buffer
UE_template->dl_pdus_total +=
UE_template->dl_pdus_in_buffer[i];
#ifdef DEBUG_eNB_SCHEDULER #ifdef DEBUG_eNB_SCHEDULER
/* note for dl_buffer_head_sdu_remaining_size_to_send[i] : /* note for dl_buffer_head_sdu_remaining_size_to_send[i] :
* 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent
*/ */
if (UE_template->dl_buffer_info[i] > 0) if (UE_template->dl_buffer_info[i] > 0)
LOG_D(MAC, LOG_D(MAC,
"[eNB %d][SLICE %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n", "[eNB %d][SLICE %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n",
Mod_id, slice_id, frameP, subframeP, UE_id, Mod_id, slice_id, frameP, subframeP, UE_id,
i, UE_template->dl_pdus_in_buffer[i], i, UE_template->dl_pdus_in_buffer[i],
UE_template->dl_buffer_info[i], UE_template->dl_buffer_info[i],
UE_template->dl_buffer_head_sdu_creation_time[i], UE_template->dl_buffer_head_sdu_creation_time[i],
UE_template-> UE_template->dl_buffer_head_sdu_remaining_size_to_send[i],
dl_buffer_head_sdu_remaining_size_to_send[i], UE_template->dl_buffer_head_sdu_is_segmented[i]);
UE_template->dl_buffer_head_sdu_is_segmented[i]);
#endif #endif
} }
//#ifdef DEBUG_eNB_SCHEDULER //#ifdef DEBUG_eNB_SCHEDULER
if (UE_template->dl_buffer_total > 0) if (UE_template->dl_buffer_total > 0)
LOG_D(MAC, LOG_D(MAC,
"[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n", "[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n",
Mod_id, frameP, subframeP, UE_id, Mod_id, frameP, subframeP, UE_id,
UE_template->dl_buffer_total, UE_template->dl_buffer_total,
UE_template->dl_pdus_total); UE_template->dl_pdus_total);
//#endif //#endif
} }
} }
...@@ -199,156 +192,133 @@ assign_rbs_required(module_id_t Mod_id, ...@@ -199,156 +192,133 @@ assign_rbs_required(module_id_t Mod_id,
uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]) uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB])
{ {
uint16_t TBS = 0; uint16_t TBS = 0;
int UE_id, n, i, j, CC_id, pCCid, tmp; int UE_id, n, i, j, CC_id, pCCid, tmp;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
eNB_UE_STATS *eNB_UE_stats, *eNB_UE_stats_i, *eNB_UE_stats_j; eNB_UE_STATS *eNB_UE_stats, *eNB_UE_stats_i, *eNB_UE_stats_j;
int N_RB_DL; int N_RB_DL;
// clear rb allocations across all CC_id // clear rb allocations across all CC_id
for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) {
if (UE_list->active[UE_id] != TRUE) if (UE_list->active[UE_id] != TRUE) continue;
continue; if (!ue_slice_membership(UE_id, slice_id)) continue;
if (!ue_slice_membership(UE_id, slice_id)) pCCid = UE_PCCID(Mod_id, UE_id);
continue;
pCCid = UE_PCCID(Mod_id, UE_id);
//update CQI information across component carriers //update CQI information across component carriers
for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) { for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) {
CC_id = UE_list->ordered_CCids[n][UE_id];
eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
eNB_UE_stats->dlsch_mcs1 =cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], CC_id = UE_list->ordered_CCids[n][UE_id];
slice_maxmcs[slice_id]); eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
eNB_UE_stats->dlsch_mcs1 = cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], slice_maxmcs[slice_id]);
} }
// provide the list of CCs sorted according to MCS // provide the list of CCs sorted according to MCS
for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) { for (i = 0; i < UE_list->numactiveCCs[UE_id]; ++i) {
eNB_UE_stats_i = eNB_UE_stats_i = &UE_list->eNB_UE_stats[UE_list->ordered_CCids[i][UE_id]][UE_id];
&UE_list->eNB_UE_stats[UE_list-> for (j = i + 1; j < UE_list->numactiveCCs[UE_id]; j++) {
ordered_CCids[i][UE_id]][UE_id]; DevAssert(j < NFAPI_CC_MAX);
for (j = i + 1; j < UE_list->numactiveCCs[UE_id]; j++) { eNB_UE_stats_j = &UE_list->eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]][UE_id];
DevAssert(j < NFAPI_CC_MAX); if (eNB_UE_stats_j->dlsch_mcs1 > eNB_UE_stats_i->dlsch_mcs1) {
eNB_UE_stats_j = tmp = UE_list->ordered_CCids[i][UE_id];
&UE_list-> UE_list->ordered_CCids[i][UE_id] = UE_list->ordered_CCids[j][UE_id];
eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]][UE_id]; UE_list->ordered_CCids[j][UE_id] = tmp;
if (eNB_UE_stats_j->dlsch_mcs1 > }
eNB_UE_stats_i->dlsch_mcs1) { }
tmp = UE_list->ordered_CCids[i][UE_id]; }
UE_list->ordered_CCids[i][UE_id] =
UE_list->ordered_CCids[j][UE_id];
UE_list->ordered_CCids[j][UE_id] = tmp;
}
}
}
if (UE_list->UE_template[pCCid][UE_id].dl_buffer_total > 0) { if (UE_list->UE_template[pCCid][UE_id].dl_buffer_total > 0) {
LOG_D(MAC, "[preprocessor] assign RB for UE %d\n", UE_id); LOG_D(MAC, "[preprocessor] assign RB for UE %d\n", UE_id);
for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) { for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) {
CC_id = UE_list->ordered_CCids[i][UE_id]; CC_id = UE_list->ordered_CCids[i][UE_id];
eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
if (eNB_UE_stats->dlsch_mcs1 == 0) { if (eNB_UE_stats->dlsch_mcs1 == 0) {
nb_rbs_required[CC_id][UE_id] = 4; // don't let the TBS get too small nb_rbs_required[CC_id][UE_id] = 4; // don't let the TBS get too small
} else { } else {
nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id]; nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id];
} }
TBS = TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rbs_required[CC_id][UE_id]);
get_TBS_DL(eNB_UE_stats->dlsch_mcs1,
nb_rbs_required[CC_id][UE_id]);
LOG_D(MAC, LOG_D(MAC,
"[preprocessor] start RB assignement for UE %d CC_id %d dl buffer %d (RB unit %d, MCS %d, TBS %d) \n", "[preprocessor] start RB assignement for UE %d CC_id %d dl buffer %d (RB unit %d, MCS %d, TBS %d) \n",
UE_id, CC_id, UE_id, CC_id,
UE_list->UE_template[pCCid][UE_id].dl_buffer_total, UE_list->UE_template[pCCid][UE_id].dl_buffer_total,
nb_rbs_required[CC_id][UE_id], nb_rbs_required[CC_id][UE_id],
eNB_UE_stats->dlsch_mcs1, TBS); eNB_UE_stats->dlsch_mcs1, TBS);
N_RB_DL = N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
to_prb(RC.mac[Mod_id]->common_channels[CC_id].
mib->message.dl_Bandwidth);
UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id] = UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id] =
nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL); nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL);
/* calculating required number of RBs for each UE */ /* calculating required number of RBs for each UE */
while (TBS < while (TBS < UE_list->UE_template[pCCid][UE_id].dl_buffer_total) {
UE_list->UE_template[pCCid][UE_id]. nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id];
dl_buffer_total) {
nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id]; if (nb_rbs_required[CC_id][UE_id] > UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]) {
TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]);
if (nb_rbs_required[CC_id][UE_id] > UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]) { nb_rbs_required[CC_id][UE_id] = UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id];
TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]); break;
nb_rbs_required[CC_id][UE_id] = UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]; }
break; TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rbs_required[CC_id][UE_id]);
} } // end of while
TBS = LOG_D(MAC,
get_TBS_DL(eNB_UE_stats->dlsch_mcs1, "[eNB %d] Frame %d: UE %d on CC %d: RB unit %d, nb_required RB %d (TBS %d, mcs %d)\n",
nb_rbs_required[CC_id][UE_id]); Mod_id, frameP, UE_id, CC_id, min_rb_unit[CC_id],
} // end of while nb_rbs_required[CC_id][UE_id], TBS,
eNB_UE_stats->dlsch_mcs1);
LOG_D(MAC, }
"[eNB %d] Frame %d: UE %d on CC %d: RB unit %d, nb_required RB %d (TBS %d, mcs %d)\n",
Mod_id, frameP, UE_id, CC_id, min_rb_unit[CC_id],
nb_rbs_required[CC_id][UE_id], TBS,
eNB_UE_stats->dlsch_mcs1);
}
}
} }
}
} }
// This function scans all CC_ids for a particular UE to find the maximum round index of its HARQ processes // This function scans all CC_ids for a particular UE to find the maximum round index of its HARQ processes
int int
maxround(module_id_t Mod_id, uint16_t rnti, int frame, maxround(module_id_t Mod_id, uint16_t rnti, int frame,
sub_frame_t subframe, uint8_t ul_flag) sub_frame_t subframe, uint8_t ul_flag) {
{
uint8_t round, round_max = 0, UE_id;
int CC_id, harq_pid;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
COMMON_channels_t *cc;
for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { uint8_t round, round_max = 0, UE_id;
int CC_id, harq_pid;
cc = &RC.mac[Mod_id]->common_channels[CC_id]; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
COMMON_channels_t *cc;
UE_id = find_UE_id(Mod_id, rnti); for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) {
cc = &RC.mac[Mod_id]->common_channels[CC_id];
harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frame ,subframe); UE_id = find_UE_id(Mod_id, rnti);
harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frame ,subframe);
round = UE_list->UE_sched_ctrl[UE_id].round[CC_id][harq_pid]; round = UE_list->UE_sched_ctrl[UE_id].round[CC_id][harq_pid];
if (round > round_max) { if (round > round_max) {
round_max = round; round_max = round;
}
} }
}
return round_max; return round_max;
} }
// This function scans all CC_ids for a particular UE to find the maximum DL CQI // This function scans all CC_ids for a particular UE to find the maximum DL CQI
// it returns -1 if the UE is not found in PHY layer (get_eNB_UE_stats gives NULL) // it returns -1 if the UE is not found in PHY layer (get_eNB_UE_stats gives NULL)
int maxcqi(module_id_t Mod_id, int32_t UE_id) int maxcqi(module_id_t Mod_id, int32_t UE_id) {
{ UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; int CC_id, n;
int CC_id, n; int CQI = 0;
int CQI = 0;
for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) { for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) {
CC_id = UE_list->ordered_CCids[n][UE_id]; CC_id = UE_list->ordered_CCids[n][UE_id];
if (UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id] > CQI) { if (UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id] > CQI) {
CQI = UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]; CQI = UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id];
}
} }
}
return CQI; return CQI;
} }
struct sort_ue_dl_params { struct sort_ue_dl_params {
...@@ -360,24 +330,24 @@ struct sort_ue_dl_params { ...@@ -360,24 +330,24 @@ struct sort_ue_dl_params {
static int ue_dl_compare(const void *_a, const void *_b, void *_params) static int ue_dl_compare(const void *_a, const void *_b, void *_params)
{ {
struct sort_ue_dl_params *params = _params; struct sort_ue_dl_params *params = _params;
UE_list_t *UE_list = &RC.mac[params->Mod_idP]->UE_list; UE_list_t *UE_list = &RC.mac[params->Mod_idP]->UE_list;
int i; int i;
int slice_id = params->slice_id; int slice_id = params->slice_id;
int UE_id1 = *(const int *) _a; int UE_id1 = *(const int *) _a;
int UE_id2 = *(const int *) _b; int UE_id2 = *(const int *) _b;
int rnti1 = UE_RNTI(params->Mod_idP, UE_id1); int rnti1 = UE_RNTI(params->Mod_idP, UE_id1);
int pCC_id1 = UE_PCCID(params->Mod_idP, UE_id1); int pCC_id1 = UE_PCCID(params->Mod_idP, UE_id1);
int round1 = maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP, 1); int round1 = maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP, 1);
int rnti2 = UE_RNTI(params->Mod_idP, UE_id2); int rnti2 = UE_RNTI(params->Mod_idP, UE_id2);
int pCC_id2 = UE_PCCID(params->Mod_idP, UE_id2); int pCC_id2 = UE_PCCID(params->Mod_idP, UE_id2);
int round2 = maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP, 1); int round2 = maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP, 1);
int cqi1 = maxcqi(params->Mod_idP, UE_id1); int cqi1 = maxcqi(params->Mod_idP, UE_id1);
int cqi2 = maxcqi(params->Mod_idP, UE_id2); int cqi2 = maxcqi(params->Mod_idP, UE_id2);
for (i = 0; i < CR_NUM; ++i) { for (i = 0; i < CR_NUM; ++i) {
switch (UE_list->sorting_criteria[slice_id][i]) { switch (UE_list->sorting_criteria[slice_id][i]) {
...@@ -435,22 +405,22 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) ...@@ -435,22 +405,22 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params)
} }
void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) { void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) {
int i; int i;
UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list;
uint32_t policy = sorting_policy[slice_id]; uint32_t policy = slice_sorting_policy[slice_id];
uint32_t mask = 0x0000000F; uint32_t mask = 0x0000000F;
uint16_t criterion; uint16_t criterion;
for(i = 0; i < CR_NUM; ++i) { for (i = 0; i < CR_NUM; ++i) {
criterion = (uint16_t)(policy >> 4*(CR_NUM - 1 - i) & mask); criterion = (uint16_t) (policy >> 4 * (CR_NUM - 1 - i) & mask);
if (criterion >= CR_NUM) { if (criterion >= CR_NUM) {
LOG_W(MAC, "Invalid criterion in slice %d policy, revert to default policy \n", slice_id); LOG_W(MAC, "Invalid criterion in slice %d policy, revert to default policy \n", slice_id);
sorting_policy[slice_id] = 0x1234; slice_sorting_policy[slice_id] = 0x1234;
break; break;
} }
UE_list->sorting_criteria[slice_id][i] = criterion; UE_list->sorting_criteria[slice_id][i] = criterion;
} }
} }
void decode_slice_positioning(module_id_t Mod_idP, void decode_slice_positioning(module_id_t Mod_idP,
...@@ -589,6 +559,7 @@ void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, ...@@ -589,6 +559,7 @@ void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id,
int UE_id, CC_id, N_RB_DL, i; int UE_id, CC_id, N_RB_DL, i;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
UE_sched_ctrl *ue_sched_ctl; UE_sched_ctrl *ue_sched_ctl;
uint16_t available_rbs;
for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
...@@ -601,7 +572,11 @@ void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, ...@@ -601,7 +572,11 @@ void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id,
for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) {
CC_id = UE_list->ordered_CCids[i][UE_id]; CC_id = UE_list->ordered_CCids[i][UE_id];
N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL) - rbs_retx[CC_id]; available_rbs = nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL);
if (rbs_retx[CC_id] < available_rbs)
ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = available_rbs - rbs_retx[CC_id];
else
ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = 0;
} }
} }
} }
...@@ -680,7 +655,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, ...@@ -680,7 +655,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
// Reduces the available RBs according to slicing configuration // Reduces the available RBs according to slicing configuration
dlsch_scheduler_pre_processor_partitioning(Mod_id, slice_id, rbs_retx); dlsch_scheduler_pre_processor_partitioning(Mod_id, slice_id, rbs_retx);
switch (accounting_policy[slice_id]) { switch (slice_accounting_policy[slice_id]) {
// If greedy scheduling, try to account all the required RBs // If greedy scheduling, try to account all the required RBs
case 1: case 1:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment