Simplify TS alloc: separate capacity computation
Move TRX capacity computation into separate function and document it. Change-Id: Ifd88fc7ff818ea2a041eae61c5d457926a0df0f2 Related: OS#2282
This commit is contained in:
parent
f633b8d8b2
commit
adca67bcbb
|
@ -61,24 +61,6 @@ static bool test_and_set_bit(uint32_t *bits, size_t elem)
|
||||||
return was_set;
|
return was_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int8_t find_free_usf(const struct gprs_rlcmac_pdch *pdch)
|
|
||||||
{
|
|
||||||
uint8_t usf_map = 0;
|
|
||||||
uint8_t usf;
|
|
||||||
|
|
||||||
usf_map = pdch->assigned_usf();
|
|
||||||
if (usf_map == (1 << 7) - 1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* look for USF, don't use USF=7 */
|
|
||||||
for (usf = 0; usf < 7; usf++) {
|
|
||||||
if (!(usf_map & (1 << usf)))
|
|
||||||
return usf;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int8_t find_free_tfi(const struct gprs_rlcmac_pdch *pdch, enum gprs_rlcmac_tbf_direction dir)
|
static inline int8_t find_free_tfi(const struct gprs_rlcmac_pdch *pdch, enum gprs_rlcmac_tbf_direction dir)
|
||||||
{
|
{
|
||||||
uint32_t tfi_map = pdch->assigned_tfi(dir);
|
uint32_t tfi_map = pdch->assigned_tfi(dir);
|
||||||
|
@ -214,7 +196,7 @@ static int find_least_busy_pdch(const struct gprs_rlcmac_trx *trx, enum gprs_rlc
|
||||||
}
|
}
|
||||||
/* Make sure that an USF is available */
|
/* Make sure that an USF is available */
|
||||||
if (dir == GPRS_RLCMAC_UL_TBF) {
|
if (dir == GPRS_RLCMAC_UL_TBF) {
|
||||||
usf = find_free_usf(pdch);
|
usf = find_free_usf(pdch->assigned_usf());
|
||||||
if (usf < 0) {
|
if (usf < 0) {
|
||||||
LOGP(DRLCMAC, LOGL_DEBUG,
|
LOGP(DRLCMAC, LOGL_DEBUG,
|
||||||
"- Skipping TS %d, because "
|
"- Skipping TS %d, because "
|
||||||
|
@ -464,6 +446,33 @@ int alloc_algorithm_a(struct gprs_rlcmac_bts *bts, GprsMs *ms_, struct gprs_rlcm
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Compute capacity of a given TRX
|
||||||
|
*
|
||||||
|
* \param[in] trx Pointer to TRX object
|
||||||
|
* \param[in] rx_window Receive window
|
||||||
|
* \param[in] tx_window Transmit window
|
||||||
|
* \returns non-negative capacity
|
||||||
|
*/
|
||||||
|
static inline unsigned compute_capacity(const struct gprs_rlcmac_trx *trx, int rx_window, int tx_window)
|
||||||
|
{
|
||||||
|
const struct gprs_rlcmac_pdch *pdch;
|
||||||
|
unsigned ts, capacity = 0;
|
||||||
|
|
||||||
|
for (ts = 0; ts < ARRAY_SIZE(trx->pdch); ts++) {
|
||||||
|
pdch = &trx->pdch[ts];
|
||||||
|
if (rx_window & (1 << ts))
|
||||||
|
capacity += OSMO_MAX(32 - pdch->num_reserved(GPRS_RLCMAC_DL_TBF), 1);
|
||||||
|
|
||||||
|
/* Only consider common slots for UL */
|
||||||
|
if (tx_window & rx_window & (1 << ts)) {
|
||||||
|
if (find_free_usf(pdch->assigned_usf()) >= 0)
|
||||||
|
capacity += OSMO_MAX(32 - pdch->num_reserved(GPRS_RLCMAC_UL_TBF), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return capacity;
|
||||||
|
}
|
||||||
|
|
||||||
/*! Find set of slots available for allocation while taking MS class into account
|
/*! Find set of slots available for allocation while taking MS class into account
|
||||||
*
|
*
|
||||||
* \param[in] trx Pointer to TRX object
|
* \param[in] trx Pointer to TRX object
|
||||||
|
@ -564,7 +573,6 @@ int find_multi_slots(struct gprs_rlcmac_trx *trx, uint8_t mslot_class, uint8_t *
|
||||||
unsigned rx_slot_count;
|
unsigned rx_slot_count;
|
||||||
uint16_t rx_bad;
|
uint16_t rx_bad;
|
||||||
uint8_t rx_good;
|
uint8_t rx_good;
|
||||||
unsigned ts;
|
|
||||||
int capacity;
|
int capacity;
|
||||||
|
|
||||||
/* Filter out bad slots */
|
/* Filter out bad slots */
|
||||||
|
@ -663,25 +671,7 @@ int find_multi_slots(struct gprs_rlcmac_trx *trx, uint8_t mslot_class, uint8_t *
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute capacity */
|
/* Compute capacity */
|
||||||
capacity = 0;
|
capacity = compute_capacity(trx, rx_window, tx_window);
|
||||||
|
|
||||||
for (ts = 0; ts < ARRAY_SIZE(trx->pdch); ts++) {
|
|
||||||
int c;
|
|
||||||
const struct gprs_rlcmac_pdch *pdch = &trx->pdch[ts];
|
|
||||||
if (rx_window & (1 << ts)) {
|
|
||||||
c = 32 - pdch->num_reserved(GPRS_RLCMAC_DL_TBF);
|
|
||||||
c = OSMO_MAX(c, 1);
|
|
||||||
capacity += c;
|
|
||||||
}
|
|
||||||
/* Only consider common slots for UL */
|
|
||||||
if (tx_window & rx_window & (1 << ts)) {
|
|
||||||
if (find_free_usf(pdch) >= 0) {
|
|
||||||
c = 32 - pdch->num_reserved(GPRS_RLCMAC_UL_TBF);
|
|
||||||
c = OSMO_MAX(c, 1);
|
|
||||||
capacity += c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ENABLE_TS_ALLOC_DEBUG
|
#ifdef ENABLE_TS_ALLOC_DEBUG
|
||||||
LOGP(DRLCMAC, LOGL_DEBUG,
|
LOGP(DRLCMAC, LOGL_DEBUG,
|
||||||
|
@ -702,7 +692,10 @@ int find_multi_slots(struct gprs_rlcmac_trx *trx, uint8_t mslot_class, uint8_t *
|
||||||
max_capacity = capacity;
|
max_capacity = capacity;
|
||||||
max_ul_slots = tx_window;
|
max_ul_slots = tx_window;
|
||||||
max_dl_slots = rx_window;
|
max_dl_slots = rx_window;
|
||||||
}}}}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!max_ul_slots || !max_dl_slots) {
|
if (!max_ul_slots || !max_dl_slots) {
|
||||||
LOGP(DRLCMAC, LOGL_NOTICE,
|
LOGP(DRLCMAC, LOGL_NOTICE,
|
||||||
|
|
|
@ -212,3 +212,19 @@ void mslot_fill_rx_mask(uint8_t mslot_class, uint8_t num_tx, uint8_t *rx_mask)
|
||||||
rx_mask[MASK_TT] = (rx_mask[MASK_TT] << 3) | (rx_mask[MASK_TT] >> 5);
|
rx_mask[MASK_TT] = (rx_mask[MASK_TT] << 3) | (rx_mask[MASK_TT] >> 5);
|
||||||
rx_mask[MASK_TR] = (rx_mask[MASK_TR] << 3) | (rx_mask[MASK_TR] >> 5);
|
rx_mask[MASK_TR] = (rx_mask[MASK_TR] << 3) | (rx_mask[MASK_TR] >> 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* look for USF, don't use USF=7 */
|
||||||
|
int8_t find_free_usf(uint8_t usf_map)
|
||||||
|
{
|
||||||
|
uint8_t usf;
|
||||||
|
|
||||||
|
if (usf_map == (1 << 7) - 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (usf = 0; usf < 7; usf++) {
|
||||||
|
if (!(usf_map & (1 << usf)))
|
||||||
|
return usf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
|
@ -50,3 +50,4 @@ uint8_t mslot_class_get_type(uint8_t ms_cl);
|
||||||
uint8_t mslot_class_max();
|
uint8_t mslot_class_max();
|
||||||
|
|
||||||
void mslot_fill_rx_mask(uint8_t mslot_class, uint8_t num_tx, uint8_t *rx_mask);
|
void mslot_fill_rx_mask(uint8_t mslot_class, uint8_t num_tx, uint8_t *rx_mask);
|
||||||
|
int8_t find_free_usf(uint8_t usf_map);
|
||||||
|
|
Loading…
Reference in New Issue