Review at https://gerrit.osmocom.org/3935
Simplify TS alloc: move slot check into function Move timeslot applicability check outside of nested for loop into separate function and document it. Change-Id: Ic39e848da47dc11357782362fdf6206d2c1457c2 Related: OS#2282 --- M src/gprs_rlcmac_ts_alloc.cpp 1 file changed, 116 insertions(+), 107 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/35/3935/1 diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index f654ffa..cb790f7 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -527,6 +527,119 @@ return capacity; } +enum { MASK_TT, MASK_TR }; + +static bool skip_slot(const struct gprs_rlcmac_trx *trx, const struct gprs_ms_multislot_class *ms_class, + uint8_t *rx_mask, unsigned mask_sel, unsigned ul_ts, int *capacity, uint32_t *checked_rx, + uint8_t dl_slots, uint8_t ul_slots, int *rx_window, int tx_window, uint16_t rx_valid_win, + unsigned tx_slot_count, bool enable_debug) +{ + char slot_info[9] = { 0 }; + unsigned common_slot_count; + unsigned req_common_slots; + unsigned rx_slot_count; + uint8_t rx_good; + + /* Filter out bad slots */ + uint16_t rx_bad = (uint16_t)(0xff & ~rx_mask[mask_sel]) << ul_ts; + rx_bad = (rx_bad | (rx_bad >> 8)) & 0xff; + rx_good = dl_slots & ~rx_bad; + + /* TODO: CHECK this calculation -> separate function for unit testing */ + + *rx_window = rx_good & rx_valid_win; + rx_slot_count = pcu_bitcount(*rx_window); + + if (enable_debug) + LOGP(DRLCMAC, LOGL_DEBUG, + "n_tx=%d, n_rx=%d, mask_sel=%d, tx=%02x, rx=%02x, mask=%02x, bad=%02x, good=%02x, " + "ul=%02x, dl=%02x\n", + tx_slot_count, rx_slot_count, mask_sel, + tx_window, rx_window, rx_mask[mask_sel], rx_bad, rx_good, + ul_slots, dl_slots); + + /* Check compliance with TS 45.002, table 6.4.2.2.1 */ + /* Whether to skip this round doesn not only depend on the bit + * sets but also on mask_sel. Therefore this check must be done + * before doing the test_and_set_bit shortcut. */ + if (ms_class->type == 1) { + unsigned slot_sum = rx_slot_count + tx_slot_count; + /* Assume down + up / dynamic. + * TODO: For ext-dynamic, down only, up only add more cases. + */ + if (slot_sum <= 6 && tx_slot_count < 3) { + if (mask_sel != MASK_TR) + return true; /* Skip Tta */ + } else if (slot_sum > 6 && tx_slot_count < 3) { + if (mask_sel != MASK_TT) + return true; /* Skip Tra */ + } else { + /* No supported row in TS 45.002, table 6.4.2.2.1. */ + if (enable_debug) { + snprintf(slot_info, 9, OSMO_BIT_SPEC, OSMO_BIT_PRINT_EX(rx_bad, 'x')); + masked_override_with(slot_info, *rx_window, 'D'); + masked_override_with(slot_info, tx_window, 'U'); + LOGP(DRLCMAC, LOGL_DEBUG, + " Skipping DL/UL slots: (TS=0)\"%s\"(TS=7), combination not supported\n", + slot_info); + } + + return true; + } + } + + /* Avoid repeated RX combination check */ + if (test_and_set_bit(checked_rx, *rx_window)) + return true; + + if (!rx_good) { + if (enable_debug) { + snprintf(slot_info, 9, OSMO_BIT_SPEC, OSMO_BIT_PRINT_EX(rx_bad, 'x')); + masked_override_with(slot_info, tx_window, 'U'); + LOGP(DRLCMAC, LOGL_DEBUG, + " Skipping DL/UL slots: (TS=0)\"%s\"(TS=7), no DL slots available\n", slot_info); + } + + return true; + } + + if (!(*rx_window)) + return true; + + /* Check number of common slots according to TS 45.002, §6.4.2.2 */ + common_slot_count = pcu_bitcount(tx_window & *rx_window); + req_common_slots = OSMO_MIN(tx_slot_count, rx_slot_count); + if (ms_class->type == 1) + req_common_slots = OSMO_MIN(req_common_slots, 2); + + if (req_common_slots != common_slot_count) { + if (enable_debug) { + snprintf(slot_info, 9, OSMO_BIT_SPEC, OSMO_BIT_PRINT_EX(rx_bad, 'x')); + masked_override_with(slot_info, *rx_window, 'D'); + masked_override_with(slot_info, tx_window, 'U'); + LOGP(DRLCMAC, LOGL_DEBUG, + " Skipping DL/UL slots: (TS=0)\"%s\"(TS=7), invalid number of common TS: %d (expected %d)\n", + slot_info, common_slot_count, req_common_slots); + } + + return true; + } + + /* Compute capacity */ + *capacity = compute_capacity(trx, *rx_window, tx_window); + + if (enable_debug) { + snprintf(slot_info, 9, OSMO_BIT_SPEC, OSMO_BIT_PRINT_EX(rx_bad, 'x')); + masked_override_with(slot_info, *rx_window, 'D'); + masked_override_with(slot_info, tx_window, 'U'); + masked_override_with(slot_info, *rx_window& tx_window, 'C'); + LOGP(DRLCMAC, LOGL_DEBUG, " Considering DL/UL slots: (TS=0)\"%s\"(TS=7), capacity = %d\n", + slot_info, *capacity); + } + + return false; +} + /*! Find set of slots available for allocation while taking MS class into account * * \param[in] trx Pointer to TRX object @@ -553,7 +666,6 @@ unsigned ul_ts, dl_ts; unsigned num_tx; - enum {MASK_TT, MASK_TR}; unsigned mask_sel; if (ms->ms_class() >= 32) { @@ -678,115 +790,12 @@ /* Validate with both Tta/Ttb/Trb and Ttb/Tra/Trb */ for (mask_sel = MASK_TT; mask_sel <= MASK_TR; mask_sel += 1) { - unsigned common_slot_count; - unsigned req_common_slots; - unsigned rx_slot_count; - uint16_t rx_bad; - uint8_t rx_good; int capacity; - /* Filter out bad slots */ - rx_bad = (uint16_t)(0xff & ~rx_mask[mask_sel]) << ul_ts; - rx_bad = (rx_bad | (rx_bad >> 8)) & 0xff; - rx_good = *dl_slots & ~rx_bad; - - /* TODO: CHECK this calculation -> separate function for unit testing */ - - rx_window = rx_good & rx_valid_win; - rx_slot_count = pcu_bitcount(rx_window); - - if (enable_debug) - LOGP(DRLCMAC, LOGL_DEBUG, "n_tx=%d, n_rx=%d, mask_sel=%d, " - "tx=%02x, rx=%02x, mask=%02x, bad=%02x, good=%02x, " - "ul=%02x, dl=%02x\n", - tx_slot_count, rx_slot_count, mask_sel, - tx_window, rx_window, rx_mask[mask_sel], rx_bad, rx_good, - *ul_slots, *dl_slots); - - /* Check compliance with TS 45.002, table 6.4.2.2.1 */ - /* Whether to skip this round doesn not only depend on the bit - * sets but also on mask_sel. Therefore this check must be done - * before doing the test_and_set_bit shortcut. */ - if (ms_class->type == 1) { - unsigned slot_sum = rx_slot_count + tx_slot_count; - /* Assume down+up/dynamic. - * TODO: For ext-dynamic, down only, up only add more cases. - */ - if (slot_sum <= 6 && tx_slot_count < 3) { - if (mask_sel != MASK_TR) - /* Skip Tta */ - continue; - } else if (slot_sum > 6 && tx_slot_count < 3) { - if (mask_sel != MASK_TT) - /* Skip Tra */ - continue; - } else { - /* No supported row in TS 45.002, table 6.4.2.2.1. */ - if (enable_debug) { - snprintf(slot_info, 9, OSMO_BIT_SPEC, - OSMO_BIT_PRINT_EX(rx_bad, 'x')); - masked_override_with(slot_info, rx_window, 'D'); - masked_override_with(slot_info, tx_window, 'U'); - LOGP(DRLCMAC, LOGL_DEBUG, - " Skipping DL/UL slots: (TS=0)\"%s\"(TS=7), " - "combination not supported\n", slot_info); - } - continue; - } - } - - /* Avoid repeated RX combination check */ - if (test_and_set_bit(checked_rx, rx_window)) + if (skip_slot(trx, ms_class, rx_mask, mask_sel, ul_ts, &capacity, checked_rx, + *dl_slots, *ul_slots, &rx_window, tx_window, rx_valid_win, + tx_slot_count, enable_debug)) continue; - - if (!rx_good) { - if (enable_debug) { - snprintf(slot_info, 9, OSMO_BIT_SPEC, - OSMO_BIT_PRINT_EX(rx_bad, 'x')); - masked_override_with(slot_info, tx_window, 'U'); - LOGP(DRLCMAC, LOGL_DEBUG, - " Skipping DL/UL slots: (TS=0)\"%s\"(TS=7), " - "no DL slots available\n", slot_info); - } - continue; - } - - if (!rx_window) - continue; - - /* Check number of common slots according to TS 45.002, §6.4.2.2 */ - common_slot_count = pcu_bitcount(tx_window & rx_window); - req_common_slots = OSMO_MIN(tx_slot_count, rx_slot_count); - if (ms_class->type == 1) - req_common_slots = OSMO_MIN(req_common_slots, 2); - - if (req_common_slots != common_slot_count) { - if (enable_debug) { - snprintf(slot_info, 9, OSMO_BIT_SPEC, - OSMO_BIT_PRINT_EX(rx_bad, 'x')); - masked_override_with(slot_info, rx_window, 'D'); - masked_override_with(slot_info, tx_window, 'U'); - LOGP(DRLCMAC, LOGL_DEBUG, - " Skipping DL/UL slots: (TS=0)\"%s\"(TS=7), " - "invalid number of common TS: %d (expected %d)\n", - slot_info, common_slot_count, req_common_slots); - } - continue; - } - - /* Compute capacity */ - capacity = compute_capacity(trx, rx_window, tx_window); - - if (enable_debug) { - snprintf(slot_info, 9, OSMO_BIT_SPEC, OSMO_BIT_PRINT_EX(rx_bad, 'x')); - masked_override_with(slot_info, rx_window, 'D'); - masked_override_with(slot_info, tx_window, 'U'); - masked_override_with(slot_info, rx_window& tx_window, 'C'); - LOGP(DRLCMAC, LOGL_DEBUG, - " Considering DL/UL slots: (TS=0)\"%s\"(TS=7), " - "capacity = %d\n", - slot_info, capacity); - } if (capacity <= max_capacity) continue; -- To view, visit https://gerrit.osmocom.org/3935 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic39e848da47dc11357782362fdf6206d2c1457c2 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: Max <msur...@sysmocom.de>