mirror of https://github.com/pvnis/srsRAN_4G.git
sched: created class common to LTE and NR for ue buffer status management
parent
de06dbc684
commit
020bec025e
@ -0,0 +1,95 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2021 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* By using this file, you agree to the terms and conditions set
|
||||||
|
* forth in the LICENSE file which can be found at the top level of
|
||||||
|
* the distribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRSRAN_UE_BUFFER_MANAGER_H
|
||||||
|
#define SRSRAN_UE_BUFFER_MANAGER_H
|
||||||
|
|
||||||
|
#include "sched_config.h"
|
||||||
|
#include "srsran/common/common_lte.h"
|
||||||
|
#include "srsran/common/common_nr.h"
|
||||||
|
#include "srsran/srslog/srslog.h"
|
||||||
|
#include "srsran/support/srsran_assert.h"
|
||||||
|
|
||||||
|
namespace srsenb {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to handle UE DL+UL RLC and MAC buffers state
|
||||||
|
*/
|
||||||
|
template <bool isNR>
|
||||||
|
class ue_buffer_manager
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
const static uint32_t MAX_LC_ID = isNR ? srsran::MAX_NR_NOF_BEARERS : srsran::MAX_LTE_LCID;
|
||||||
|
const static uint32_t MAX_LCG_ID = isNR ? 7 : 3;
|
||||||
|
const static uint32_t MAX_SRB_LC_ID = isNR ? srsran::MAX_NR_SRB_ID : srsran::MAX_LTE_SRB_ID;
|
||||||
|
const static uint32_t MAX_NOF_LCIDS = MAX_LC_ID + 1;
|
||||||
|
const static uint32_t MAX_NOF_LCGS = MAX_LCG_ID + 1;
|
||||||
|
constexpr static uint32_t pbr_infinity = -1;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ue_buffer_manager(srslog::basic_logger& logger_) : logger(logger_) {}
|
||||||
|
|
||||||
|
// Bearer configuration
|
||||||
|
void config_lcid(uint32_t lcid, const mac_lc_ch_cfg_t& bearer_cfg);
|
||||||
|
|
||||||
|
// Buffer Status update
|
||||||
|
void ul_bsr(uint32_t lcg_id, uint32_t val);
|
||||||
|
void dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t retx_queue);
|
||||||
|
|
||||||
|
// Configuration getters
|
||||||
|
bool is_bearer_active(uint32_t lcid) const { return get_cfg(lcid).is_active(); }
|
||||||
|
bool is_bearer_ul(uint32_t lcid) const { return get_cfg(lcid).is_ul(); }
|
||||||
|
bool is_bearer_dl(uint32_t lcid) const { return get_cfg(lcid).is_dl(); }
|
||||||
|
const mac_lc_ch_cfg_t& get_cfg(uint32_t lcid) const
|
||||||
|
{
|
||||||
|
srsran_assert(is_lcid_valid(lcid), "Provided LCID=%d is above limit=%d", lcid, MAX_LC_ID);
|
||||||
|
return channels[lcid].cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// DL newtx buffer status for given LCID (no RLC overhead included)
|
||||||
|
int get_dl_tx(uint32_t lcid) const { return is_bearer_dl(lcid) ? channels[lcid].buf_tx : 0; }
|
||||||
|
|
||||||
|
/// DL retx buffer status for given LCID (no RLC overhead included)
|
||||||
|
int get_dl_retx(uint32_t lcid) const { return is_bearer_dl(lcid) ? channels[lcid].buf_retx : 0; }
|
||||||
|
|
||||||
|
/// Sum of DL RLC newtx and retx buffer status for given LCID (no RLC overhead included)
|
||||||
|
int get_dl_tx_total(uint32_t lcid) const { return get_dl_tx(lcid) + get_dl_retx(lcid); }
|
||||||
|
|
||||||
|
/// Sum of DL RLC newtx and retx buffer status for all LCIDS
|
||||||
|
int get_dl_tx_total() const;
|
||||||
|
|
||||||
|
// UL BSR methods
|
||||||
|
bool is_lcg_active(uint32_t lcg) const;
|
||||||
|
int get_bsr(uint32_t lcg) const;
|
||||||
|
const std::array<int, MAX_NOF_LCGS>& get_bsr_state() const { return lcg_bsr; }
|
||||||
|
|
||||||
|
static bool is_lcid_valid(uint32_t lcid) { return lcid <= MAX_LC_ID; }
|
||||||
|
static bool is_lcg_valid(uint32_t lcg) { return lcg <= MAX_LCG_ID; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
srslog::basic_logger& logger;
|
||||||
|
|
||||||
|
struct logical_channel {
|
||||||
|
mac_lc_ch_cfg_t cfg;
|
||||||
|
int buf_tx = 0;
|
||||||
|
int buf_retx = 0;
|
||||||
|
int Bj = 0;
|
||||||
|
int bucket_size = 0;
|
||||||
|
};
|
||||||
|
std::array<logical_channel, MAX_NOF_LCIDS> channels;
|
||||||
|
|
||||||
|
std::array<int, MAX_NOF_LCGS> lcg_bsr{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srsenb
|
||||||
|
|
||||||
|
#endif // SRSRAN_UE_BUFFER_MANAGER_H
|
@ -1,66 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* \section COPYRIGHT
|
|
||||||
*
|
|
||||||
* Copyright 2013-2021 Software Radio Systems Limited
|
|
||||||
*
|
|
||||||
* By using this file, you agree to the terms and conditions set
|
|
||||||
* forth in the LICENSE file which can be found at the top level of
|
|
||||||
* the distribution.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SRSRAN_SCHED_NR_UE_BUFFER_MANAGER_H
|
|
||||||
#define SRSRAN_SCHED_NR_UE_BUFFER_MANAGER_H
|
|
||||||
|
|
||||||
#include "srsenb/hdr/stack/mac/common/sched_config.h"
|
|
||||||
#include "srsran/srslog/srslog.h"
|
|
||||||
#include "srsran/support/srsran_assert.h"
|
|
||||||
|
|
||||||
namespace srsenb {
|
|
||||||
namespace sched_nr_impl {
|
|
||||||
|
|
||||||
class ue_buffer_manager
|
|
||||||
{
|
|
||||||
const static uint32_t MAX_LCG_ID = 7;
|
|
||||||
const static uint32_t MAX_LC_ID = 32;
|
|
||||||
const static uint32_t MAX_SRB_LC_ID = 3;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ue_buffer_manager(srslog::basic_logger& logger_);
|
|
||||||
|
|
||||||
// Configuration getters
|
|
||||||
bool is_channel_active(uint32_t lcid) const { return get_cfg(lcid).is_active(); }
|
|
||||||
bool is_bearer_ul(uint32_t lcid) const { return get_cfg(lcid).is_ul(); }
|
|
||||||
bool is_bearer_dl(uint32_t lcid) const { return get_cfg(lcid).is_dl(); }
|
|
||||||
const logical_channel_cfg_t& get_cfg(uint32_t lcid) const
|
|
||||||
{
|
|
||||||
srsran_assert(lcid < MAX_LC_ID, "Provided LCID=%d is above limit=%d", lcid, MAX_LC_ID);
|
|
||||||
return channels[lcid].cfg;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Buffer Status update
|
|
||||||
void ul_bsr(uint32_t lcg_id, uint32_t val);
|
|
||||||
void dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t retx_queue);
|
|
||||||
|
|
||||||
// UL BSR methods
|
|
||||||
bool is_lcg_active(uint32_t lcg) const;
|
|
||||||
int get_bsr(uint32_t lcg) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
srslog::basic_logger& logger;
|
|
||||||
|
|
||||||
struct logical_channel {
|
|
||||||
logical_channel_cfg_t cfg;
|
|
||||||
int buf_tx = 0;
|
|
||||||
int buf_retx = 0;
|
|
||||||
};
|
|
||||||
std::array<logical_channel, MAX_LC_ID> channels;
|
|
||||||
|
|
||||||
std::array<int, MAX_LCG_ID> lcg_bsr{0};
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace sched_nr_impl
|
|
||||||
} // namespace srsenb
|
|
||||||
|
|
||||||
#endif // SRSRAN_SCHED_NR_UE_BUFFER_MANAGER_H
|
|
@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
# Copyright 2013-2021 Software Radio Systems Limited
|
||||||
|
#
|
||||||
|
# By using this file, you agree to the terms and conditions set
|
||||||
|
# forth in the LICENSE file which can be found at the top level of
|
||||||
|
# the distribution.
|
||||||
|
#
|
||||||
|
|
||||||
|
set(SOURCES ue_buffer_manager.cc)
|
||||||
|
add_library(srsenb_mac_common STATIC ${SOURCES})
|
@ -0,0 +1,116 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2021 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* By using this file, you agree to the terms and conditions set
|
||||||
|
* forth in the LICENSE file which can be found at the top level of
|
||||||
|
* the distribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "srsenb/hdr/stack/mac/common/ue_buffer_manager.h"
|
||||||
|
#include "srsran/common/string_helpers.h"
|
||||||
|
#include "srsran/srslog/bundled/fmt/format.h"
|
||||||
|
#include "srsran/srslog/bundled/fmt/ranges.h"
|
||||||
|
|
||||||
|
namespace srsenb {
|
||||||
|
|
||||||
|
template <bool isNR>
|
||||||
|
void ue_buffer_manager<isNR>::config_lcid(uint32_t lcid, const mac_lc_ch_cfg_t& bearer_cfg)
|
||||||
|
{
|
||||||
|
if (not is_lcid_valid(lcid)) {
|
||||||
|
logger.warning("Configuring bearer with invalid logical channel id=%d", lcid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (not is_lcg_valid(bearer_cfg.group)) {
|
||||||
|
logger.warning("Configuring bearer with invalid logical channel group id=%d", bearer_cfg.group);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update bearer config
|
||||||
|
if (bearer_cfg != channels[lcid].cfg) {
|
||||||
|
channels[lcid].cfg = bearer_cfg;
|
||||||
|
if (channels[lcid].cfg.pbr == pbr_infinity) {
|
||||||
|
channels[lcid].bucket_size = std::numeric_limits<int>::max();
|
||||||
|
channels[lcid].Bj = std::numeric_limits<int>::max();
|
||||||
|
} else {
|
||||||
|
channels[lcid].bucket_size = channels[lcid].cfg.bsd * channels[lcid].cfg.pbr;
|
||||||
|
channels[lcid].Bj = 0;
|
||||||
|
}
|
||||||
|
logger.info("SCHED: bearer configured: lcid=%d, mode=%s, prio=%d",
|
||||||
|
lcid,
|
||||||
|
to_string(channels[lcid].cfg.direction),
|
||||||
|
channels[lcid].cfg.priority);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool isNR>
|
||||||
|
int ue_buffer_manager<isNR>::get_dl_tx_total() const
|
||||||
|
{
|
||||||
|
int sum = 0;
|
||||||
|
for (size_t lcid = 0; is_lcid_valid(lcid); ++lcid) {
|
||||||
|
sum += get_dl_tx_total(lcid);
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool isNR>
|
||||||
|
bool ue_buffer_manager<isNR>::is_lcg_active(uint32_t lcg) const
|
||||||
|
{
|
||||||
|
if (lcg == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (uint32_t lcid = 0; is_lcid_valid(lcid); ++lcid) {
|
||||||
|
if (is_bearer_ul(lcid) and channels[lcid].cfg.group == (int)lcg) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool isNR>
|
||||||
|
int ue_buffer_manager<isNR>::get_bsr(uint32_t lcg) const
|
||||||
|
{
|
||||||
|
return is_lcg_active(lcg) ? lcg_bsr[lcg] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool isNR>
|
||||||
|
void ue_buffer_manager<isNR>::ul_bsr(uint32_t lcg_id, uint32_t val)
|
||||||
|
{
|
||||||
|
if (not is_lcg_valid(lcg_id)) {
|
||||||
|
logger.warning("The provided logical channel group id=%d is not valid", lcg_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lcg_bsr[lcg_id] = val;
|
||||||
|
|
||||||
|
if (logger.debug.enabled()) {
|
||||||
|
fmt::memory_buffer str_buffer;
|
||||||
|
fmt::format_to(str_buffer, "{}", lcg_bsr);
|
||||||
|
logger.debug("SCHED: lcg_id=%d, bsr=%d. Current state=%s", lcg_id, val, srsran::to_c_str(str_buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool isNR>
|
||||||
|
void ue_buffer_manager<isNR>::dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t retx_queue)
|
||||||
|
{
|
||||||
|
if (not is_lcid_valid(lcid)) {
|
||||||
|
logger.warning("The provided lcid=%d is not valid", lcid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (lcid <= MAX_SRB_LC_ID and
|
||||||
|
(channels[lcid].buf_tx != (int)tx_queue or channels[lcid].buf_retx != (int)retx_queue)) {
|
||||||
|
logger.info("SCHED: DL lcid=%d buffer_state=%d,%d", lcid, tx_queue, retx_queue);
|
||||||
|
} else {
|
||||||
|
logger.debug("SCHED: DL lcid=%d buffer_state=%d,%d", lcid, tx_queue, retx_queue);
|
||||||
|
}
|
||||||
|
channels[lcid].buf_retx = retx_queue;
|
||||||
|
channels[lcid].buf_tx = tx_queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Explicit instantiation
|
||||||
|
template class ue_buffer_manager<true>;
|
||||||
|
template class ue_buffer_manager<false>;
|
||||||
|
|
||||||
|
} // namespace srsenb
|
@ -1,70 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* \section COPYRIGHT
|
|
||||||
*
|
|
||||||
* Copyright 2013-2021 Software Radio Systems Limited
|
|
||||||
*
|
|
||||||
* By using this file, you agree to the terms and conditions set
|
|
||||||
* forth in the LICENSE file which can be found at the top level of
|
|
||||||
* the distribution.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "srsenb/hdr/stack/mac/nr/sched_nr_ue_buffer_manager.h"
|
|
||||||
#include "srsran/common/string_helpers.h"
|
|
||||||
#include "srsran/srslog/bundled/fmt/format.h"
|
|
||||||
#include "srsran/srslog/bundled/fmt/ranges.h"
|
|
||||||
|
|
||||||
namespace srsenb {
|
|
||||||
namespace sched_nr_impl {
|
|
||||||
|
|
||||||
ue_buffer_manager::ue_buffer_manager(srslog::basic_logger& logger_) : logger(logger_) {}
|
|
||||||
|
|
||||||
bool ue_buffer_manager::is_lcg_active(uint32_t lcg) const
|
|
||||||
{
|
|
||||||
if (lcg == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
for (uint32_t lcid = 0; lcid < MAX_LC_ID; ++lcid) {
|
|
||||||
if (is_bearer_ul(lcid) and channels[lcid].cfg.group == (int)lcg) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ue_buffer_manager::get_bsr(uint32_t lcg) const
|
|
||||||
{
|
|
||||||
return is_lcg_active(lcg) ? lcg_bsr[lcg] : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ue_buffer_manager::ul_bsr(uint32_t lcg_id, uint32_t val)
|
|
||||||
{
|
|
||||||
srsran_assert(lcg_id < MAX_LCG_ID, "Provided LCG_ID=%d is above its limit=%d", lcg_id, MAX_LCG_ID);
|
|
||||||
lcg_bsr[lcg_id] = val;
|
|
||||||
|
|
||||||
if (logger.debug.enabled()) {
|
|
||||||
fmt::memory_buffer str_buffer;
|
|
||||||
fmt::format_to(str_buffer, "{}", lcg_bsr);
|
|
||||||
logger.debug("SCHED: lcg_id=%d, bsr=%s. Current state=%s", lcg_id, val, srsran::to_c_str(str_buffer));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ue_buffer_manager::dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t retx_queue)
|
|
||||||
{
|
|
||||||
if (lcid >= MAX_LC_ID) {
|
|
||||||
logger.warning("The provided lcid=%d is not valid", lcid);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (lcid <= MAX_SRB_LC_ID and
|
|
||||||
(channels[lcid].buf_tx != (int)tx_queue or channels[lcid].buf_retx != (int)retx_queue)) {
|
|
||||||
logger.info("SCHED: DL lcid=%d buffer_state=%d,%d", lcid, tx_queue, retx_queue);
|
|
||||||
} else {
|
|
||||||
logger.debug("SCHED: DL lcid=%d buffer_state=%d,%d", lcid, tx_queue, retx_queue);
|
|
||||||
}
|
|
||||||
channels[lcid].buf_retx = retx_queue;
|
|
||||||
channels[lcid].buf_tx = tx_queue;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sched_nr_impl
|
|
||||||
} // namespace srsenb
|
|
Loading…
Reference in New Issue