Move the accounting phase of the DL pre-processor in a separate procedure
This commit is contained in:
committed by
Navid Nikaein
parent
5357ef2050
commit
10e91d4e2f
+182
-178
@@ -593,119 +593,58 @@ void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
|
||||||
|
|
||||||
|
|
||||||
// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done
|
|
||||||
void
|
|
||||||
dlsch_scheduler_pre_processor(module_id_t Mod_id,
|
|
||||||
slice_id_t slice_id,
|
slice_id_t slice_id,
|
||||||
frame_t frameP,
|
frame_t frameP,
|
||||||
sub_frame_t subframeP,
|
sub_frame_t subframeP,
|
||||||
int N_RBG[MAX_NUM_CCs], int *mbsfn_flag)
|
int N_RBG[MAX_NUM_CCs],
|
||||||
{
|
int min_rb_unit[MAX_NUM_CCs],
|
||||||
|
uint8_t rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
|
||||||
|
uint8_t MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX],
|
||||||
|
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]) {
|
||||||
|
|
||||||
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], harq_pid =
|
|
||||||
0, round = 0, total_ue_count[MAX_NUM_CCs], total_rbs_used[MAX_NUM_CCs];
|
int UE_id, CC_id;
|
||||||
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX];
|
int ii, r1;
|
||||||
int UE_id, i;
|
|
||||||
uint16_t ii, j;
|
rnti_t rnti;
|
||||||
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
|
uint8_t harq_pid, round, transmission_mode;
|
||||||
|
uint8_t total_rbs_used[MAX_NUM_CCs];
|
||||||
|
uint8_t total_ue_count[MAX_NUM_CCs];
|
||||||
|
uint16_t average_rbs_per_user[MAX_NUM_CCs];
|
||||||
uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
|
uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
|
||||||
uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
|
uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
|
||||||
uint16_t average_rbs_per_user[MAX_NUM_CCs] = { 0 };
|
|
||||||
rnti_t rnti;
|
|
||||||
int min_rb_unit[MAX_NUM_CCs];
|
|
||||||
uint16_t r1 = 0;
|
|
||||||
uint8_t CC_id;
|
|
||||||
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
|
|
||||||
|
|
||||||
int N_RB_DL;
|
int N_RB_DL;
|
||||||
int transmission_mode = 0;
|
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
|
||||||
UE_sched_ctrl *ue_sched_ctl;
|
UE_sched_ctrl *ue_sched_ctl;
|
||||||
// int rrc_status = RRC_IDLE;
|
|
||||||
COMMON_channels_t *cc;
|
COMMON_channels_t *cc;
|
||||||
|
|
||||||
#ifdef TM5
|
|
||||||
int harq_pid1 = 0;
|
|
||||||
int round1 = 0, round2 = 0;
|
|
||||||
int UE_id2;
|
|
||||||
uint16_t i1, i2, i3;
|
|
||||||
rnti_t rnti1, rnti2;
|
|
||||||
LTE_eNB_UE_stats *eNB_UE_stats1 = NULL;
|
|
||||||
LTE_eNB_UE_stats *eNB_UE_stats2 = NULL;
|
|
||||||
UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||||
|
total_ue_count[CC_id] = 0;
|
||||||
if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here
|
total_rbs_used[CC_id] = 0;
|
||||||
continue;
|
average_rbs_per_user[CC_id] = 0;
|
||||||
|
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; ++UE_id) {
|
||||||
|
nb_rbs_required_remaining[CC_id][UE_id] = 0;
|
||||||
|
|
||||||
min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id);
|
|
||||||
|
|
||||||
for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
|
||||||
if (UE_list->active[i] != TRUE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!ue_slice_membership(i, slice_id))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
UE_id = i;
|
|
||||||
// Initialize scheduling information for all active UEs
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dlsch_scheduler_pre_processor_reset(Mod_id,
|
|
||||||
UE_id,
|
|
||||||
CC_id,
|
|
||||||
frameP,
|
|
||||||
subframeP,
|
|
||||||
N_RBG[CC_id],
|
|
||||||
nb_rbs_required,
|
|
||||||
nb_rbs_required_remaining,
|
|
||||||
total_ue_count,
|
|
||||||
total_rbs_used,
|
|
||||||
rballoc_sub,
|
|
||||||
MIMO_mode_indicator);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Store the DLSCH buffer for each logical channel
|
|
||||||
store_dlsch_buffer(Mod_id, slice_id,frameP, subframeP);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate the number of RBs required by each UE on the basis of logical channel's buffer
|
|
||||||
assign_rbs_required(Mod_id, slice_id, frameP, subframeP, nb_rbs_required,
|
|
||||||
min_rb_unit);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Sorts the user on the basis of dlsch logical channel buffer and CQI
|
|
||||||
sort_UEs(Mod_id, slice_id, frameP, subframeP);
|
|
||||||
|
|
||||||
|
|
||||||
// loop over all active UEs
|
// loop over all active UEs
|
||||||
for (i = UE_list->head; i >= 0; i = UE_list->next[i]) {
|
for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||||
rnti = UE_RNTI(Mod_id, i);
|
rnti = UE_RNTI(Mod_id, UE_id);
|
||||||
|
|
||||||
if (rnti == NOT_A_RNTI)
|
if (rnti == NOT_A_RNTI)
|
||||||
continue;
|
continue;
|
||||||
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
|
if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
|
||||||
continue;
|
continue;
|
||||||
UE_id = i;
|
|
||||||
if (!ue_slice_membership(UE_id, slice_id))
|
if (!ue_slice_membership(UE_id, slice_id))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) {
|
for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) {
|
||||||
CC_id = UE_list->ordered_CCids[ii][UE_id];
|
CC_id = UE_list->ordered_CCids[ii][UE_id];
|
||||||
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||||
cc = &RC.mac[Mod_id]->common_channels[ii];
|
cc = &RC.mac[Mod_id]->common_channels[CC_id];
|
||||||
|
// TODO Can we use subframe2harqpid() here?
|
||||||
if (cc->tdd_Config)
|
if (cc->tdd_Config)
|
||||||
harq_pid = ((frameP * 10) + subframeP) % 10;
|
harq_pid = ((frameP * 10) + subframeP) % 10;
|
||||||
else
|
else
|
||||||
@@ -714,10 +653,8 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
|
|||||||
|
|
||||||
average_rbs_per_user[CC_id] = 0;
|
average_rbs_per_user[CC_id] = 0;
|
||||||
|
|
||||||
|
|
||||||
if (round != 8) {
|
if (round != 8) {
|
||||||
nb_rbs_required[CC_id][UE_id] =
|
nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
|
||||||
UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
|
|
||||||
total_rbs_used[CC_id] += nb_rbs_required[CC_id][UE_id];
|
total_rbs_used[CC_id] += nb_rbs_required[CC_id][UE_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -725,19 +662,17 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
|
|||||||
if (nb_rbs_required[CC_id][UE_id] > 0) {
|
if (nb_rbs_required[CC_id][UE_id] > 0) {
|
||||||
total_ue_count[CC_id] = total_ue_count[CC_id] + 1;
|
total_ue_count[CC_id] = total_ue_count[CC_id] + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop over all active UEs and calculate avg rb per user based on total active UEs
|
// loop over all active UEs and calculate avg rb per user based on total active UEs
|
||||||
for (i = UE_list->head; i >= 0; i = UE_list->next[i]) {
|
for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||||
rnti = UE_RNTI(Mod_id, i);
|
rnti = UE_RNTI(Mod_id, UE_id);
|
||||||
|
|
||||||
if (rnti == NOT_A_RNTI)
|
if (rnti == NOT_A_RNTI)
|
||||||
continue;
|
continue;
|
||||||
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
|
if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
|
||||||
continue;
|
continue;
|
||||||
UE_id = i;
|
|
||||||
if (!ue_slice_membership(UE_id, slice_id))
|
if (!ue_slice_membership(UE_id, slice_id))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -754,54 +689,57 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
|
|||||||
* per user by a coefficient which represents the degree of priority.
|
* per user by a coefficient which represents the degree of priority.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth) - total_rbs_used[CC_id];
|
||||||
|
|
||||||
N_RB_DL =
|
// recalculate based on the what is left after retransmission
|
||||||
to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->
|
|
||||||
message.dl_Bandwidth) - total_rbs_used[CC_id];
|
|
||||||
|
|
||||||
//recalcualte based on the what is left after retransmission
|
|
||||||
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||||
ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id]= flexran_nb_rbs_allowed_slice(slice_percentage[slice_id],N_RB_DL);
|
ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] =
|
||||||
|
flexran_nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL);
|
||||||
|
|
||||||
if (total_ue_count[CC_id] == 0) {
|
if (total_ue_count[CC_id] == 0) {
|
||||||
average_rbs_per_user[CC_id] = 0;
|
average_rbs_per_user[CC_id] = 0;
|
||||||
} else if ((min_rb_unit[CC_id] * total_ue_count[CC_id]) <= (ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id])) {
|
} else if ((min_rb_unit[CC_id] * total_ue_count[CC_id]) <=
|
||||||
|
(ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id])) {
|
||||||
average_rbs_per_user[CC_id] =
|
average_rbs_per_user[CC_id] =
|
||||||
(uint16_t) floor(ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] / total_ue_count[CC_id]);
|
(uint16_t) floor(ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] / total_ue_count[CC_id]);
|
||||||
} else {
|
} else {
|
||||||
average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE
|
// consider the total number of use that can be scheduled UE
|
||||||
|
average_rbs_per_user[CC_id] = min_rb_unit[CC_id];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// note: nb_rbs_required is assigned according to total_buffer_dl
|
// note: nb_rbs_required is assigned according to total_buffer_dl
|
||||||
// extend nb_rbs_required to capture per LCID RB required
|
// extend nb_rbs_required to capture per LCID RB required
|
||||||
for (i = UE_list->head; i >= 0; i = UE_list->next[i]) {
|
for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||||
rnti = UE_RNTI(Mod_id, i);
|
rnti = UE_RNTI(Mod_id, UE_id);
|
||||||
|
|
||||||
if (rnti == NOT_A_RNTI)
|
if (rnti == NOT_A_RNTI)
|
||||||
continue;
|
continue;
|
||||||
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
|
if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
|
||||||
continue;
|
continue;
|
||||||
if (!ue_slice_membership(i, slice_id))
|
if (!ue_slice_membership(UE_id, slice_id))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (ii = 0; ii < UE_num_active_CC(UE_list, i); ii++) {
|
for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) {
|
||||||
CC_id = UE_list->ordered_CCids[ii][i];
|
CC_id = UE_list->ordered_CCids[ii][UE_id];
|
||||||
ue_sched_ctl = &UE_list->UE_sched_ctrl[i];
|
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||||
|
cc = &RC.mac[Mod_id]->common_channels[CC_id];
|
||||||
|
// TODO Can we use subframe2harqpid() here?
|
||||||
|
if (cc->tdd_Config)
|
||||||
|
harq_pid = ((frameP * 10) + subframeP) % 10;
|
||||||
|
else
|
||||||
|
harq_pid = ((frameP * 10) + subframeP) & 7;
|
||||||
round = ue_sched_ctl->round[CC_id][harq_pid];
|
round = ue_sched_ctl->round[CC_id][harq_pid];
|
||||||
|
|
||||||
// control channel or retransmission
|
// control channel or retransmission
|
||||||
/* TODO: do we have to check for retransmission? */
|
/* TODO: do we have to check for retransmission? */
|
||||||
if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED
|
if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED || round > 0) {
|
||||||
|| round > 0) {
|
nb_rbs_required_remaining_1[CC_id][UE_id] =
|
||||||
nb_rbs_required_remaining_1[CC_id][i] =
|
nb_rbs_required[CC_id][UE_id];
|
||||||
nb_rbs_required[CC_id][i];
|
|
||||||
} else {
|
} else {
|
||||||
nb_rbs_required_remaining_1[CC_id][i] =
|
nb_rbs_required_remaining_1[CC_id][UE_id] =
|
||||||
cmin(average_rbs_per_user[CC_id],
|
cmin(average_rbs_per_user[CC_id], nb_rbs_required[CC_id][UE_id]);
|
||||||
nb_rbs_required[CC_id][i]);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -811,47 +749,45 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
|
|||||||
// 2nd stage: remaining RBs are allocated to high priority UEs
|
// 2nd stage: remaining RBs are allocated to high priority UEs
|
||||||
for (r1 = 0; r1 < 2; r1++) {
|
for (r1 = 0; r1 < 2; r1++) {
|
||||||
|
|
||||||
for (i = UE_list->head; i >= 0; i = UE_list->next[i]) {
|
for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||||
for (ii = 0; ii < UE_num_active_CC(UE_list, i); ii++) {
|
for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) {
|
||||||
CC_id = UE_list->ordered_CCids[ii][i];
|
CC_id = UE_list->ordered_CCids[ii][UE_id];
|
||||||
|
|
||||||
if (r1 == 0) {
|
if (r1 == 0) {
|
||||||
nb_rbs_required_remaining[CC_id][i] =
|
nb_rbs_required_remaining[CC_id][UE_id] =
|
||||||
nb_rbs_required_remaining_1[CC_id][i];
|
nb_rbs_required_remaining_1[CC_id][UE_id];
|
||||||
} else { // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round
|
} else { // rb required based only on the buffer - rb allocated in the 1st round + extra reaming rb form the 1st round
|
||||||
nb_rbs_required_remaining[CC_id][i] =
|
nb_rbs_required_remaining[CC_id][UE_id] =
|
||||||
nb_rbs_required[CC_id][i] -
|
nb_rbs_required[CC_id][UE_id] -
|
||||||
nb_rbs_required_remaining_1[CC_id][i] +
|
nb_rbs_required_remaining_1[CC_id][UE_id] +
|
||||||
nb_rbs_required_remaining[CC_id][i];
|
nb_rbs_required_remaining[CC_id][UE_id];
|
||||||
if (nb_rbs_required_remaining[CC_id][i] < 0)
|
if (nb_rbs_required_remaining[CC_id][UE_id] < 0)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nb_rbs_required[CC_id][i] > 0)
|
if (nb_rbs_required[CC_id][UE_id] > 0)
|
||||||
LOG_D(MAC,
|
LOG_D(MAC,
|
||||||
"round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n",
|
"round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n",
|
||||||
r1, CC_id, i,
|
r1, CC_id, UE_id,
|
||||||
nb_rbs_required_remaining[CC_id][i],
|
nb_rbs_required_remaining[CC_id][UE_id],
|
||||||
nb_rbs_required_remaining_1[CC_id][i],
|
nb_rbs_required_remaining_1[CC_id][UE_id],
|
||||||
nb_rbs_required[CC_id][i],
|
nb_rbs_required[CC_id][UE_id],
|
||||||
UE_list->UE_sched_ctrl[i].
|
UE_list->UE_sched_ctrl[UE_id].pre_nb_available_rbs[CC_id],
|
||||||
pre_nb_available_rbs[CC_id], N_RBG[CC_id],
|
N_RBG[CC_id],
|
||||||
min_rb_unit[CC_id]);
|
min_rb_unit[CC_id]);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||||
for (i = UE_list->head; i >= 0; i = UE_list->next[i]) {
|
|
||||||
UE_id = i;
|
|
||||||
|
|
||||||
for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) {
|
for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) {
|
||||||
|
|
||||||
|
CC_id = UE_list->ordered_CCids[ii][UE_id];
|
||||||
// if there are UEs with traffic
|
// if there are UEs with traffic
|
||||||
if (total_ue_count[CC_id] > 0) {
|
if (total_ue_count[CC_id] > 0) {
|
||||||
CC_id = UE_list->ordered_CCids[ii][UE_id];
|
// ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||||
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
// round = ue_sched_ctl->round[CC_id][harq_pid];
|
||||||
round = ue_sched_ctl->round[CC_id][harq_pid];
|
|
||||||
|
|
||||||
rnti = UE_RNTI(Mod_id, UE_id);
|
rnti = UE_RNTI(Mod_id, UE_id);
|
||||||
|
|
||||||
@@ -860,7 +796,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
|
|||||||
continue;
|
continue;
|
||||||
if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
|
if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
|
||||||
continue;
|
continue;
|
||||||
if (!ue_slice_membership(i, slice_id))
|
if (!ue_slice_membership(UE_id, slice_id))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
transmission_mode = get_tmode(Mod_id, CC_id, UE_id);
|
transmission_mode = get_tmode(Mod_id, CC_id, UE_id);
|
||||||
@@ -888,8 +824,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
|
|||||||
MIMO_mode_indicator);
|
MIMO_mode_indicator);
|
||||||
|
|
||||||
#ifdef TM5
|
#ifdef TM5
|
||||||
|
// data chanel TM5: to be revisited
|
||||||
// data chanel TM5: to be revisted
|
|
||||||
if ((round == 0) &&
|
if ((round == 0) &&
|
||||||
(transmission_mode == 5) &&
|
(transmission_mode == 5) &&
|
||||||
(ue_sched_ctl->dl_pow_off[CC_id] != 1)) {
|
(ue_sched_ctl->dl_pow_off[CC_id] != 1)) {
|
||||||
@@ -908,7 +843,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
|
|||||||
&& (nb_rbs_required_remaining[CC_id][UE_id]
|
&& (nb_rbs_required_remaining[CC_id][UE_id]
|
||||||
> 0)) {
|
> 0)) {
|
||||||
|
|
||||||
for (ii = UE_list->next[i + 1]; ii >= 0;
|
for (ii = UE_list->next[UE_id + 1]; ii >= 0;
|
||||||
ii = UE_list->next[ii]) {
|
ii = UE_list->next[ii]) {
|
||||||
|
|
||||||
UE_id2 = ii;
|
UE_id2 = ii;
|
||||||
@@ -1051,12 +986,95 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} // total_ue_count
|
} // total_ue_count
|
||||||
}
|
} // CC
|
||||||
}
|
} // UE
|
||||||
} // end of for for r1 and r2
|
} // end of for for r1 and r2
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done
|
||||||
|
void
|
||||||
|
dlsch_scheduler_pre_processor(module_id_t Mod_id,
|
||||||
|
slice_id_t slice_id,
|
||||||
|
frame_t frameP,
|
||||||
|
sub_frame_t subframeP,
|
||||||
|
int N_RBG[MAX_NUM_CCs],
|
||||||
|
int *mbsfn_flag) {
|
||||||
|
|
||||||
|
int UE_id;
|
||||||
|
uint8_t CC_id;
|
||||||
|
uint16_t i, j;
|
||||||
|
|
||||||
|
uint8_t rballoc_sub[MAX_NUM_CCs][N_RBG_MAX];
|
||||||
|
uint8_t MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]; // If TM5 is revisited, we can move this inside accounting
|
||||||
|
|
||||||
|
int min_rb_unit[MAX_NUM_CCs];
|
||||||
|
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
|
||||||
|
|
||||||
|
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
|
||||||
|
UE_sched_ctrl *ue_sched_ctl;
|
||||||
|
// int rrc_status = RRC_IDLE;
|
||||||
|
|
||||||
#ifdef TM5
|
#ifdef TM5
|
||||||
|
int harq_pid1 = 0;
|
||||||
|
int round1 = 0, round2 = 0;
|
||||||
|
int UE_id2;
|
||||||
|
uint16_t i1, i2, i3;
|
||||||
|
rnti_t rnti1, rnti2;
|
||||||
|
LTE_eNB_UE_stats *eNB_UE_stats1 = NULL;
|
||||||
|
LTE_eNB_UE_stats *eNB_UE_stats2 = NULL;
|
||||||
|
UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||||
|
|
||||||
|
if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here
|
||||||
|
continue;
|
||||||
|
|
||||||
|
min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id);
|
||||||
|
|
||||||
|
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; ++UE_id) {
|
||||||
|
if (UE_list->active[UE_id] != TRUE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!ue_slice_membership(UE_id, slice_id))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Initialize scheduling information for all active UEs
|
||||||
|
dlsch_scheduler_pre_processor_reset(Mod_id,
|
||||||
|
UE_id,
|
||||||
|
CC_id,
|
||||||
|
frameP,
|
||||||
|
subframeP,
|
||||||
|
N_RBG[CC_id],
|
||||||
|
nb_rbs_required,
|
||||||
|
rballoc_sub,
|
||||||
|
MIMO_mode_indicator);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the DLSCH buffer for each logical channel
|
||||||
|
store_dlsch_buffer(Mod_id, slice_id, frameP, subframeP);
|
||||||
|
|
||||||
|
// Calculate the number of RBs required by each UE on the basis of logical channel's buffer
|
||||||
|
assign_rbs_required(Mod_id, slice_id, frameP, subframeP, nb_rbs_required, min_rb_unit);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
dlsch_scheduler_pre_processor_accounting(Mod_id,
|
||||||
|
slice_id,
|
||||||
|
frameP,
|
||||||
|
subframeP,
|
||||||
|
N_RBG,
|
||||||
|
min_rb_unit,
|
||||||
|
rballoc_sub,
|
||||||
|
MIMO_mode_indicator,
|
||||||
|
nb_rbs_required);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TM5
|
||||||
// This has to be revisited!!!!
|
// This has to be revisited!!!!
|
||||||
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||||
i1 = 0;
|
i1 = 0;
|
||||||
@@ -1096,37 +1114,28 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
|
|||||||
1;
|
1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = UE_list->head; i >= 0; i = UE_list->next[i]) {
|
for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||||
UE_id = i;
|
|
||||||
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
|
||||||
|
|
||||||
for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) {
|
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||||
CC_id = UE_list->ordered_CCids[ii][UE_id];
|
for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) {
|
||||||
|
CC_id = UE_list->ordered_CCids[i][UE_id];
|
||||||
//PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id];
|
//PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id];
|
||||||
|
|
||||||
if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) {
|
if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) {
|
||||||
LOG_D(MAC,
|
LOG_D(MAC, "******************DL Scheduling Information for UE%d ************************\n", UE_id);
|
||||||
"******************DL Scheduling Information for UE%d ************************\n",
|
LOG_D(MAC, "dl power offset UE%d = %d \n", UE_id, ue_sched_ctl->dl_pow_off[CC_id]);
|
||||||
UE_id);
|
LOG_D(MAC, "***********RB Alloc for every subband for UE%d ***********\n", UE_id);
|
||||||
LOG_D(MAC, "dl power offset UE%d = %d \n", UE_id,
|
|
||||||
ue_sched_ctl->dl_pow_off[CC_id]);
|
|
||||||
LOG_D(MAC,
|
|
||||||
"***********RB Alloc for every subband for UE%d ***********\n",
|
|
||||||
UE_id);
|
|
||||||
|
|
||||||
for (j = 0; j < N_RBG[CC_id]; j++) {
|
for (j = 0; j < N_RBG[CC_id]; j++) {
|
||||||
//PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[i] = rballoc_sub_UE[CC_id][UE_id][i];
|
//PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[UE_id] = rballoc_sub_UE[CC_id][UE_id][UE_id];
|
||||||
LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n",
|
LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n", UE_id, j, ue_sched_ctl->rballoc_sub_UE[CC_id][j]);
|
||||||
UE_id, j,
|
|
||||||
ue_sched_ctl->rballoc_sub_UE[CC_id][j]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id];
|
//PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id];
|
||||||
LOG_D(MAC, "[eNB %d][SLICE %d]Total RBs allocated for UE%d = %d\n", Mod_id, slice_id, UE_id,
|
LOG_D(MAC, "[eNB %d][SLICE %d]Total RBs allocated for UE%d = %d\n",
|
||||||
ue_sched_ctl->pre_nb_available_rbs[CC_id]);
|
Mod_id, slice_id, UE_id, ue_sched_ctl->pre_nb_available_rbs[CC_id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1143,11 +1152,6 @@ dlsch_scheduler_pre_processor_reset(int module_idP,
|
|||||||
int N_RBG,
|
int N_RBG,
|
||||||
uint16_t nb_rbs_required[MAX_NUM_CCs]
|
uint16_t nb_rbs_required[MAX_NUM_CCs]
|
||||||
[NUMBER_OF_UE_MAX],
|
[NUMBER_OF_UE_MAX],
|
||||||
uint16_t
|
|
||||||
nb_rbs_required_remaining
|
|
||||||
[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
|
|
||||||
unsigned char total_ue_count[MAX_NUM_CCs],
|
|
||||||
unsigned char total_rbs_used[MAX_NUM_CCs],
|
|
||||||
unsigned char
|
unsigned char
|
||||||
rballoc_sub[MAX_NUM_CCs]
|
rballoc_sub[MAX_NUM_CCs]
|
||||||
[N_RBG_MAX],
|
[N_RBG_MAX],
|
||||||
@@ -1162,8 +1166,7 @@ dlsch_scheduler_pre_processor_reset(int module_idP,
|
|||||||
|
|
||||||
uint8_t *vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map;
|
uint8_t *vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map;
|
||||||
int N_RB_DL =
|
int N_RB_DL =
|
||||||
to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->
|
to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth);
|
||||||
message.dl_Bandwidth);
|
|
||||||
int RBGsize = N_RB_DL / N_RBG, RBGsize_last;
|
int RBGsize = N_RB_DL / N_RBG, RBGsize_last;
|
||||||
#ifdef SF0_LIMIT
|
#ifdef SF0_LIMIT
|
||||||
int sf0_upper = -1, sf0_lower = -1;
|
int sf0_upper = -1, sf0_lower = -1;
|
||||||
@@ -1237,9 +1240,7 @@ dlsch_scheduler_pre_processor_reset(int module_idP,
|
|||||||
nb_rbs_required[CC_id][UE_id] = 0;
|
nb_rbs_required[CC_id][UE_id] = 0;
|
||||||
ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0;
|
ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0;
|
||||||
ue_sched_ctl->dl_pow_off[CC_id] = 2;
|
ue_sched_ctl->dl_pow_off[CC_id] = 2;
|
||||||
nb_rbs_required_remaining[CC_id][UE_id] = 0;
|
|
||||||
total_ue_count[CC_id]=0;
|
|
||||||
total_rbs_used[CC_id]=0;
|
|
||||||
switch (N_RB_DL) {
|
switch (N_RB_DL) {
|
||||||
case 6:
|
case 6:
|
||||||
RBGsize = 1;
|
RBGsize = 1;
|
||||||
@@ -1295,12 +1296,14 @@ dlsch_scheduler_pre_processor_reset(int module_idP,
|
|||||||
AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL);
|
AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Initialize Subbands according to VRB map
|
// Initialize Subbands according to VRB map
|
||||||
for (i = 0; i < N_RBG; i++) {
|
for (i = 0; i < N_RBG; i++) {
|
||||||
int rb_size = i == N_RBG - 1 ? RBGsize_last : RBGsize;
|
int rb_size = i == N_RBG - 1 ? RBGsize_last : RBGsize;
|
||||||
|
|
||||||
ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0;
|
ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0;
|
||||||
rballoc_sub[CC_id][i] = 0;
|
rballoc_sub[CC_id][i] = 0;
|
||||||
|
|
||||||
#ifdef SF0_LIMIT
|
#ifdef SF0_LIMIT
|
||||||
// for avoiding 6+ PRBs around DC in subframe 0 (avoid excessive errors)
|
// for avoiding 6+ PRBs around DC in subframe 0 (avoid excessive errors)
|
||||||
/* TODO: make it proper - allocate those RBs, do not "protect" them, but
|
/* TODO: make it proper - allocate those RBs, do not "protect" them, but
|
||||||
@@ -1310,6 +1313,7 @@ dlsch_scheduler_pre_processor_reset(int module_idP,
|
|||||||
if (subframeP == 0 && i >= sf0_lower && i <= sf0_upper)
|
if (subframeP == 0 && i >= sf0_lower && i <= sf0_upper)
|
||||||
rballoc_sub[CC_id][i] = 1;
|
rballoc_sub[CC_id][i] = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// for SI-RNTI,RA-RNTI and P-RNTI allocations
|
// for SI-RNTI,RA-RNTI and P-RNTI allocations
|
||||||
for (j = 0; j < rb_size; j++) {
|
for (j = 0; j < rb_size; j++) {
|
||||||
if (vrb_map[j + (i * RBGsize)] != 0) {
|
if (vrb_map[j + (i * RBGsize)] != 0) {
|
||||||
|
|||||||
@@ -209,11 +209,6 @@ void dlsch_scheduler_pre_processor_reset(int module_idP, int UE_id,
|
|||||||
uint16_t
|
uint16_t
|
||||||
nb_rbs_required[MAX_NUM_CCs]
|
nb_rbs_required[MAX_NUM_CCs]
|
||||||
[NUMBER_OF_UE_MAX],
|
[NUMBER_OF_UE_MAX],
|
||||||
uint16_t
|
|
||||||
nb_rbs_required_remaining
|
|
||||||
[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
|
|
||||||
unsigned char total_ue_count[MAX_NUM_CCs],
|
|
||||||
unsigned char total_rbs_used[MAX_NUM_CCs],
|
|
||||||
unsigned char
|
unsigned char
|
||||||
rballoc_sub[MAX_NUM_CCs]
|
rballoc_sub[MAX_NUM_CCs]
|
||||||
[N_RBG_MAX],
|
[N_RBG_MAX],
|
||||||
|
|||||||
Reference in New Issue
Block a user