Commit fe25fa5d authored by Robert Schmidt's avatar Robert Schmidt

Generalize RB size search into nr_find_nb_rb(), use everywhere

The TDA change used a binary search (worst case O(log n)) for finding
the right amount of RBs, whereas everywhere else we used a linear search
(O(n)). We generalize the binary search into a function nr_find_nb_rb()
and use it for DL and UL allocation.
parent 9f4f68a1
......@@ -467,46 +467,24 @@ bool allocate_dl_retransmission(module_id_t module_id,
NR_pdsch_semi_static_t temp_ps;
nr_set_pdsch_semi_static(
scc, UE_info->secondaryCellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, &temp_ps);
/* perform binary search to find whether we can have a TBS sufficiently
* large within rbSize RBs */
int hi = rbSize;
int lo = 1;
for (int p = (hi + lo) / 2; lo + 1 < hi; p = (hi + lo) / 2) {
const uint32_t TBS = nr_compute_tbs(retInfo->Qm,
retInfo->R,
p,
temp_ps.nrOfSymbols,
temp_ps.N_PRB_DMRS * temp_ps.N_DMRS_SLOT,
0 /* N_PRB_oh, 0 for initialBWP */,
0 /* tb_scaling */,
1 /* nrOfLayers */)
>> 3;
if (retInfo->tb_size == TBS) {
hi = p;
break;
} else if (retInfo->tb_size < TBS) {
hi = p;
} else {
lo = p;
}
}
const uint32_t TBS = nr_compute_tbs(retInfo->Qm,
retInfo->R,
hi,
temp_ps.nrOfSymbols,
temp_ps.N_PRB_DMRS * temp_ps.N_DMRS_SLOT,
0 /* N_PRB_oh, 0 for initialBWP */,
0 /* tb_scaling */,
1 /* nrOfLayers */)
>> 3;
if (TBS != retInfo->tb_size) {
LOG_D(MAC, "new TBsize %d of new TDA does not match old TBS %d\n", TBS, retInfo->tb_size);
uint32_t new_tbs;
uint16_t new_rbSize;
bool success = nr_find_nb_rb(retInfo->Qm,
retInfo->R,
temp_ps.nrOfSymbols,
temp_ps.N_PRB_DMRS * temp_ps.N_DMRS_SLOT,
retInfo->tb_size,
rbSize,
&new_tbs,
&new_rbSize);
if (!success || new_tbs != retInfo->tb_size) {
LOG_D(MAC, "%s(): new TBsize %d of new TDA does not match old TBS %d\n", __func__, new_tbs, retInfo->tb_size);
return false; /* the maximum TBsize we might have is smaller than what we need */
}
/* we can allocate it. Overwrite the time_domain_allocation, the number
* of RBs, and the new TB size. The rest is done below */
retInfo->tb_size = TBS;
retInfo->rbSize = hi;
retInfo->tb_size = new_tbs;
retInfo->rbSize = new_rbSize;
retInfo->time_domain_allocation = tda;
sched_ctrl->pdsch_semi_static = temp_ps;
}
......@@ -663,6 +641,9 @@ void pf_dl(module_id_t module_id,
// Freq-demain allocation
while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++;
uint16_t max_rbSize = 1;
while (rbStart + max_rbSize < bwpSize && rballoc_mask[rbStart + max_rbSize])
max_rbSize++;
/* MCS has been set above */
const uint8_t num_dmrs_cdm_grps_no_data = 1;
......@@ -675,22 +656,18 @@ void pf_dl(module_id_t module_id,
sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
int rbSize = 0;
uint32_t TBS = 0;
uint16_t rbSize;
const int oh = 2 + (sched_ctrl->num_total_bytes >= 256)
+ 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024);
do {
rbSize++;
TBS = nr_compute_tbs(sched_pdsch->Qm,
sched_pdsch->R,
rbSize,
ps->nrOfSymbols,
ps->N_PRB_DMRS * ps->N_DMRS_SLOT,
0 /* N_PRB_oh, 0 for initialBWP */,
0 /* tb_scaling */,
1 /* nrOfLayers */)
>> 3;
} while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart + rbSize] && TBS < sched_ctrl->num_total_bytes + oh);
nr_find_nb_rb(sched_pdsch->Qm,
sched_pdsch->R,
ps->nrOfSymbols,
ps->N_PRB_DMRS * ps->N_DMRS_SLOT,
sched_ctrl->num_total_bytes + oh,
max_rbSize,
&TBS,
&rbSize);
sched_pdsch->rbSize = rbSize;
sched_pdsch->rbStart = rbStart;
sched_pdsch->tb_size = TBS;
......
......@@ -210,6 +210,52 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
}
bool nr_find_nb_rb(uint16_t Qm,
uint16_t R,
uint16_t nb_symb_sch,
uint16_t nb_dmrs_prb,
uint32_t bytes,
uint16_t nb_rb_max,
uint32_t *tbs,
uint16_t *nb_rb)
{
/* is the maximum (not even) enough? */
*nb_rb = nb_rb_max;
*tbs = nr_compute_tbs(Qm, R, *nb_rb, nb_symb_sch, nb_dmrs_prb, 0, 0, 1) >> 3;
/* check whether it does not fit, or whether it exactly fits. Some algorithms
* might depend on the return value! */
if (bytes > *tbs)
return false;
if (bytes == *tbs)
return true;
/* is the minimum enough? */
*nb_rb = 1;
*tbs = nr_compute_tbs(Qm, R, *nb_rb, nb_symb_sch, nb_dmrs_prb, 0, 0, 1) >> 3;
if (bytes <= *tbs)
return true;
/* perform binary search to allocate all bytes within a TBS up to nb_rb_max
* RBs */
int hi = nb_rb_max;
int lo = 1;
for (int p = (hi + lo) / 2; lo + 1 < hi; p = (hi + lo) / 2) {
const uint32_t TBS = nr_compute_tbs(Qm, R, p, nb_symb_sch, nb_dmrs_prb, 0, 0, 1) >> 3;
if (bytes == TBS) {
hi = p;
break;
} else if (bytes < TBS) {
hi = p;
} else {
lo = p;
}
}
*nb_rb = hi;
*tbs = nr_compute_tbs(Qm, R, *nb_rb, nb_symb_sch, nb_dmrs_prb, 0, 0, 1) >> 3;
/* return whether we could allocate all bytes and stay below nb_rb_max */
return *tbs >= bytes && *nb_rb <= nb_rb_max;
}
void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
const NR_CellGroupConfig_t *secondaryCellGroup,
const NR_BWP_Downlink_t *bwp,
......
......@@ -779,29 +779,24 @@ void pf_ul(module_id_t module_id,
while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++;
sched_pusch->rbStart = rbStart;
if (rbStart + min_rb >= bwpSize) {
LOG_D(MAC, "cannot allocate UL data for UE %d/RNTI %04x: no resources\n",
UE_id, UE_info->rnti[UE_id]);
continue;
}
uint16_t max_rbSize = 1;
while (rbStart + max_rbSize < bwpSize && rballoc_mask[rbStart + max_rbSize])
max_rbSize++;
/* Calculate the current scheduling bytes */
/* Calculate the current scheduling bytes and the necessary RBs */
const int B = cmax(sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes, 0);
uint16_t rbSize = min_rb - 1;
do {
rbSize++;
sched_pusch->rbSize = rbSize;
sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm,
sched_pusch->R,
sched_pusch->rbSize,
ps->nrOfSymbols,
ps->N_PRB_DMRS * ps->num_dmrs_symb,
0, // nb_rb_oh
0,
1 /* NrOfLayers */)
>> 3;
} while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart+rbSize] &&
sched_pusch->tb_size < B);
uint16_t rbSize = 0;
uint32_t TBS = 0;
nr_find_nb_rb(sched_pusch->Qm,
sched_pusch->R,
ps->nrOfSymbols,
ps->N_PRB_DMRS * ps->num_dmrs_symb,
B,
max_rbSize,
&TBS,
&rbSize);
sched_pusch->rbSize = rbSize;
sched_pusch->tb_size = TBS;
LOG_D(MAC,"rbSize %d, TBS %d, est buf %d, sched_ul %d, B %d\n",
rbSize, sched_pusch->tb_size, sched_ctrl->estimated_ul_buffer, sched_ctrl->sched_ul_bytes, B);
......
......@@ -392,4 +392,14 @@ void find_SSB_and_RO_available(module_id_t module_idP);
void calculate_preferred_dl_tda(module_id_t module_id, NR_CellGroupConfig_t *secondaryCellGroup, int bwp_id);
bool find_free_CCE(module_id_t module_id, sub_frame_t slot, int UE_id);
bool nr_find_nb_rb(uint16_t Qm,
uint16_t R,
uint16_t nb_symb_sch,
uint16_t nb_dmrs_prb,
uint32_t bytes,
uint16_t nb_rb_max,
uint32_t *tbs,
uint16_t *nb_rb);
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
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