aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gprs_rlcmac_ts_alloc.cpp792
-rw-r--r--tests/alloc/AllocTest.cpp14
-rw-r--r--tests/alloc/AllocTest.err14
-rw-r--r--tests/alloc/AllocTest.ok443
4 files changed, 659 insertions, 604 deletions
diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp
index 8d4357e7..0169d49f 100644
--- a/src/gprs_rlcmac_ts_alloc.cpp
+++ b/src/gprs_rlcmac_ts_alloc.cpp
@@ -77,6 +77,42 @@ static const struct gprs_ms_multislot_class gprs_ms_multislot_class[32] = {
/* N/A */ { MS_NA,MS_NA, MS_NA, MS_NA, MS_NA, MS_NA, MS_NA, MS_NA },
};
+static unsigned lsb(unsigned x)
+{
+ return x & -x;
+}
+
+static unsigned bitcount(unsigned x)
+{
+ unsigned count = 0;
+ for (count = 0; x; count += 1)
+ x &= x - 1;
+
+ return count;
+}
+
+static char *set_flag_chars(char *buf, uint8_t val, char set_char, char unset_char = 0)
+{
+ int i;
+
+ for (i = 0; i < 8; i += 1, val = val >> 1) {
+ if (val & 1)
+ buf[i] = set_char;
+ else if (unset_char)
+ buf[i] = unset_char;
+ }
+
+ return buf;
+}
+
+static bool test_and_set_bit(uint32_t *bits, size_t elem)
+{
+ bool was_set = bits[elem/32] & (1 << (elem % 32));
+ bits[elem/32] |= (1 << (elem % 32));
+
+ return was_set;
+}
+
static inline int8_t find_free_usf(struct gprs_rlcmac_pdch *pdch)
{
struct gprs_rlcmac_ul_tbf *tbf;
@@ -304,347 +340,249 @@ int alloc_algorithm_a(struct gprs_rlcmac_bts *bts,
return 0;
}
-/*
- * Select a window of Rx slots if available.
- * The maximum allowed slots depend on RX or the window of available
- * slots. This must be done for uplink TBF also, because it is the basis
- * for calculating control slot and uplink slot(s).
- */
-static uint8_t select_dl_slots(struct gprs_rlcmac_trx *trx,
- const int ms_type, const int ms_max_rxslots,
- uint8_t *out_rx_win_min, uint8_t *out_rx_win_max)
-
+static int find_multi_slots(struct gprs_rlcmac_bts *bts,
+ struct gprs_rlcmac_trx *trx,
+ GprsMs *ms, uint8_t *ul_slots, uint8_t *dl_slots)
{
- uint8_t rx_window = 0;
- int rx_window_size = 0;
- int8_t last_tsc = -1; /* must be signed */
- uint8_t rx_win_min = 0, rx_win_max = 0;
-
- for (int ts_no = 0; ts_no < 8; ts_no++) {
- struct gprs_rlcmac_pdch *pdch;
- pdch = &trx->pdch[ts_no];
+ const struct gprs_ms_multislot_class *ms_class;
+ uint8_t Tx, Sum; /* Maximum Number of Slots: RX, Tx, Sum Rx+Tx */
+ uint8_t Tta, Ttb, Tra, Trb; /* Minimum Number of Slots */
+ uint8_t Type; /* Type of Mobile */
+ int rx_window, tx_window, pdch_slots;
+ static const char *digit[10] = { "0","1","2","3","4","5","6","7","8","9" };
+ char slot_info[9] = {0};
+ int max_capacity;
+ uint8_t max_ul_slots;
+ uint8_t max_dl_slots;
+ unsigned max_slots;
- /* check if enabled */
- if (!pdch->is_enabled()) {
- LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, because "
- "not enabled\n", ts_no);
- if (ms_type == 1 && rx_window)
- goto inc_window;
- continue;
- }
- /* check if TSC changes */
- if (last_tsc < 0)
- last_tsc = pdch->tsc;
- else if (last_tsc != pdch->tsc) {
- LOGP(DRLCMAC, LOGL_ERROR, "Skipping TS %d of TRX=%d, "
- "because it has different TSC than lower TS "
- "of TRX. In order to allow multislot, all "
- "slots must be configured with the same "
- "TSC!\n", ts_no, trx->trx_no);
- if (ms_type == 1 && rx_window)
- goto inc_window;
- continue;
- }
+ unsigned ul_ts, dl_ts;
+ unsigned num_tx;
- if (!rx_window)
- rx_win_min = ts_no;
+ uint32_t checked_tx[256/32] = {0};
- rx_window |= (1 << ts_no);
- LOGP(DRLCMAC, LOGL_DEBUG, "- Selected DL TS %d\n", ts_no);
+ if (ms->ms_class() >= 32) {
+ LOGP(DRLCMAC, LOGL_ERROR, "Multislot class %d out of range.\n",
+ ms->ms_class());
+ return -EINVAL;
+ }
- /* range of window (required for Type 1) */
- rx_win_max = ts_no;
+ if (ms->ms_class()) {
+ ms_class = &gprs_ms_multislot_class[ms->ms_class()];
+ LOGP(DRLCMAC, LOGL_DEBUG, "Slot Allocation (Algorithm B) for "
+ "class %d\n", ms->ms_class());
+ } else {
+ ms_class = &gprs_ms_multislot_class[12];
+ LOGP(DRLCMAC, LOGL_DEBUG, "Slot Allocation (Algorithm B) for "
+ "unknown class (assuming 12)\n");
+ }
-inc_window:
- if (++rx_window_size == ms_max_rxslots) {
- LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because slots / "
- "window reached maximum alowed Rx size\n");
- break;
- }
- if (ms_type == 1 && rx_window_size == 5) {
- LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because slots / "
- "window reached maximum supported Rx size of "
- "this algorithm\n");
- break;
- }
+ if (ms_class->tx == MS_NA) {
+ LOGP(DRLCMAC, LOGL_NOTICE, "Multislot class %d not "
+ "applicable.\n", ms->ms_class());
+ return -EINVAL;
}
- LOGP(DRLCMAC, LOGL_DEBUG, "- Selected slots for RX: "
- "(TS=0)\"%c%c%c%c%c%c%c%c\"(TS=7)\n",
- ((rx_window & 0x01)) ? 'D' : '.',
- ((rx_window & 0x02)) ? 'D' : '.',
- ((rx_window & 0x04)) ? 'D' : '.',
- ((rx_window & 0x08)) ? 'D' : '.',
- ((rx_window & 0x10)) ? 'D' : '.',
- ((rx_window & 0x20)) ? 'D' : '.',
- ((rx_window & 0x40)) ? 'D' : '.',
- ((rx_window & 0x80)) ? 'D' : '.');
-
- *out_rx_win_min = rx_win_min;
- *out_rx_win_max = rx_win_max;
- return rx_window;
-}
+ Tx = ms_class->tx;
+ Sum = ms_class->sum;
+ Tta = ms_class->ta;
+ Ttb = ms_class->tb;
+ Tra = ms_class->ra;
+ Trb = ms_class->rb;
+ Type = ms_class->type;
-static int reduce_rx_window(const int ms_type, const GprsMs *ms,
- const int Tt, const int Tr,
- int *rx_window,
- uint8_t *rx_win_min, uint8_t *rx_win_max)
-{
- gprs_rlcmac_ul_tbf *ul_tbf;
+ /* Tta and Ttb may depend on hopping or frequency change */
+ /* TODO: Set them to 1 */
+ if (Ttb == MS_A || Ttb == MS_B)
+ Ttb = 0;
+ if (Trb == MS_A || Trb == MS_C)
+ Trb = 0;
- if (ms_type != 1)
- return 0;
- if (!ms)
- return 0;
+ LOGP(DRLCMAC, LOGL_DEBUG, "- Rx=%d Tx=%d Sum Rx+Tx=%s Tta=%s Ttb=%d "
+ " Tra=%d Trb=%d Type=%d\n", ms_class->rx, Tx,
+ (Sum == MS_NA) ? "N/A" : digit[Sum],
+ (Tta == MS_NA) ? "N/A" : digit[Tta], Ttb, Tra, Trb, Type);
- ul_tbf = ms->ul_tbf();
+ max_slots = OSMO_MAX(ms_class->rx, ms_class->tx);
- if (!ul_tbf)
- return 0;
+ if (*dl_slots == 0)
+ *dl_slots = 0xff;
- uint8_t collide = 0, ul_usage = 0;
+ if (*ul_slots == 0)
+ *ul_slots = 0xff;
- /* calculate mask of colliding slots */
- for (uint8_t ts_no = 0; ts_no < 8; ts_no++) {
- int j;
- if (!ul_tbf->pdch[ts_no])
- continue;
+ pdch_slots = find_possible_pdchs(trx, max_slots, 0xff);
- ul_usage |= (1 << ts_no);
- /* mark bits from TS-t .. TS+r */
- for (j = (ts_no - Tt) & 7; j != ((ts_no + Tr + 1) & 7); j = (j + 1) & 7)
- collide |= (1 << j);
- }
+ *dl_slots &= pdch_slots;
+ *ul_slots &= pdch_slots;
- LOGP(DRLCMAC, LOGL_DEBUG, "- Not allowed slots due to existing "
- "UL allocation: (TS=0)\"%c%c%c%c%c%c%c%c\"(TS=7) "
- " D=downlink x=not usable\n",
- ((ul_usage & 0x01)) ? 'D' : ((collide & 0x01))?'x':'.',
- ((ul_usage & 0x02)) ? 'D' : ((collide & 0x02))?'x':'.',
- ((ul_usage & 0x04)) ? 'D' : ((collide & 0x04))?'x':'.',
- ((ul_usage & 0x08)) ? 'D' : ((collide & 0x08))?'x':'.',
- ((ul_usage & 0x10)) ? 'D' : ((collide & 0x10))?'x':'.',
- ((ul_usage & 0x20)) ? 'D' : ((collide & 0x20))?'x':'.',
- ((ul_usage & 0x40)) ? 'D' : ((collide & 0x40))?'x':'.',
- ((ul_usage & 0x80)) ? 'D' : ((collide & 0x80))?'x':'.');
-
- /*
- * Uplink/Downlink in GSM is shifted by three timeslots. Make
- * sure they don't collide.
- */
- *rx_window &= ~(collide << 3);
- *rx_window &= ~(collide >> 5);
- LOGP(DRLCMAC, LOGL_DEBUG, "- Remaining slots for RX: "
- "(TS=0)\"%c%c%c%c%c%c%c%c\"(TS=7)\n",
- ((*rx_window & 0x01)) ? 'D' : '.',
- ((*rx_window & 0x02)) ? 'D' : '.',
- ((*rx_window & 0x04)) ? 'D' : '.',
- ((*rx_window & 0x08)) ? 'D' : '.',
- ((*rx_window & 0x10)) ? 'D' : '.',
- ((*rx_window & 0x20)) ? 'D' : '.',
- ((*rx_window & 0x40)) ? 'D' : '.',
- ((*rx_window & 0x80)) ? 'D' : '.');
-
- if (!*rx_window) {
- LOGP(DRLCMAC, LOGL_NOTICE, "No suitable downlink slots "
- "available with current uplink assignment\n");
- return -EBUSY;
- }
+ LOGP(DRLCMAC, LOGL_DEBUG, "- Possible DL/UL slots: (TS=0)\"%s\"(TS=7)\n",
+ set_flag_chars(set_flag_chars(set_flag_chars(slot_info,
+ *dl_slots, 'D', '.'),
+ *ul_slots, 'U'),
+ *ul_slots & *dl_slots, 'C'));
- return 0;
-}
+ /* Check for each UL (TX) slot */
-/* shrink range of rx_win_min and rx_win_max */
-static void shrink_rx_window(uint8_t *rx_win_min, uint8_t *rx_win_max, int rx_window)
-{
- /* calculate new min/max */
- for (uint8_t ts_no = *rx_win_min; ts_no <= *rx_win_max; ts_no++) {
- if ((rx_window & (1 << ts_no)))
- break;
- *rx_win_min = ts_no + 1;
- LOGP(DRLCMAC, LOGL_DEBUG, "- TS is unused, so "
- "raising start of DL window to %d\n",
- *rx_win_min);
- }
- for (uint8_t ts_no = *rx_win_max; ts_no >= *rx_win_min; ts_no--) {
- if ((rx_window & (1 << ts_no)))
- break;
- *rx_win_max = ts_no - 1;
- LOGP(DRLCMAC, LOGL_DEBUG, "- TS is unused, so "
- "lowering end of DL window to %d\n",
- *rx_win_max);
- }
-}
+ max_capacity = -1;
+ max_ul_slots = 0;
+ max_dl_slots = 0;
-/*
- * reduce window, to allow at least one uplink TX slot
- * this is only required for Type 1
- */
-static uint8_t update_rx_win_max(const int ms_type, const int Tt,
- const int Tr, uint8_t rx_win_min, uint8_t rx_win_max)
-{
- if (ms_type != 1)
- return rx_win_max;
+ /* Iterate through possible numbers of TX slots */
+ for (num_tx = 1; num_tx <= ms_class->tx; num_tx += 1) {
+ uint16_t tx_valid_win = (1 << num_tx) - 1;
- if (rx_win_max - rx_win_min + 1 + Tt + 1 + Tr > 8) {
- rx_win_max = rx_win_min + 7 - Tt - 1 - Tr;
- LOGP(DRLCMAC, LOGL_DEBUG, "- Reduce RX window due to time "
- "contraints to %d slots\n", rx_win_max - rx_win_min + 1);
- }
+ uint8_t rx_mask[2]; /* 0: Tt*, 1: Tr* */
+ rx_mask[0] = (0x100 >> OSMO_MAX(Ttb, Tta)) - 1;
+ rx_mask[0] &= ~((1 << (Trb + num_tx)) - 1);
+ rx_mask[0] = rx_mask[0] << 3 | rx_mask[0] >> 5;
+ rx_mask[1] = (0x100 >> Ttb) - 1;
+ rx_mask[1] &= ~((1 << (OSMO_MAX(Trb, Tra) + num_tx)) - 1);
+ rx_mask[1] = rx_mask[1] << 3 | rx_mask[1] >> 5;
- return rx_win_max;
-}
+ /* Rotate group of TX slots: UUU-----, -UUU----, ..., UU-----U */
+ for (ul_ts = 0; ul_ts < 8; ul_ts += 1, tx_valid_win <<= 1) {
+ unsigned tx_slot_count;
+ int max_rx;
+ uint16_t rx_valid_win;
+ uint32_t checked_rx[256/32] = {0};
-static void tx_win_from_rx(const int ms_type,
- uint8_t rx_win_min, uint8_t rx_win_max,
- int Tt, int Tr,
- uint8_t *tx_win_min, uint8_t *tx_win_max,
- uint8_t *tx_range)
-{
- if (ms_type == 1) {
- /* calculate TX window (shifted by 3 timeslots)
- * it uses the space between tx_win_max and tx_win_min */
- *tx_win_min = (rx_win_max - 2 + Tt) & 7;
- *tx_win_max = (rx_win_min + 4 - Tr) & 7;
- } else {
- /* TX and RX simultaniously */
- *tx_win_min = rx_win_min;
- *tx_win_max = 7;
- }
+ /* Wrap valid window */
+ tx_valid_win = (tx_valid_win | tx_valid_win >> 8) & 0xff;
- *tx_range = (*tx_win_max - *tx_win_min + 1) & 7;
- /* if TX window fills complete range */
- if (*tx_range == 0)
- *tx_range = 8;
- LOGP(DRLCMAC, LOGL_DEBUG, "- TX-Window is: %d..%d\n", *tx_win_min,
- *tx_win_max);
-}
+ tx_window = tx_valid_win;
-/*
- * Select a window of Tx slots if available.
- * The maximum allowed slots depend on TX or the window of available
- * slots.
- */
-static int select_ul_slots(gprs_rlcmac_trx *trx,
- const int ms_type, const int ms_max_txslots,
- uint8_t tx_win_min, uint8_t tx_range,
- int8_t *usf, int8_t *first_common_ts, uint8_t rx_window)
-{
- int tsc = -1;
- uint8_t tx_window = 0;
- int i;
- uint8_t ts_no;
+ /* Filter out unavailable slots */
+ tx_window &= *ul_slots;
- for (ts_no = tx_win_min, i = 0; i < tx_range; ts_no = (ts_no + 1) & 7, i++) {
- gprs_rlcmac_pdch *pdch = &trx->pdch[ts_no];
+ /* Avoid repeated TX combination check */
+ if (test_and_set_bit(checked_tx, tx_window))
+ continue;
- /* check if enabled */
- if (!pdch->is_enabled()) {
- LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, "
- "because not enabled\n", ts_no);
- if (ms_type == 1 && tx_window)
- goto inc_window;
+ if (!tx_window)
continue;
- }
- /* check if used as downlink */
- if (!(rx_window & (1 << ts_no))) {
- LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, "
- "because not a downlink slot\n", ts_no);
- if (ms_type == 1 && tx_window)
- goto inc_window;
+
+ tx_slot_count = bitcount(tx_window);
+
+ max_rx = OSMO_MIN(ms_class->rx, ms_class->sum - num_tx);
+ rx_valid_win = (1 << max_rx) - 1;
+
+ /* Rotate group of RX slots: DDD-----, -DDD----, ..., DD-----D */
+ for (dl_ts = 0; dl_ts < 8; dl_ts += 1, rx_valid_win <<= 1) {
+ /* Wrap valid window */
+ rx_valid_win = (rx_valid_win | rx_valid_win >> 8) & 0xff;
+
+ /* Validate with both Tta/Ttb/Trb and Ttb/Tra/Trb */
+ for (unsigned m_idx = 0; m_idx < ARRAY_SIZE(rx_mask); m_idx += 1) {
+ unsigned common_slot_count;
+ unsigned req_common_slots;
+ unsigned rx_slot_count;
+ uint16_t rx_bad;
+ uint8_t rx_good;
+ unsigned ts;
+ int capacity;
+
+ /* Filter out bad slots */
+ rx_bad = (uint16_t)(0xff & ~rx_mask[m_idx]) << 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;
+
+ /* Avoid repeated RX combination check */
+ if (test_and_set_bit(checked_rx, rx_window))
continue;
- }
- /* check if TSC changes */
- if (tsc < 0)
- tsc = pdch->tsc;
- else if (tsc != pdch->tsc) {
- LOGP(DRLCMAC, LOGL_ERROR, "Skipping TS %d of "
- "TRX=%d, because it has different TSC "
- "than lower TS of TRX. In order to "
- "allow multislot, all slots must be "
- "configured with the same TSC!\n",
- ts_no, trx->trx_no);
- if (ms_type == 1)
- goto inc_window;
+
+ rx_slot_count = bitcount(rx_window);
+
+#if 0
+ LOGP(DRLCMAC, LOGL_DEBUG, "n_tx=%d, n_rx=%d, "
+ "tx=%02x, rx=%02x, mask=%02x, bad=%02x, good=%02x, ul=%02x, dl=%02x\n",
+ tx_slot_count, rx_slot_count,
+ tx_window, rx_window, rx_mask[m_idx], rx_bad, rx_good, *ul_slots, *dl_slots);
+#endif
+
+ if (!rx_good) {
+ LOGP(DRLCMAC, LOGL_DEBUG,
+ "- Skipping DL/UL slots: (TS=0)\"%s\"(TS=7), "
+ "no DL slots available\n",
+ set_flag_chars(set_flag_chars(slot_info,
+ rx_bad, 'x', '.'),
+ tx_window, 'U'));
continue;
}
- /* check for free usf */
- usf[ts_no] = find_free_usf(pdch);
- if (usf[ts_no] < 0) {
- LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, "
- "because no USF available\n", ts_no);
- if (ms_type == 1)
- goto inc_window;
+
+ if (!rx_window)
continue;
- }
- if (!tx_window)
- *first_common_ts = ts_no;
+ /* Check number of common slots according to TS 54.002, 6.4.2.2 */
+ common_slot_count = 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) {
+ LOGP(DRLCMAC, LOGL_DEBUG,
+ "- Skipping DL/UL slots: (TS=0)\"%s\"(TS=7), "
+ "invalid number of common TS: %d (expected %d)\n",
+ set_flag_chars(set_flag_chars(set_flag_chars(
+ slot_info,
+ rx_bad, 'x', '.'),
+ rx_window, 'D'),
+ tx_window, 'U'),
+ common_slot_count,
+ req_common_slots);
+ continue;
+ }
- tx_window |= (1 << ts_no);
- LOGP(DRLCMAC, LOGL_DEBUG, "- Selected UL TS %d\n", ts_no);
+ /* Compute capacity */
+ capacity = 0;
-inc_window:
- if (1 && ms_type == 1) { /* FIXME: multislot UL assignment */
- LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because "
- "1 slot assigned\n");
- break;
- }
- if (i+1 == ms_max_txslots) {
- LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because "
- "slots / window reached maximum "
- "allowed Tx size\n");
- break;
+ for (ts = 0; ts < ARRAY_SIZE(trx->pdch); ts++) {
+ int c;
+ struct gprs_rlcmac_pdch *pdch = &trx->pdch[ts];
+ if (rx_window & (1 << ts)) {
+ c = 32 - pdch->num_reserved(GPRS_RLCMAC_DL_TBF);
+ capacity += c;
+ }
+ if (tx_window & (1 << ts)) {
+ c = 32 - pdch->num_reserved(GPRS_RLCMAC_UL_TBF);
+ capacity += c;
+ }
}
- }
- LOGP(DRLCMAC, LOGL_DEBUG, "- Selected TX window: "
- "(TS=0)\"%c%c%c%c%c%c%c%c\"(TS=7)\n",
- ((tx_window & 0x01)) ? 'U' : '.',
- ((tx_window & 0x02)) ? 'U' : '.',
- ((tx_window & 0x04)) ? 'U' : '.',
- ((tx_window & 0x08)) ? 'U' : '.',
- ((tx_window & 0x10)) ? 'U' : '.',
- ((tx_window & 0x20)) ? 'U' : '.',
- ((tx_window & 0x40)) ? 'U' : '.',
- ((tx_window & 0x80)) ? 'U' : '.');
-
- if (!tx_window) {
- LOGP(DRLCMAC, LOGL_NOTICE, "No suitable uplink slots "
- "available\n");
- return -EBUSY;
- }
+ LOGP(DRLCMAC, LOGL_DEBUG,
+ "- Considering DL/UL slots: (TS=0)\"%s\"(TS=7), "
+ "capacity = %d\n",
+ set_flag_chars(set_flag_chars(set_flag_chars(set_flag_chars(
+ slot_info,
+ rx_bad, 'x', '.'),
+ rx_window, 'D'),
+ tx_window, 'U'),
+ rx_window & tx_window, 'C'),
+ capacity);
+
+ if (capacity <= max_capacity)
+ continue;
- return tx_window;
-}
+ max_capacity = capacity;
+ max_ul_slots = tx_window;
+ max_dl_slots = rx_window;
+ }}}}
-/*
- * Assign the first common ts, which is used for control or
- * single slot.
- */
-static int select_first_ts(gprs_rlcmac_trx *trx, uint8_t tx_win_min,
- uint8_t tx_range, uint8_t rx_window)
-{
- uint8_t ts_no;
- int i;
- for (ts_no = tx_win_min, i = 0; i < tx_range; ts_no = (ts_no + 1) & 7, i++) {
- gprs_rlcmac_pdch *pdch = &trx->pdch[ts_no];
- /* check if enabled */
- if (!pdch->is_enabled()) {
- LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, "
- "because not enabled\n", ts_no);
- continue;
- }
- /* check if used as downlink */
- if (!(rx_window & (1 << ts_no))) {
- LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, "
- "because not a downlink slot\n", ts_no);
- continue;
- }
- return ts_no;
+ if (!max_ul_slots || !max_dl_slots) {
+ LOGP(DRLCMAC, LOGL_NOTICE,
+ "No valid UL/DL slot combination found\n");
+ return -EINVAL;
}
- return -1;
+ *ul_slots = max_ul_slots;
+ *dl_slots = max_dl_slots;
+
+ return 0;
}
/* Slot Allocation: Algorithm B
@@ -657,153 +595,166 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts,
GprsMs *ms,
struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single)
{
- const struct gprs_ms_multislot_class *ms_class;
- uint8_t Tx, Sum; /* Maximum Number of Slots: RX, Tx, Sum Rx+Tx */
- uint8_t Tta, Ttb, Tra, Trb, Tt, Tr; /* Minimum Number of Slots */
- uint8_t Type; /* Type of Mobile */
- int rx_window;
- static const char *digit[10] = { "0","1","2","3","4","5","6","7","8","9" };
- int8_t usf[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; /* must be signed */
- int8_t first_common_ts = -1;
- uint8_t ts;
+ uint8_t dl_slots = 0;
+ uint8_t ul_slots = 0;
+ int8_t first_common_ts;
uint8_t slotcount = 0;
+ uint8_t avail_count = 0;
+ char slot_info[9] = {0};
+ int ts;
+ int rc;
-
- if (tbf->ms_class() >= 32) {
- LOGP(DRLCMAC, LOGL_ERROR, "Multislot class %d out of range.\n",
- tbf->ms_class());
+ if (!ms) {
+ LOGP(DRLCMAC, LOGL_ERROR, "MS not set\n");
return -EINVAL;
}
- if (tbf->ms_class()) {
- ms_class = &gprs_ms_multislot_class[tbf->ms_class()];
- LOGP(DRLCMAC, LOGL_DEBUG, "Slot Allocation (Algorithm B) for "
- "class %d\n", tbf->ms_class());
- } else {
- ms_class = &gprs_ms_multislot_class[12];
- LOGP(DRLCMAC, LOGL_DEBUG, "Slot Allocation (Algorithm B) for "
- "unknow class (assuming 12)\n");
- }
+ dl_slots = ms->reserved_dl_slots();
+ ul_slots = ms->reserved_ul_slots();
- if (ms_class->tx == MS_NA) {
- LOGP(DRLCMAC, LOGL_NOTICE, "Multislot class %d not "
- "applicable.\n", tbf->ms_class());
- return -EINVAL;
+ if (!dl_slots || !ul_slots) {
+ rc = find_multi_slots(bts, tbf->trx, ms, &ul_slots, &dl_slots);
+ if (rc < 0)
+ return rc;
+
+ ms->set_reserved_slots(tbf->trx, ul_slots, dl_slots);
+
+ LOGP(DRLCMAC, LOGL_DEBUG,
+ "- Reserved DL/UL slots: (TS=0)\"%s\"(TS=7)\n",
+ set_flag_chars(set_flag_chars(set_flag_chars(slot_info,
+ dl_slots, 'D', '.'),
+ ul_slots, 'U'),
+ ul_slots & dl_slots, 'C'));
}
- Tx = ms_class->tx;
- Sum = ms_class->sum;
- Tta = ms_class->ta;
- Ttb = ms_class->tb;
- Tra = ms_class->ra;
- Trb = ms_class->rb;
- Type = ms_class->type;
+ first_common_ts = ms->first_common_ts();
- /* Tta and Ttb may depend on hopping or frequency change */
- if (Ttb == MS_A || Ttb == MS_B)
- Ttb = 0;
- if (Trb == MS_A || Trb == MS_C)
- Trb = 0;
+ if (single) {
+ /* Make sure to consider the first common slot only */
+ ul_slots = dl_slots = dl_slots & ul_slots;
- LOGP(DRLCMAC, LOGL_DEBUG, "- Rx=%d Tx=%d Sum Rx+Tx=%s Tta=%s Ttb=%d "
- " Tra=%d Trb=%d Type=%d\n", ms_class->rx, Tx,
- (Sum == MS_NA) ? "N/A" : digit[Sum],
- (Tta == MS_NA) ? "N/A" : digit[Tta], Ttb, Tra, Trb, Type);
+ ts = first_common_ts;
- /* select the values for time contraints */
- /* applicable to type 1 and type 2 */
- Tt = Ttb;
- Tr = Trb;
-
- uint8_t rx_win_min, rx_win_max;
- rx_window = select_dl_slots(tbf->trx, ms_class->type, ms_class->rx,
- &rx_win_min, &rx_win_max);
-
-
- /* reduce window, if existing uplink slots collide RX window */
- int rc = reduce_rx_window(ms_class->type, ms, Tt, Tr,
- &rx_window, &rx_win_min, &rx_win_max);
- if (rc < 0)
- return rc;
- shrink_rx_window(&rx_win_min, &rx_win_max, rx_window);
- rx_win_max = update_rx_win_max(ms_class->type, Tt, Tr,
- rx_win_min, rx_win_max);
- shrink_rx_window(&rx_win_min, &rx_win_max, rx_window);
- LOGP(DRLCMAC, LOGL_DEBUG, "- RX-Window is: %d..%d\n", rx_win_min,
- rx_win_max);
-
- /* calculate TX window */
- uint8_t tx_win_min, tx_win_max, tx_range;
- tx_win_from_rx(ms_class->type, rx_win_min, rx_win_max, Tt, Tr,
- &tx_win_min, &tx_win_max, &tx_range);
-
- /* select UL slots but in both cases assign first_common_ts */
- uint8_t tx_window = 0;
- if (tbf->direction == GPRS_RLCMAC_UL_TBF) {
- rc = select_ul_slots(tbf->trx, ms_class->type, ms_class->tx,
- tx_win_min, tx_range, usf,
- &first_common_ts, rx_window);
- if (rc < 0)
- return rc;
- tx_window = rc;
- } else {
- first_common_ts = select_first_ts(tbf->trx, tx_win_min,
- tx_range, rx_window);
+ if (ts < 0)
+ ts = find_least_busy_pdch(tbf->trx, tbf->direction,
+ dl_slots & ul_slots, NULL);
+ if (ts < 0)
+ ul_slots = dl_slots = lsb(dl_slots & ul_slots);
+ else
+ ul_slots = dl_slots = (dl_slots & ul_slots) & (1<<ts);
+ } else if (first_common_ts > 0) {
+ /* Make sure to keep the common TBF */
+ uint8_t disable_dl_slots;
+
+ /* Mark all slots below the common TBF, e.g. cTS=4 -> xxx----- */
+ disable_dl_slots = (1 << (first_common_ts - 1)) - 1;
+
+ /* Only disable common slots in that set */
+ disable_dl_slots &= (dl_slots & ul_slots);
+
+ /* Remove them from the uplink set */
+ ul_slots &= ~disable_dl_slots;
+
+ /* The disabled UL slots will not be used again for subsequent
+ * TBF, do not reserve them anymore */
+ if (disable_dl_slots)
+ ms->set_reserved_slots(tbf->trx, ul_slots, dl_slots);
}
- #warning "first_common_ts might be different if there was no free USF for the new uplink assignment"
- if (first_common_ts < 0) {
- LOGP(DRLCMAC, LOGL_NOTICE, "No first common slots available\n");
+ if (dl_slots == 0) {
+ LOGP(DRLCMAC, LOGL_NOTICE, "No downlink slots available\n");
+ return -EINVAL;
+ }
+
+ if (ul_slots == 0) {
+ LOGP(DRLCMAC, LOGL_NOTICE, "No uplink slots available\n");
return -EINVAL;
}
if (tbf->direction == GPRS_RLCMAC_DL_TBF) {
struct gprs_rlcmac_dl_tbf *dl_tbf = static_cast<gprs_rlcmac_dl_tbf *>(tbf);
+
+ LOGP(DRLCMAC, LOGL_DEBUG,
+ "- Selected DL slots: (TS=0)\"%s\"(TS=7)%s\n",
+ set_flag_chars(set_flag_chars(slot_info,
+ ms->reserved_dl_slots(), 'd', '.'),
+ dl_slots, 'D'),
+ single ? ", single" : "");
+
/* assign downlink */
- if (rx_window == 0) {
+ if (dl_slots == 0) {
LOGP(DRLCMAC, LOGL_NOTICE, "No downlink slots "
"available\n");
return -EINVAL;
}
for (ts = 0; ts < 8; ts++) {
- if ((rx_window & (1 << ts))) {
- /* be sure to select a single downlink slots
- * that can be used for uplink, if multiple
- * slots are assigned later. */
- if (single && first_common_ts != ts)
- continue;
- LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning DL TS "
- "%d\n", ts);
- assign_dlink_tbf(&tbf->trx->pdch[ts], dl_tbf);
- slotcount++;
- if (slotcount == 1)
- dl_tbf->first_ts = ts;
- if (single)
- break;
- }
+ if (!(dl_slots & (1 << ts)))
+ continue;
+
+ LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning DL TS "
+ "%d\n", ts);
+ assign_dlink_tbf(&tbf->trx->pdch[ts], dl_tbf);
+ slotcount++;
+ if (slotcount == 1)
+ dl_tbf->first_ts = ts;
}
+ avail_count = bitcount(ms->reserved_dl_slots());
+
} else {
struct gprs_rlcmac_ul_tbf *ul_tbf = static_cast<gprs_rlcmac_ul_tbf *>(tbf);
+ int free_usf = -1;
+
+ if (first_common_ts >= 0)
+ ul_slots = 1 << first_common_ts;
+ else
+ ul_slots = ul_slots & dl_slots;
+
+ ts = find_least_busy_pdch(tbf->trx, GPRS_RLCMAC_UL_TBF,
+ ul_slots, &free_usf);
+
+ if (free_usf < 0) {
+ LOGP(DRLCMAC, LOGL_NOTICE, "No USF available\n");
+ return -EBUSY;
+ }
+ ul_slots = 1 << ts;
+
+ LOGP(DRLCMAC, LOGL_DEBUG,
+ "- Selected UL slots: (TS=0)\"%s\"(TS=7)%s\n",
+ set_flag_chars(set_flag_chars(slot_info,
+ ms->reserved_ul_slots(), 'u', '.'),
+ ul_slots, 'U'),
+ single ? ", single" : "");
+
+ assign_uplink_tbf_usf(&tbf->trx->pdch[ts], ul_tbf, free_usf);
+ slotcount++;
+ ul_tbf->first_ts = ts;
+
+ avail_count = bitcount(ms->reserved_ul_slots());
+#if 0 /* This code assigns multiple slots for UL (and wastes USFs that way) */
for (ts = 0; ts < 8; ts++) {
- if ((tx_window & (1 << ts))) {
- LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning UL TS "
- "%d\n", ts);
- assign_uplink_tbf_usf(&tbf->trx->pdch[ts], ul_tbf, usf[ts]);
- slotcount++;
- if (slotcount == 1)
- ul_tbf->first_ts = ts;
- if (single)
- break;
+ if (!(ul_slots & (1 << ts)))
+ continue;
+
+ free_usf = find_free_usf(&tbf->trx->pdch[ts]);
+ if (free_usf < 0) {
+ LOGP(DRLCMAC, LOGL_DEBUG,
+ "- Skipping TS %d, because "
+ "no USF available\n", ts);
+ continue;
}
+
+ LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning UL TS "
+ "%d\n", ts);
+ assign_uplink_tbf_usf(&tbf->trx->pdch[ts], ul_tbf, free_usf);
+ slotcount++;
+ if (slotcount == 1)
+ ul_tbf->first_ts = ts;
}
+#endif
}
- if (single && slotcount) {
- uint8_t ts_count = 0;
- for (ts = 0; ts < 8; ts++)
- if ((tx_window & (1 << ts)))
- ts_count++;
- tbf->upgrade_to_multislot = (ts_count > 1);
+ if (single && slotcount) {
+ tbf->upgrade_to_multislot = (avail_count > slotcount);
LOGP(DRLCMAC, LOGL_INFO, "Using single slot at TS %d for %s\n",
tbf->first_ts,
(tbf->direction == GPRS_RLCMAC_DL_TBF) ? "DL" : "UL");
@@ -812,8 +763,13 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts,
LOGP(DRLCMAC, LOGL_INFO, "Using %d slots for %s\n", slotcount,
(tbf->direction == GPRS_RLCMAC_DL_TBF) ? "DL" : "UL");
}
- if (slotcount == 0)
- return -EBUSY;
+
+ first_common_ts = ffs(dl_slots & ul_slots) - 1;
+
+ if (first_common_ts < 0) {
+ LOGP(DRLCMAC, LOGL_NOTICE, "No first common slots available\n");
+ return -EINVAL;
+ }
tbf->first_common_ts = first_common_ts;
diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp
index b918132c..187b88a8 100644
--- a/tests/alloc/AllocTest.cpp
+++ b/tests/alloc/AllocTest.cpp
@@ -565,18 +565,18 @@ static void test_successive_allocation()
test_successive_allocation(alloc_algorithm_a, 1, 1, TEST_MODE_UL_AND_DL,
32, "algorithm A (UL and DL)");
test_successive_allocation(alloc_algorithm_b, 10, 10, TEST_MODE_UL_AND_DL,
- 7, "algorithm B class 10 (UL and DL)");
+ 32, "algorithm B class 10 (UL and DL)");
test_successive_allocation(alloc_algorithm_b, 12, 12, TEST_MODE_UL_AND_DL,
- 7, "algorithm B class 12 (UL and DL)");
+ 29, "algorithm B class 12 (UL and DL)");
test_successive_allocation(alloc_algorithm_b, 1, 12, TEST_MODE_UL_AND_DL,
- 14, "algorithm B class 1-12 (UL and DL)");
+ 31, "algorithm B class 1-12 (UL and DL)");
test_successive_allocation(alloc_algorithm_b, 1, 29, TEST_MODE_UL_AND_DL,
- 18, "algorithm B class 1-29 (UL and DL)");
+ 24, "algorithm B class 1-29 (UL and DL)");
test_successive_allocation(alloc_algorithm_a, 1, 1, TEST_MODE_DL_AND_UL,
32, "algorithm A (DL and UL)");
test_successive_allocation(alloc_algorithm_b, 10, 10, TEST_MODE_DL_AND_UL,
- 7, "algorithm B class 10 (DL and UL)");
+ 15, "algorithm B class 10 (DL and UL)");
test_successive_allocation(alloc_algorithm_a, 1, 1, TEST_MODE_DL_AFTER_UL,
32, "algorithm A (DL after UL)");
@@ -586,12 +586,12 @@ static void test_successive_allocation()
test_successive_allocation(alloc_algorithm_a, 1, 1, TEST_MODE_UL_AFTER_DL,
32, "algorithm A (UL after DL)");
test_successive_allocation(alloc_algorithm_b, 10, 10, TEST_MODE_UL_AFTER_DL,
- 7, "algorithm B class 10 (UL after DL)");
+ 32, "algorithm B class 10 (UL after DL)");
test_successive_allocation(alloc_algorithm_a, 1, 1, TEST_MODE_UL_ONLY,
32, "algorithm A (UL only)");
test_successive_allocation(alloc_algorithm_b, 10, 10, TEST_MODE_UL_ONLY,
- 7, "algorithm B class 10 (UL only)");
+ 32, "algorithm B class 10 (UL only)");
test_successive_allocation(alloc_algorithm_a, 1, 1, TEST_MODE_DL_ONLY,
32, "algorithm A (DL ONLY)");
diff --git a/tests/alloc/AllocTest.err b/tests/alloc/AllocTest.err
index 3f9fc832..58a57d2d 100644
--- a/tests/alloc/AllocTest.err
+++ b/tests/alloc/AllocTest.err
@@ -3,17 +3,17 @@ No TFI available.
No TFI available.
- Failed to allocate a TS, no USF available
No TFI available.
-No suitable uplink slots available
-No suitable uplink slots available
-No suitable uplink slots available
-No suitable uplink slots available
No TFI available.
-No suitable uplink slots available
+No USF available
+No USF available
+No USF available
+No TFI available.
+No USF available
+No TFI available.
+No TFI available.
No TFI available.
No TFI available.
No TFI available.
-No suitable uplink slots available
No TFI available.
-No suitable uplink slots available
No TFI available.
No TFI available.
diff --git a/tests/alloc/AllocTest.ok b/tests/alloc/AllocTest.ok
index 3602d8c0..4b6aad90 100644
--- a/tests/alloc/AllocTest.ok
+++ b/tests/alloc/AllocTest.ok
@@ -410,8 +410,6 @@ PDCH[5] is used for DL
PDCH[5] is control_ts for DL
PDCH[5] is first common for DL
PDCH[5] is used for UL
-PDCH[6] is used for UL
-PDCH[7] is used for UL
PDCH[5] is control_ts for UL
PDCH[5] is first common for UL
PDCH[5] is used for DL
@@ -421,8 +419,6 @@ PDCH[5] is control_ts for DL
PDCH[5] is first common for DL
Testing jolly example
PDCH[1] is used for UL
-PDCH[2] is used for UL
-PDCH[3] is used for UL
PDCH[1] is control_ts for UL
PDCH[1] is first common for UL
PDCH[1] is used for DL
@@ -445,8 +441,6 @@ PDCH[5] is used for DL
PDCH[5] is control_ts for DL
PDCH[5] is first common for DL
PDCH[5] is used for UL
-PDCH[6] is used for UL
-PDCH[7] is used for UL
PDCH[5] is control_ts for UL
PDCH[5] is first common for UL
PDCH[5] is used for DL
@@ -455,18 +449,15 @@ PDCH[7] is used for DL
PDCH[5] is control_ts for DL
PDCH[5] is first common for DL
Testing jolly example
-PDCH[1] is used for UL
PDCH[2] is used for UL
-PDCH[3] is used for UL
-PDCH[4] is used for UL
-PDCH[1] is control_ts for UL
-PDCH[1] is first common for UL
+PDCH[2] is control_ts for UL
+PDCH[2] is first common for UL
PDCH[1] is used for DL
PDCH[2] is used for DL
PDCH[3] is used for DL
PDCH[4] is used for DL
-PDCH[1] is control_ts for DL
-PDCH[1] is first common for DL
+PDCH[2] is control_ts for DL
+PDCH[2] is first common for DL
Going to test multislot assignment MS_CLASS=15
Testing UL then DL assignment.
PDCH[5] is used for UL
@@ -482,8 +473,6 @@ PDCH[5] is used for DL
PDCH[5] is control_ts for DL
PDCH[5] is first common for DL
PDCH[5] is used for UL
-PDCH[6] is used for UL
-PDCH[7] is used for UL
PDCH[5] is control_ts for UL
PDCH[5] is first common for UL
PDCH[5] is used for DL
@@ -492,18 +481,15 @@ PDCH[7] is used for DL
PDCH[5] is control_ts for DL
PDCH[5] is first common for DL
Testing jolly example
-PDCH[1] is used for UL
PDCH[2] is used for UL
-PDCH[3] is used for UL
-PDCH[4] is used for UL
-PDCH[1] is control_ts for UL
-PDCH[1] is first common for UL
+PDCH[2] is control_ts for UL
+PDCH[2] is first common for UL
PDCH[1] is used for DL
PDCH[2] is used for DL
PDCH[3] is used for DL
PDCH[4] is used for DL
-PDCH[1] is control_ts for DL
-PDCH[1] is first common for DL
+PDCH[2] is control_ts for DL
+PDCH[2] is first common for DL
Going to test multislot assignment MS_CLASS=16
Testing UL then DL assignment.
PDCH[5] is used for UL
@@ -519,8 +505,6 @@ PDCH[5] is used for DL
PDCH[5] is control_ts for DL
PDCH[5] is first common for DL
PDCH[5] is used for UL
-PDCH[6] is used for UL
-PDCH[7] is used for UL
PDCH[5] is control_ts for UL
PDCH[5] is first common for UL
PDCH[5] is used for DL
@@ -529,18 +513,15 @@ PDCH[7] is used for DL
PDCH[5] is control_ts for DL
PDCH[5] is first common for DL
Testing jolly example
-PDCH[1] is used for UL
PDCH[2] is used for UL
-PDCH[3] is used for UL
-PDCH[4] is used for UL
-PDCH[1] is control_ts for UL
-PDCH[1] is first common for UL
+PDCH[2] is control_ts for UL
+PDCH[2] is first common for UL
PDCH[1] is used for DL
PDCH[2] is used for DL
PDCH[3] is used for DL
PDCH[4] is used for DL
-PDCH[1] is control_ts for DL
-PDCH[1] is first common for DL
+PDCH[2] is control_ts for DL
+PDCH[2] is first common for DL
Going to test multislot assignment MS_CLASS=17
Testing UL then DL assignment.
PDCH[5] is used for UL
@@ -556,8 +537,6 @@ PDCH[5] is used for DL
PDCH[5] is control_ts for DL
PDCH[5] is first common for DL
PDCH[5] is used for UL
-PDCH[6] is used for UL
-PDCH[7] is used for UL
PDCH[5] is control_ts for UL
PDCH[5] is first common for UL
PDCH[5] is used for DL
@@ -566,18 +545,15 @@ PDCH[7] is used for DL
PDCH[5] is control_ts for DL
PDCH[5] is first common for DL
Testing jolly example
-PDCH[1] is used for UL
PDCH[2] is used for UL
-PDCH[3] is used for UL
-PDCH[4] is used for UL
-PDCH[1] is control_ts for UL
-PDCH[1] is first common for UL
+PDCH[2] is control_ts for UL
+PDCH[2] is first common for UL
PDCH[1] is used for DL
PDCH[2] is used for DL
PDCH[3] is used for DL
PDCH[4] is used for DL
-PDCH[1] is control_ts for DL
-PDCH[1] is first common for DL
+PDCH[2] is control_ts for DL
+PDCH[2] is first common for DL
Going to test multislot assignment MS_CLASS=18
Testing UL then DL assignment.
PDCH[5] is used for UL
@@ -593,8 +569,6 @@ PDCH[5] is used for DL
PDCH[5] is control_ts for DL
PDCH[5] is first common for DL
PDCH[5] is used for UL
-PDCH[6] is used for UL
-PDCH[7] is used for UL
PDCH[5] is control_ts for UL
PDCH[5] is first common for UL
PDCH[5] is used for DL
@@ -603,18 +577,15 @@ PDCH[7] is used for DL
PDCH[5] is control_ts for DL
PDCH[5] is first common for DL
Testing jolly example
-PDCH[1] is used for UL
PDCH[2] is used for UL
-PDCH[3] is used for UL
-PDCH[4] is used for UL
-PDCH[1] is control_ts for UL
-PDCH[1] is first common for UL
+PDCH[2] is control_ts for UL
+PDCH[2] is first common for UL
PDCH[1] is used for DL
PDCH[2] is used for DL
PDCH[3] is used for DL
PDCH[4] is used for DL
-PDCH[1] is control_ts for DL
-PDCH[1] is first common for DL
+PDCH[2] is control_ts for DL
+PDCH[2] is first common for DL
Going to test multislot assignment MS_CLASS=19
Testing UL then DL assignment.
PDCH[5] is used for UL
@@ -8653,58 +8624,128 @@ Going to test assignment with many TBF, algorithm A (UL and DL)
Successfully allocated 32 UL TBFs
Going to test assignment with many TBF, algorithm B class 10 (UL and DL)
TBF[0] class 10 reserves ...DDCD.
- TBF[1] class 10 reserves ...DDCD.
- TBF[2] class 10 reserves ...DDCD.
- TBF[3] class 10 reserves ...DDCD.
- TBF[4] class 10 reserves ...DDCD.
- TBF[5] class 10 reserves ...DDCD.
- TBF[6] class 10 reserves ...DDCD.
- Successfully allocated 7 UL TBFs
+ TBF[1] class 10 reserves .....DCD
+ TBF[2] class 10 reserves ...DCD..
+ TBF[3] class 10 reserves .....DDC
+ TBF[4] class 10 reserves ...DCD..
+ TBF[5] class 10 reserves .....DCD
+ TBF[6] class 10 reserves ...DDC..
+ TBF[7] class 10 reserves .....DDC
+ TBF[8] class 10 reserves ...DCD..
+ TBF[9] class 10 reserves .....DCD
+ TBF[10] class 10 reserves ...DDC..
+ TBF[11] class 10 reserves .....DDC
+ TBF[12] class 10 reserves ...DCD..
+ TBF[13] class 10 reserves .....DCD
+ TBF[14] class 10 reserves ...DDC..
+ TBF[15] class 10 reserves .....DDC
+ TBF[16] class 10 reserves ...DCD..
+ TBF[17] class 10 reserves .....DCD
+ TBF[18] class 10 reserves ...DDC..
+ TBF[19] class 10 reserves .....DDC
+ TBF[20] class 10 reserves ...DCD..
+ TBF[21] class 10 reserves .....DCD
+ TBF[22] class 10 reserves ...CD...
+ TBF[23] class 10 reserves .....DDC
+ TBF[24] class 10 reserves ...CD...
+ TBF[25] class 10 reserves ...CD...
+ TBF[26] class 10 reserves .....DCD
+ TBF[27] class 10 reserves ...CD...
+ TBF[28] class 10 reserves ....DCD.
+ TBF[29] class 10 reserves .....DDC
+ TBF[30] class 10 reserves ...CD...
+ TBF[31] class 10 reserves ...CD...
+ Successfully allocated 32 UL TBFs
Going to test assignment with many TBF, algorithm B class 12 (UL and DL)
TBF[0] class 12 reserves ...DDCD.
- TBF[1] class 12 reserves ...DDCD.
- TBF[2] class 12 reserves ...DDCD.
- TBF[3] class 12 reserves ...DDCD.
- TBF[4] class 12 reserves ...DDCD.
- TBF[5] class 12 reserves ...DDCD.
- TBF[6] class 12 reserves ...DDCD.
- Successfully allocated 7 UL TBFs
+ TBF[1] class 12 reserves .....DCD
+ TBF[2] class 12 reserves ...CD...
+ TBF[3] class 12 reserves .....DDC
+ TBF[4] class 12 reserves ...DC...
+ TBF[5] class 12 reserves .....DCD
+ TBF[6] class 12 reserves ...CD...
+ TBF[7] class 12 reserves .....DDC
+ TBF[8] class 12 reserves ...DC...
+ TBF[9] class 12 reserves .....DCD
+ TBF[10] class 12 reserves ...CD...
+ TBF[11] class 12 reserves .....DDC
+ TBF[12] class 12 reserves ...DC...
+ TBF[13] class 12 reserves .....DCD
+ TBF[14] class 12 reserves ...CD...
+ TBF[15] class 12 reserves .....DDC
+ TBF[16] class 12 reserves ...DC...
+ TBF[17] class 12 reserves .....DCD
+ TBF[18] class 12 reserves ...CD...
+ TBF[19] class 12 reserves .....DDC
+ TBF[20] class 12 reserves ...DC...
+ TBF[21] class 12 reserves .....DCD
+ TBF[22] class 12 reserves ...CD...
+ TBF[23] class 12 reserves .....DDC
+ TBF[24] class 12 reserves ...DC...
+ TBF[25] class 12 reserves .....DCD
+ TBF[26] class 12 reserves ...CD...
+ TBF[27] class 12 reserves .....DDC
+ TBF[28] class 12 reserves ...DC...
+ Successfully allocated 29 UL TBFs
Going to test assignment with many TBF, algorithm B class 1-12 (UL and DL)
TBF[0] class 1 reserves ...C....
- TBF[1] class 2 reserves ...DC...
- TBF[2] class 3 reserves ...DC...
+ TBF[1] class 2 reserves ....DC..
+ TBF[2] class 3 reserves ......DC
TBF[3] class 4 reserves ...DCD..
- TBF[4] class 5 reserves ...CD...
- TBF[5] class 6 reserves ...DCD..
- TBF[6] class 7 reserves ...DCD..
- TBF[7] class 8 reserves ...DDCD.
+ TBF[4] class 5 reserves ......CD
+ TBF[5] class 6 reserves ...CD...
+ TBF[6] class 7 reserves .....CD.
+ TBF[7] class 8 reserves ....DDCD
TBF[8] class 9 reserves ...DCD..
- TBF[9] class 10 reserves ...DDCD.
- TBF[10] class 11 reserves ...DDCD.
- TBF[11] class 12 reserves ...DDCD.
- TBF[12] class 1 reserves ...C....
- TBF[13] class 2 reserves ...DC...
- Successfully allocated 14 UL TBFs
+ TBF[9] class 10 reserves .....DDC
+ TBF[10] class 11 reserves ...CD...
+ TBF[11] class 12 reserves ...C....
+ TBF[12] class 1 reserves .......C
+ TBF[13] class 2 reserves ......DC
+ TBF[14] class 3 reserves ...C....
+ TBF[15] class 4 reserves ....DCD.
+ TBF[16] class 5 reserves ......CD
+ TBF[17] class 6 reserves ...DC...
+ TBF[18] class 7 reserves .....C..
+ TBF[19] class 8 reserves ....DDCD
+ TBF[20] class 9 reserves .....DCD
+ TBF[21] class 10 reserves ...DCD..
+ TBF[22] class 11 reserves ...DC...
+ TBF[23] class 12 reserves ...C....
+ TBF[24] class 1 reserves .......C
+ TBF[25] class 2 reserves ......DC
+ TBF[26] class 3 reserves ...C....
+ TBF[27] class 4 reserves ....DCD.
+ TBF[28] class 5 reserves ......CD
+ TBF[29] class 6 reserves ...DC...
+ TBF[30] class 7 reserves ......C.
+ Successfully allocated 31 UL TBFs
Going to test assignment with many TBF, algorithm B class 1-29 (UL and DL)
TBF[0] class 1 reserves ...C....
- TBF[1] class 2 reserves ...DC...
- TBF[2] class 3 reserves ...DC...
+ TBF[1] class 2 reserves ....DC..
+ TBF[2] class 3 reserves ......DC
TBF[3] class 4 reserves ...DCD..
- TBF[4] class 5 reserves ...CD...
- TBF[5] class 6 reserves ...DCD..
- TBF[6] class 7 reserves ...DCD..
- TBF[7] class 8 reserves ...DDCD.
+ TBF[4] class 5 reserves ......CD
+ TBF[5] class 6 reserves ...CD...
+ TBF[6] class 7 reserves .....CD.
+ TBF[7] class 8 reserves ....DDCD
TBF[8] class 9 reserves ...DCD..
- TBF[9] class 10 reserves ...DDCD.
- TBF[10] class 11 reserves ...DDCD.
- TBF[11] class 12 reserves ...DDCD.
- TBF[12] class 13 reserves ...CDD..
- TBF[13] class 14 reserves ...CDDD.
- TBF[14] class 15 reserves ...CDDDD
- TBF[15] class 16 reserves ...CDDDD
- TBF[16] class 17 reserves ...CDDDD
- TBF[17] class 18 reserves ...DDDCD
- Successfully allocated 18 UL TBFs
+ TBF[9] class 10 reserves .....DDC
+ TBF[10] class 11 reserves ...CD...
+ TBF[11] class 12 reserves ...C....
+ TBF[12] class 13 reserves .....CDD
+ TBF[13] class 14 reserves ....DDCD
+ TBF[14] class 15 reserves ...DCD..
+ TBF[15] class 16 reserves ...DCD..
+ TBF[16] class 17 reserves ...DDDDC
+ TBF[17] class 18 reserves ...DDC..
+ TBF[18] class 19 reserves ...DDCDD
+ TBF[19] class 20 reserves ...DDCDD
+ TBF[20] class 21 reserves ....CD..
+ TBF[21] class 22 reserves .....DC.
+ TBF[22] class 23 reserves ...C....
+ TBF[23] class 24 reserves ...DDCDD
+ Successfully allocated 24 UL TBFs
Going to test assignment with many TBF, algorithm A (DL and UL)
TBF[0] class 1 reserves ...C....
TBF[1] class 1 reserves ....C...
@@ -8741,13 +8782,21 @@ Going to test assignment with many TBF, algorithm A (DL and UL)
Successfully allocated 32 UL TBFs
Going to test assignment with many TBF, algorithm B class 10 (DL and UL)
TBF[0] class 10 reserves ...DDCD.
- TBF[1] class 10 reserves ...DDCD.
- TBF[2] class 10 reserves ...DDCD.
- TBF[3] class 10 reserves ...DDCD.
- TBF[4] class 10 reserves ...DDCD.
- TBF[5] class 10 reserves ...DDCD.
- TBF[6] class 10 reserves ...DDCD.
- Successfully allocated 7 UL TBFs
+ TBF[1] class 10 reserves .....DCD
+ TBF[2] class 10 reserves ...DCD..
+ TBF[3] class 10 reserves .....DCD
+ TBF[4] class 10 reserves ...DCD..
+ TBF[5] class 10 reserves .....DCD
+ TBF[6] class 10 reserves ...DCD..
+ TBF[7] class 10 reserves .....DCD
+ TBF[8] class 10 reserves ...DCD..
+ TBF[9] class 10 reserves .....DCD
+ TBF[10] class 10 reserves ...DCD..
+ TBF[11] class 10 reserves .....DCD
+ TBF[12] class 10 reserves ...DCD..
+ TBF[13] class 10 reserves .....DCD
+ TBF[14] class 10 reserves ...DCD..
+ Successfully allocated 15 UL TBFs
Going to test assignment with many TBF, algorithm A (DL after UL)
TBF[0] class 1 reserves ...C....
TBF[1] class 1 reserves ....C...
@@ -8784,37 +8833,37 @@ Going to test assignment with many TBF, algorithm A (DL after UL)
Successfully allocated 32 UL TBFs
Going to test assignment with many TBF, algorithm B class 10 (DL after UL)
TBF[0] class 10 reserves ...DDCD.
- TBF[1] class 10 reserves ...DDCD.
- TBF[2] class 10 reserves ...DDCD.
- TBF[3] class 10 reserves ...DDCD.
- TBF[4] class 10 reserves ...DDCD.
- TBF[5] class 10 reserves ...DDCD.
- TBF[6] class 10 reserves ...DDCD.
- TBF[7] class 10 reserves ...DDCD.
- TBF[8] class 10 reserves ...DDCD.
- TBF[9] class 10 reserves ...DDCD.
- TBF[10] class 10 reserves ...DDCD.
- TBF[11] class 10 reserves ...DDCD.
- TBF[12] class 10 reserves ...DDCD.
- TBF[13] class 10 reserves ...DDCD.
- TBF[14] class 10 reserves ...DDCD.
- TBF[15] class 10 reserves ...DDCD.
- TBF[16] class 10 reserves ...DDCD.
- TBF[17] class 10 reserves ...DDCD.
- TBF[18] class 10 reserves ...DDCD.
- TBF[19] class 10 reserves ...DDCD.
- TBF[20] class 10 reserves ...DDCD.
- TBF[21] class 10 reserves ...DDCD.
- TBF[22] class 10 reserves ...DDCD.
- TBF[23] class 10 reserves ...DDCD.
- TBF[24] class 10 reserves ...DDCD.
- TBF[25] class 10 reserves ...DDCD.
- TBF[26] class 10 reserves ...DDCD.
- TBF[27] class 10 reserves ...DDCD.
- TBF[28] class 10 reserves ...DDCD.
- TBF[29] class 10 reserves ...DDCD.
- TBF[30] class 10 reserves ...DDCD.
- TBF[31] class 10 reserves ...DDCD.
+ TBF[1] class 10 reserves .....DCD
+ TBF[2] class 10 reserves ...DCD..
+ TBF[3] class 10 reserves .....DCD
+ TBF[4] class 10 reserves ...DCD..
+ TBF[5] class 10 reserves .....DCD
+ TBF[6] class 10 reserves ...DCD..
+ TBF[7] class 10 reserves .....DCD
+ TBF[8] class 10 reserves ...DCD..
+ TBF[9] class 10 reserves .....DCD
+ TBF[10] class 10 reserves ...DCD..
+ TBF[11] class 10 reserves .....DCD
+ TBF[12] class 10 reserves ...DCD..
+ TBF[13] class 10 reserves .....DCD
+ TBF[14] class 10 reserves ...DCD..
+ TBF[15] class 10 reserves .....DCD
+ TBF[16] class 10 reserves ...DCD..
+ TBF[17] class 10 reserves .....DCD
+ TBF[18] class 10 reserves ...DCD..
+ TBF[19] class 10 reserves .....DCD
+ TBF[20] class 10 reserves ...DCD..
+ TBF[21] class 10 reserves .....DCD
+ TBF[22] class 10 reserves ...CD...
+ TBF[23] class 10 reserves .....DCD
+ TBF[24] class 10 reserves ...CD...
+ TBF[25] class 10 reserves ...CD...
+ TBF[26] class 10 reserves .....DCD
+ TBF[27] class 10 reserves ...CD...
+ TBF[28] class 10 reserves ....DCD.
+ TBF[29] class 10 reserves .....DCD
+ TBF[30] class 10 reserves ...CD...
+ TBF[31] class 10 reserves ...CD...
Successfully allocated 32 UL TBFs
Going to test assignment with many TBF, algorithm A (UL after DL)
TBF[0] class 1 reserves ...U....
@@ -8852,13 +8901,38 @@ Going to test assignment with many TBF, algorithm A (UL after DL)
Successfully allocated 32 UL TBFs
Going to test assignment with many TBF, algorithm B class 10 (UL after DL)
TBF[0] class 10 reserves .....U..
- TBF[1] class 10 reserves .....U..
- TBF[2] class 10 reserves .....U..
- TBF[3] class 10 reserves .....U..
- TBF[4] class 10 reserves .....U..
- TBF[5] class 10 reserves .....U..
+ TBF[1] class 10 reserves ......U.
+ TBF[2] class 10 reserves ....U...
+ TBF[3] class 10 reserves .......U
+ TBF[4] class 10 reserves ....U...
+ TBF[5] class 10 reserves ......U.
TBF[6] class 10 reserves .....U..
- Successfully allocated 7 UL TBFs
+ TBF[7] class 10 reserves .......U
+ TBF[8] class 10 reserves ....U...
+ TBF[9] class 10 reserves ......U.
+ TBF[10] class 10 reserves .....U..
+ TBF[11] class 10 reserves .......U
+ TBF[12] class 10 reserves ....U...
+ TBF[13] class 10 reserves ......U.
+ TBF[14] class 10 reserves .....U..
+ TBF[15] class 10 reserves .......U
+ TBF[16] class 10 reserves ....U...
+ TBF[17] class 10 reserves ......U.
+ TBF[18] class 10 reserves .....U..
+ TBF[19] class 10 reserves .......U
+ TBF[20] class 10 reserves ....U...
+ TBF[21] class 10 reserves ......U.
+ TBF[22] class 10 reserves ...U....
+ TBF[23] class 10 reserves .......U
+ TBF[24] class 10 reserves ...U....
+ TBF[25] class 10 reserves ...U....
+ TBF[26] class 10 reserves ......U.
+ TBF[27] class 10 reserves ...U....
+ TBF[28] class 10 reserves .....U..
+ TBF[29] class 10 reserves .......U
+ TBF[30] class 10 reserves ...U....
+ TBF[31] class 10 reserves ...U....
+ Successfully allocated 32 UL TBFs
Going to test assignment with many TBF, algorithm A (UL only)
TBF[0] class 1 reserves ...U....
TBF[1] class 1 reserves ....U...
@@ -8895,13 +8969,38 @@ Going to test assignment with many TBF, algorithm A (UL only)
Successfully allocated 32 UL TBFs
Going to test assignment with many TBF, algorithm B class 10 (UL only)
TBF[0] class 10 reserves .....U..
- TBF[1] class 10 reserves .....U..
- TBF[2] class 10 reserves .....U..
- TBF[3] class 10 reserves .....U..
- TBF[4] class 10 reserves .....U..
- TBF[5] class 10 reserves .....U..
+ TBF[1] class 10 reserves ......U.
+ TBF[2] class 10 reserves ....U...
+ TBF[3] class 10 reserves .......U
+ TBF[4] class 10 reserves ....U...
+ TBF[5] class 10 reserves ......U.
TBF[6] class 10 reserves .....U..
- Successfully allocated 7 UL TBFs
+ TBF[7] class 10 reserves .......U
+ TBF[8] class 10 reserves ....U...
+ TBF[9] class 10 reserves ......U.
+ TBF[10] class 10 reserves .....U..
+ TBF[11] class 10 reserves .......U
+ TBF[12] class 10 reserves ....U...
+ TBF[13] class 10 reserves ......U.
+ TBF[14] class 10 reserves .....U..
+ TBF[15] class 10 reserves .......U
+ TBF[16] class 10 reserves ....U...
+ TBF[17] class 10 reserves ......U.
+ TBF[18] class 10 reserves .....U..
+ TBF[19] class 10 reserves .......U
+ TBF[20] class 10 reserves ....U...
+ TBF[21] class 10 reserves ......U.
+ TBF[22] class 10 reserves ...U....
+ TBF[23] class 10 reserves .......U
+ TBF[24] class 10 reserves ...U....
+ TBF[25] class 10 reserves ...U....
+ TBF[26] class 10 reserves ......U.
+ TBF[27] class 10 reserves ...U....
+ TBF[28] class 10 reserves .....U..
+ TBF[29] class 10 reserves .......U
+ TBF[30] class 10 reserves ...U....
+ TBF[31] class 10 reserves ...U....
+ Successfully allocated 32 UL TBFs
Going to test assignment with many TBF, algorithm A (DL ONLY)
TBF[0] class 1 reserves ...C....
TBF[1] class 1 reserves ....C...
@@ -8938,35 +9037,35 @@ Going to test assignment with many TBF, algorithm A (DL ONLY)
Successfully allocated 32 UL TBFs
Going to test assignment with many TBF, algorithm B class 10 (DL ONLY)
TBF[0] class 10 reserves ...DDCD.
- TBF[1] class 10 reserves ...DDCD.
- TBF[2] class 10 reserves ...DDCD.
- TBF[3] class 10 reserves ...DDCD.
- TBF[4] class 10 reserves ...DDCD.
- TBF[5] class 10 reserves ...DDCD.
- TBF[6] class 10 reserves ...DDCD.
- TBF[7] class 10 reserves ...DDCD.
- TBF[8] class 10 reserves ...DDCD.
- TBF[9] class 10 reserves ...DDCD.
- TBF[10] class 10 reserves ...DDCD.
- TBF[11] class 10 reserves ...DDCD.
- TBF[12] class 10 reserves ...DDCD.
- TBF[13] class 10 reserves ...DDCD.
- TBF[14] class 10 reserves ...DDCD.
- TBF[15] class 10 reserves ...DDCD.
- TBF[16] class 10 reserves ...DDCD.
- TBF[17] class 10 reserves ...DDCD.
- TBF[18] class 10 reserves ...DDCD.
- TBF[19] class 10 reserves ...DDCD.
- TBF[20] class 10 reserves ...DDCD.
- TBF[21] class 10 reserves ...DDCD.
- TBF[22] class 10 reserves ...DDCD.
- TBF[23] class 10 reserves ...DDCD.
- TBF[24] class 10 reserves ...DDCD.
- TBF[25] class 10 reserves ...DDCD.
- TBF[26] class 10 reserves ...DDCD.
- TBF[27] class 10 reserves ...DDCD.
- TBF[28] class 10 reserves ...DDCD.
- TBF[29] class 10 reserves ...DDCD.
- TBF[30] class 10 reserves ...DDCD.
- TBF[31] class 10 reserves ...DDCD.
+ TBF[1] class 10 reserves .....DCD
+ TBF[2] class 10 reserves ...DCD..
+ TBF[3] class 10 reserves .....DCD
+ TBF[4] class 10 reserves ...DCD..
+ TBF[5] class 10 reserves .....DCD
+ TBF[6] class 10 reserves ...DCD..
+ TBF[7] class 10 reserves .....DCD
+ TBF[8] class 10 reserves ...DCD..
+ TBF[9] class 10 reserves .....DCD
+ TBF[10] class 10 reserves ...DCD..
+ TBF[11] class 10 reserves .....DCD
+ TBF[12] class 10 reserves ...DCD..
+ TBF[13] class 10 reserves .....DCD
+ TBF[14] class 10 reserves ...DCD..
+ TBF[15] class 10 reserves .....DCD
+ TBF[16] class 10 reserves ...DCD..
+ TBF[17] class 10 reserves .....DCD
+ TBF[18] class 10 reserves ...DCD..
+ TBF[19] class 10 reserves .....DCD
+ TBF[20] class 10 reserves ...DCD..
+ TBF[21] class 10 reserves .....DCD
+ TBF[22] class 10 reserves ...CD...
+ TBF[23] class 10 reserves .....DCD
+ TBF[24] class 10 reserves ...CD...
+ TBF[25] class 10 reserves ...CD...
+ TBF[26] class 10 reserves .....DCD
+ TBF[27] class 10 reserves ...CD...
+ TBF[28] class 10 reserves ....DCD.
+ TBF[29] class 10 reserves .....DCD
+ TBF[30] class 10 reserves ...CD...
+ TBF[31] class 10 reserves ...CD...
Successfully allocated 32 UL TBFs