Commit 3a3ac5d1 authored by francescomani's avatar francescomani

improvements in Bj computation and implementing a timer to compute time...

improvements in Bj computation and implementing a timer to compute time elapsed since last Bj update
parent e1434b43
......@@ -914,6 +914,11 @@ bool nr_timer_expired(NR_timer_t timer)
return (timer.counter >= timer.target);
}
uint32_t nr_timer_elapsed_time(NR_timer_t timer)
{
return timer.counter;
}
void nr_timer_setup(NR_timer_t *timer, const uint32_t target, const uint32_t step)
{
timer->target = target;
......
......@@ -158,6 +158,13 @@ bool nr_timer_expired(NR_timer_t timer);
* @return Indication if the timer is active or not
*/
bool is_nr_timer_active(NR_timer_t timer);
/**
* @brief To return how much time has passed since start of timer
* @param timer Timer to be checked
* @return Time passed since start of timer
*/
uint32_t nr_timer_elapsed_time(NR_timer_t timer);
extern const nr_bandentry_t nr_bandtable[];
......
......@@ -655,10 +655,86 @@ static int nr_get_ms_bucketsizeduration(long bucketsizeduration)
}
}
static uint32_t nr_get_pbr(long prioritizedbitrate) // returns Bps
{
uint32_t pbr = 0;
switch (prioritizedbitrate) {
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps0:
pbr = 0;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8:
pbr = 8;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps16:
pbr = 16;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps32:
pbr = 32;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps64:
pbr = 64;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps128:
pbr = 128;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps256:
pbr = 256;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps512:
pbr = 512;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps1024:
pbr = 1024;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps2048:
pbr = 2048;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps4096:
pbr = 4096;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8192:
pbr = 8192;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps16384:
pbr = 16384;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps32768:
pbr = 32768;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps65536:
pbr = 65536;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity:
pbr = UINT32_MAX;
break;
default:
AssertFatal(false, "The proritized bit rate value is not one of the enum values\n");
}
uint32_t pbr_bytes =
(prioritizedbitrate < NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity) ? pbr * 1000 : pbr;
return pbr_bytes;
}
static uint32_t get_lc_bucket_size(long prioritisedBitRate, long bucketSizeDuration)
{
int pbr = nr_get_pbr(prioritisedBitRate);
// in infinite pbr, the bucket is saturated by pbr
// if infinite pbr, the bucket is saturated by pbr
int bsd = 0;
if (prioritisedBitRate == NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity)
bsd = 1;
......@@ -673,8 +749,8 @@ static void set_default_logicalchannelconfig(nr_lcordered_info_t *lc_info, NR_SR
{
lc_info->lcid = srb_id;
lc_info->priority = srb_id == 2 ? 3 : 1;
lc_info->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
lc_info->bucket_size = get_lc_bucket_size(lc_info->prioritisedBitRate, 0);
lc_info->pbr = UINT32_MAX;
lc_info->bucket_size = UINT32_MAX;
}
static void nr_configure_lc_config(NR_UE_MAC_INST_t *mac,
......@@ -691,10 +767,14 @@ static void nr_configure_lc_config(NR_UE_MAC_INST_t *mac,
AssertFatal(mac_lc_config->ul_SpecificParameters, "UL parameters shouldn't be NULL for DRBs\n");
struct NR_LogicalChannelConfig__ul_SpecificParameters *ul_parm = mac_lc_config->ul_SpecificParameters;
lc_info->priority = ul_parm->priority;
lc_info->prioritisedBitRate = ul_parm->prioritisedBitRate;
lc_info->pbr = nr_get_pbr(ul_parm->prioritisedBitRate);
// TODO Verify setting to 0 is ok, 331 just says need R (release if NULL)
mac->scheduling_info.lc_sched_info[lc_info->lcid - 1].LCGID = ul_parm->logicalChannelGroup ? *ul_parm->logicalChannelGroup : 0;
lc_info->bucket_size = get_lc_bucket_size(ul_parm->prioritisedBitRate, ul_parm->bucketSizeDuration);
// setup and start Bj timer for this LC
NR_timer_t *bjt = &mac->scheduling_info.lc_sched_info[lc_info->lcid - 1].Bj_timer;
nr_timer_setup(bjt, UINT32_MAX, 1); // this timer never expires in principle, counter incremented by number of slots
nr_timer_start(bjt);
}
static void configure_logicalChannelBearer(NR_UE_MAC_INST_t *mac,
......
......@@ -186,6 +186,7 @@ typedef struct {
long LCGID;
// Bj bucket usage per lcid
int32_t Bj;
NR_timer_t Bj_timer;
} NR_LC_SCHEDULING_INFO;
typedef struct {
......@@ -435,7 +436,7 @@ typedef struct nr_lcordered_info_s {
// logical channels ids ordered as per priority
NR_LogicalChannelIdentity_t lcid;
long priority;
long prioritisedBitRate;
uint32_t pbr; // in B/s (UINT32_MAX = infinite)
// Bucket size per lcid
uint32_t bucket_size;
} nr_lcordered_info_t;
......
......@@ -240,13 +240,6 @@ bool nr_update_bsr(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP, uint8_t
uint8_t nr_locate_BsrIndexByBufferSize(const uint32_t *table, int size,
int value);
/*! \fn int nr_get_pbr(long prioritizedbitrate)
\brief get the rate in kbps from the rate configured by the higher layer
\param[in] prioritizedbitrate
\return the rate in kbps
*/
uint32_t nr_get_pbr(long prioritizedbitrate);
/*! \fn int nr_get_sf_periodicBSRTimer(uint8_t periodicBSR_Timer)
\brief get the number of subframe from the periodic BSR timer configured by the higher layers
\param[in] periodicBSR_Timer timer for periodic BSR
......
......@@ -93,6 +93,10 @@ fapi_nr_ul_config_request_pdu_t *lockGet_ul_config(NR_UE_MAC_INST_t *mac, frame_
void update_mac_timers(NR_UE_MAC_INST_t *mac)
{
nr_timer_tick(&mac->ra.contention_resolution_timer);
for (int i = 0; i < NR_MAX_NUM_LCID; i++)
AssertFatal(!nr_timer_tick(&mac->scheduling_info.lc_sched_info[i].Bj_timer),
"Bj timer for LCID %d expired! That should never happen\n",
i);
}
void remove_ul_config_last_item(fapi_nr_ul_config_request_pdu_t *pdu)
......@@ -1119,14 +1123,21 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info)
measure Bj
increment the value of Bj by product PBR * T
*/
int T = 1; // time elapsed since Bj was last incremented
int32_t bj = mac->scheduling_info.lc_sched_info[lcid - 1].Bj;
bj += nr_get_pbr(lc_info->prioritisedBitRate) * T;
if (lc_info->prioritisedBitRate == NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity)
bj = nr_get_pbr(lc_info->prioritisedBitRate);
NR_LC_SCHEDULING_INFO *sched_info = &mac->scheduling_info.lc_sched_info[lcid - 1];
int32_t bj = sched_info->Bj;
if (lc_info->pbr < UINT32_MAX) {
uint32_t slots_elapsed = nr_timer_elapsed_time(sched_info->Bj_timer); // slots elapsed since Bj was last incremented
// it is safe to divide by 1k since pbr in lc_info is computed multiplying by 1000 the RRC value to convert kB/s to B/s
uint32_t pbr_ms = lc_info->pbr / 1000;
bj += ((pbr_ms * slots_elapsed) >> mac->current_UL_BWP->scs); // each slot length is 1/scs ms
}
else
bj = UINT32_MAX;
// bj > max bucket size, set bj to max bucket size, as in ts38.321 5.4.3.1 Logical Channel Prioritization
mac->scheduling_info.lc_sched_info[lcid - 1].Bj = min(bj, bucketSize_max);
sched_info->Bj = min(bj, bucketSize_max);
// reset bj timer
nr_timer_start(&sched_info->Bj_timer);
}
// Call BSR procedure as described in Section 5.4.5 in 38.321
......@@ -2929,15 +2940,16 @@ long get_num_bytes_to_reqlc(NR_UE_MAC_INST_t *mac,
long *target)
{
/* Calculates the number of bytes the logical channel should request from the correcponding RLC buffer*/
long found_pbr = -1;
bool found_pbr = false;
uint32_t pbr = 0;
for (int i = 0; i < mac->lc_ordered_list.count; i++) {
if (mac->lc_ordered_list.array[i]->lcid == lc_num) {
found_pbr = mac->lc_ordered_list.array[i]->prioritisedBitRate;
pbr = mac->lc_ordered_list.array[i]->pbr;
found_pbr = true;
break;
}
}
AssertFatal(found_pbr >= 0, "Couldn't find LC config for ID %d\n", lc_num);
uint32_t pbr = nr_get_pbr(found_pbr);
AssertFatal(found_pbr, "Couldn't find LC config for ID %d\n", lc_num);
int32_t lcid_remain_buffer = mac->scheduling_info.lc_sched_info[lc_num - 1].LCID_buffer_remain;
*target = (same_priority_count > 1) ? min(buflen_remain_ep, pbr) : pbr;
......@@ -3055,7 +3067,7 @@ static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac,
// currently the Bj is drecremented by size of MAC SDus everytime it is served to logical channel, so by this approach there
// will be more chance for lower priority logical channels to be served in the next TTI
// second approach can also be followed where Bj is decremented only in the first round but not in the subsequent rounds
sched_info->lc_sched_info[lcid - 1].Bj -= sdu_length; // TODO avoid Bj to go below 0
sched_info->lc_sched_info[lcid - 1].Bj -= sdu_length;
LOG_D(NR_MAC,
"decrement Bj of the lcid %d by size of sdu length = %d and new Bj for lcid %d is %d\n",
lcid,
......@@ -3185,8 +3197,8 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
bool lcids_data_status[NR_MAX_NUM_LCID] = {0};
memset(lcids_data_status, 1, NR_MAX_NUM_LCID);
uint32_t lcp_allocation_counter =
0; // in the first run all the lc are allocated as per bj and prioritized bit rate but in subsequent runs, no need to consider
// in the first run all the lc are allocated as per bj and prioritized bit rate but in subsequent runs, no need to consider
uint32_t lcp_allocation_counter = 0;
// bj and prioritized bit rate but just consider priority
uint16_t buflen_ep = 0; // this variable holds the length in bytes in mac pdu when multiple equal priority channels are present
// because as per standard(TS38.321), all equal priority channels should be served equally
......@@ -3351,80 +3363,3 @@ void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UL_TIME_ALIG
dl_config->number_pdus += 1;
ul_time_alignment->ta_apply = false;
}
uint32_t nr_get_pbr(long prioritizedbitrate)
{
int32_t pbr = -1;
switch (prioritizedbitrate) {
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps0:
pbr = 0;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8:
pbr = 8;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps16:
pbr = 16;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps32:
pbr = 32;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps64:
pbr = 64;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps128:
pbr = 128;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps256:
pbr = 256;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps512:
pbr = 512;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps1024:
pbr = 1024;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps2048:
pbr = 2048;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps4096:
pbr = 4096;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8192:
pbr = 8192;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps16384:
pbr = 16384;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps32768:
pbr = 32768;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps65536:
pbr = 65536;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity:
pbr = INT32_MAX;
break;
default:
pbr = -1;
}
AssertFatal(pbr >= 0, "The proritized bit rate value is not one of the enum values\n");
uint32_t pbr_bytes =
(prioritizedbitrate < NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity) ? pbr * 1000 : pbr;
return pbr_bytes;
}
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