Niccolo: Add sorting policy
This commit is contained in:
committed by
Robert Schmidt
parent
7b1afbb0bf
commit
7e3b1f5d0a
@@ -100,6 +100,15 @@ typedef enum rb_type_e {
|
||||
RADIO_ACCESS_BEARER = 2
|
||||
} 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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -963,6 +963,10 @@ typedef struct {
|
||||
int avail;
|
||||
int num_UEs;
|
||||
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;
|
||||
|
||||
/*! \brief eNB common channels */
|
||||
|
||||
@@ -98,6 +98,10 @@ char *dl_scheduler_type[MAX_NUM_SLICES] =
|
||||
"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
|
||||
slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0};
|
||||
|
||||
@@ -447,7 +451,7 @@ schedule_dlsch(module_id_t module_idP,
|
||||
//------------------------------------------------------------------------------{
|
||||
{
|
||||
|
||||
int i=0;
|
||||
int i = 0;
|
||||
|
||||
total_slice_percentage=0;
|
||||
avg_slice_percentage=1.0/n_active_slices;
|
||||
@@ -470,7 +474,7 @@ schedule_dlsch(module_id_t module_idP,
|
||||
// Load any updated functions
|
||||
if (update_dl_scheduler[i] > 0 ) {
|
||||
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;
|
||||
LOG_N(MAC,"update dl scheduler slice %d\n", i);
|
||||
}
|
||||
@@ -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
|
||||
slice_sched_dl[i](module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/);
|
||||
}
|
||||
|
||||
@@ -52,13 +52,13 @@
|
||||
#include "rlc.h"
|
||||
|
||||
|
||||
|
||||
#define DEBUG_eNB_SCHEDULER 1
|
||||
#define DEBUG_HEADER_PARSING 1
|
||||
//#define DEBUG_PACKET_TRACE 1
|
||||
|
||||
extern float slice_percentage[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_uplink[MAX_NUM_SLICES];
|
||||
@@ -352,6 +352,7 @@ struct sort_ue_dl_params {
|
||||
int Mod_idP;
|
||||
int frameP;
|
||||
int subframeP;
|
||||
int slice_id;
|
||||
};
|
||||
|
||||
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;
|
||||
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_id2 = *(const int *) _b;
|
||||
|
||||
int rnti1 = UE_RNTI(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 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 cqi2 = maxcqi(params->Mod_idP, UE_id2);
|
||||
|
||||
if (round1 > round2)
|
||||
return -1;
|
||||
if (round1 < round2)
|
||||
return 1;
|
||||
for (i = 0; i < CR_NUM; ++i) {
|
||||
switch (UE_list->sorting_criteria[slice_id][i]) {
|
||||
|
||||
if (UE_list->UE_template[pCC_id1][UE_id1].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[1] +
|
||||
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2])
|
||||
return -1;
|
||||
if (UE_list->UE_template[pCC_id1][UE_id1].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[1] +
|
||||
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2])
|
||||
return 1;
|
||||
case CR_ROUND :
|
||||
if (round1 > round2)
|
||||
return -1;
|
||||
if (round1 < round2)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
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_head_sdu_creation_time_max)
|
||||
return -1;
|
||||
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_head_sdu_creation_time_max)
|
||||
return 1;
|
||||
case CR_SRB12 :
|
||||
if (UE_list->UE_template[pCC_id1][UE_id1].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[1] +
|
||||
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2])
|
||||
return -1;
|
||||
if (UE_list->UE_template[pCC_id1][UE_id1].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[1] +
|
||||
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2])
|
||||
return 1;
|
||||
break;
|
||||
|
||||
if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total >
|
||||
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total)
|
||||
return -1;
|
||||
if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total <
|
||||
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total)
|
||||
return 1;
|
||||
case CR_HOL :
|
||||
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_head_sdu_creation_time_max)
|
||||
return -1;
|
||||
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_head_sdu_creation_time_max)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
if (cqi1 > cqi2)
|
||||
return -1;
|
||||
if (cqi1 < cqi2)
|
||||
return 1;
|
||||
case CR_LC :
|
||||
if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total >
|
||||
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total)
|
||||
return -1;
|
||||
if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total <
|
||||
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;
|
||||
#if 0
|
||||
@@ -449,40 +461,64 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params)
|
||||
#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
|
||||
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 list[NUMBER_OF_UE_MAX];
|
||||
int list_size = 0;
|
||||
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;
|
||||
|
||||
for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
||||
for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
||||
|
||||
if (UE_list->active[i] == FALSE)
|
||||
continue;
|
||||
if ((rnti = UE_RNTI(Mod_idP, i)) == NOT_A_RNTI)
|
||||
continue;
|
||||
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
|
||||
continue;
|
||||
if (UE_list->active[i] == FALSE)
|
||||
continue;
|
||||
if ((rnti = UE_RNTI(Mod_idP, i)) == NOT_A_RNTI)
|
||||
continue;
|
||||
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
|
||||
continue;
|
||||
if (!ue_slice_membership(i, slice_id))
|
||||
continue;
|
||||
|
||||
list[list_size] = i;
|
||||
list_size++;
|
||||
}
|
||||
list[list_size] = i;
|
||||
list_size++;
|
||||
}
|
||||
|
||||
qsort_r(list, list_size, sizeof(int), ue_dl_compare, ¶ms);
|
||||
decode_sorting_policy(Mod_idP, slice_id);
|
||||
|
||||
if (list_size) {
|
||||
for (i = 0; i < list_size - 1; i++)
|
||||
UE_list->next[list[i]] = list[i + 1];
|
||||
UE_list->next[list[list_size - 1]] = -1;
|
||||
UE_list->head = list[0];
|
||||
} else {
|
||||
UE_list->head = -1;
|
||||
}
|
||||
qsort_r(list, list_size, sizeof(int), ue_dl_compare, ¶ms);
|
||||
|
||||
if (list_size) {
|
||||
for (i = 0; i < list_size - 1; i++)
|
||||
UE_list->next[list[i]] = list[i + 1];
|
||||
UE_list->next[list[list_size - 1]] = -1;
|
||||
UE_list->head = list[0];
|
||||
} else {
|
||||
UE_list->head = -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
@@ -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
|
||||
sort_UEs(Mod_id, frameP, subframeP);
|
||||
sort_UEs(Mod_id, slice_id, frameP, subframeP);
|
||||
|
||||
|
||||
// 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,
|
||||
void adjust_bsr_info(int buffer_occupancy, uint16_t TBS,
|
||||
UE_TEMPLATE * UE_template);
|
||||
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)
|
||||
\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.
|
||||
|
||||
Reference in New Issue
Block a user