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

Niccolo: Add sorting policy

parent 7b1afbb0
...@@ -100,6 +100,15 @@ typedef enum rb_type_e { ...@@ -100,6 +100,15 @@ typedef enum rb_type_e {
RADIO_ACCESS_BEARER = 2 RADIO_ACCESS_BEARER = 2
} rb_type_t; } rb_type_t;
typedef enum {
CR_ROUND = 0,
CR_SRB12 = 1,
CR_HOL = 2,
CR_LC = 3,
CR_CQI = 4,
CR_NUM = 5
} sorting_criterion_t;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// PHY TYPES // PHY TYPES
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
......
...@@ -963,6 +963,10 @@ typedef struct { ...@@ -963,6 +963,10 @@ typedef struct {
int avail; int avail;
int num_UEs; int num_UEs;
boolean_t active[NUMBER_OF_UE_MAX]; boolean_t active[NUMBER_OF_UE_MAX];
/// Sorting criteria for the UE list in the MAC preprocessor
uint16_t sorting_criteria[MAX_NUM_SLICES][CR_NUM];
} UE_list_t; } UE_list_t;
/*! \brief eNB common channels */ /*! \brief eNB common channels */
......
...@@ -98,6 +98,10 @@ char *dl_scheduler_type[MAX_NUM_SLICES] = ...@@ -98,6 +98,10 @@ 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};
// 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};
...@@ -447,7 +451,7 @@ schedule_dlsch(module_id_t module_idP, ...@@ -447,7 +451,7 @@ schedule_dlsch(module_id_t module_idP,
//------------------------------------------------------------------------------{ //------------------------------------------------------------------------------{
{ {
int i=0; int i = 0;
total_slice_percentage=0; total_slice_percentage=0;
avg_slice_percentage=1.0/n_active_slices; avg_slice_percentage=1.0/n_active_slices;
...@@ -470,7 +474,7 @@ schedule_dlsch(module_id_t module_idP, ...@@ -470,7 +474,7 @@ schedule_dlsch(module_id_t module_idP,
// Load any updated functions // Load any updated functions
if (update_dl_scheduler[i] > 0 ) { if (update_dl_scheduler[i] > 0 ) {
slice_sched_dl[i] = dlsym(NULL, dl_scheduler_type[i]); slice_sched_dl[i] = dlsym(NULL, dl_scheduler_type[i]);
update_dl_scheduler[i] = 0; update_dl_scheduler[i] = 0 ;
update_dl_scheduler_current[i] = 0; update_dl_scheduler_current[i] = 0;
LOG_N(MAC,"update dl scheduler slice %d\n", i); LOG_N(MAC,"update dl scheduler slice %d\n", i);
} }
...@@ -538,6 +542,13 @@ schedule_dlsch(module_id_t module_idP, ...@@ -538,6 +542,13 @@ schedule_dlsch(module_id_t module_idP,
} }
} }
// Check for new sorting policy
if (sorting_policy_current[i] != sorting_policy[i]) {
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, sorting_policy_current[i], sorting_policy[i]);
sorting_policy_current[i] = sorting_policy[i];
}
// Run each enabled slice-specific schedulers one by one // Run each enabled slice-specific schedulers one by one
slice_sched_dl[i](module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/); slice_sched_dl[i](module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/);
} }
......
...@@ -52,13 +52,13 @@ ...@@ -52,13 +52,13 @@
#include "rlc.h" #include "rlc.h"
#define DEBUG_eNB_SCHEDULER 1 #define DEBUG_eNB_SCHEDULER 1
#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 uint32_t sorting_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];
...@@ -352,6 +352,7 @@ struct sort_ue_dl_params { ...@@ -352,6 +352,7 @@ struct sort_ue_dl_params {
int Mod_idP; int Mod_idP;
int frameP; int frameP;
int subframeP; int subframeP;
int slice_id;
}; };
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)
...@@ -359,62 +360,73 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) ...@@ -359,62 +360,73 @@ 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 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 = int round1 = maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP, 1);
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 = int round2 = maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP, 1);
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);
if (round1 > round2) for (i = 0; i < CR_NUM; ++i) {
return -1; switch (UE_list->sorting_criteria[slice_id][i]) {
if (round1 < round2)
return 1; case CR_ROUND :
if (round1 > round2)
if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] + return -1;
UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2] > if (round1 < round2)
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + return 1;
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2]) break;
return -1;
if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] + case CR_SRB12 :
UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2] < if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] +
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2] >
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2]) UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] +
return 1; UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2])
return -1;
if (UE_list-> if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] +
UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max > UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2] <
UE_list-> UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] +
UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max) UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2])
return -1; return 1;
if (UE_list-> break;
UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max <
UE_list-> case CR_HOL :
UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max) if (UE_list-> UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max >
return 1; UE_list-> UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max)
return -1;
if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total > if (UE_list-> UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max <
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total) UE_list-> UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max)
return -1; return 1;
if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total < break;
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total)
return 1; case CR_LC :
if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total >
if (cqi1 > cqi2) UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total)
return -1; return -1;
if (cqi1 < cqi2) if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total <
return 1; UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total)
return 1;
break;
case CR_CQI :
if (cqi1 > cqi2)
return -1;
if (cqi1 < cqi2)
return 1;
default :
break;
}
}
return 0; return 0;
#if 0 #if 0
...@@ -449,40 +461,64 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) ...@@ -449,40 +461,64 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params)
#endif #endif
} }
void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) {
int i;
UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list;
uint32_t policy = sorting_policy[slice_id];
uint32_t mask = 0x0000000F;
uint16_t criterion;
for(i = 0; i < CR_NUM; ++i) {
criterion = (uint16_t)(policy >> 4*(CR_NUM - 1 - i) & mask);
if (criterion >= CR_NUM) {
LOG_W(MAC, "Invalid criterion in slice %d policy, revert to default policy \n", slice_id);
sorting_policy[slice_id] = 0x1234;
break;
}
UE_list->sorting_criteria[slice_id][i] = criterion;
}
}
// This fuction sorts the UE in order their dlsch buffer and CQI // This fuction sorts the UE in order their dlsch buffer and CQI
void sort_UEs(module_id_t Mod_idP, int frameP, sub_frame_t subframeP) void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t subframeP)
{ {
int i; int i;
int list[NUMBER_OF_UE_MAX]; int list[NUMBER_OF_UE_MAX];
int list_size = 0; int list_size = 0;
int rnti; int rnti;
struct sort_ue_dl_params params = { Mod_idP, frameP, subframeP }; struct sort_ue_dl_params params = { Mod_idP, frameP, subframeP, slice_id };
UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list;
for (i = 0; i < NUMBER_OF_UE_MAX; i++) { for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
if (UE_list->active[i] == FALSE) if (UE_list->active[i] == FALSE)
continue; continue;
if ((rnti = UE_RNTI(Mod_idP, i)) == NOT_A_RNTI) if ((rnti = UE_RNTI(Mod_idP, i)) == NOT_A_RNTI)
continue; continue;
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
continue; continue;
if (!ue_slice_membership(i, slice_id))
continue;
list[list_size] = i; list[list_size] = i;
list_size++; list_size++;
} }
qsort_r(list, list_size, sizeof(int), ue_dl_compare, &params); decode_sorting_policy(Mod_idP, slice_id);
if (list_size) { qsort_r(list, list_size, sizeof(int), ue_dl_compare, &params);
for (i = 0; i < list_size - 1; i++)
UE_list->next[list[i]] = list[i + 1]; if (list_size) {
UE_list->next[list[list_size - 1]] = -1; for (i = 0; i < list_size - 1; i++)
UE_list->head = list[0]; UE_list->next[list[i]] = list[i + 1];
} else { UE_list->next[list[list_size - 1]] = -1;
UE_list->head = -1; UE_list->head = list[0];
} } else {
UE_list->head = -1;
}
#if 0 #if 0
...@@ -651,7 +687,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, ...@@ -651,7 +687,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
// Sorts the user on the basis of dlsch logical channel buffer and CQI // Sorts the user on the basis of dlsch logical channel buffer and CQI
sort_UEs(Mod_id, frameP, subframeP); sort_UEs(Mod_id, slice_id, frameP, subframeP);
// loop over all active UEs // loop over all active UEs
......
...@@ -675,7 +675,7 @@ void assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, ...@@ -675,7 +675,7 @@ void assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP,
void adjust_bsr_info(int buffer_occupancy, uint16_t TBS, void adjust_bsr_info(int buffer_occupancy, uint16_t TBS,
UE_TEMPLATE * UE_template); UE_TEMPLATE * UE_template);
int phy_stats_exist(module_id_t Mod_id, int rnti); int phy_stats_exist(module_id_t Mod_id, int rnti);
void sort_UEs (module_id_t Mod_idP, int frameP, sub_frame_t subframeP); void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t subframeP);
/*! \fn UE_L2_state_t ue_scheduler(const module_id_t module_idP,const frame_t frameP, const sub_frame_t subframe, const lte_subframe_t direction,const uint8_t eNB_index) /*! \fn UE_L2_state_t ue_scheduler(const module_id_t module_idP,const frame_t frameP, const sub_frame_t subframe, const lte_subframe_t direction,const uint8_t eNB_index)
\brief UE scheduler where all the ue background tasks are done. This function performs the following: 1) Trigger PDCP every 5ms 2) Call RRC for link status return to PHY3) Perform SR/BSR procedures for scheduling feedback 4) Perform PHR procedures. \brief UE scheduler where all the ue background tasks are done. This function performs the following: 1) Trigger PDCP every 5ms 2) Call RRC for link status return to PHY3) Perform SR/BSR procedures for scheduling feedback 4) Perform PHR procedures.
......
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