diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2015-06-22 16:14:23 +0200 |
---|---|---|
committer | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2015-06-22 16:14:23 +0200 |
commit | 73d8bc51ce70d8c3a26c7a0c3b3c41d02d33a2db (patch) | |
tree | 1fc7cd7cc0c1134a8fc9399889113d066423c350 | |
parent | e56f9a9a22552a762ac8449a81d6ced3339347f7 (diff) |
WIP Algorithm B UL (TODO)
Select UL slot based on slot usage (similar to algorithm A)
-rw-r--r-- | src/gprs_rlcmac_ts_alloc.cpp | 172 |
1 files changed, 109 insertions, 63 deletions
diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index 7da07673..1e0f539b 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -101,11 +101,12 @@ static inline int8_t find_free_usf(struct gprs_rlcmac_pdch *pdch) } static int find_possible_pdchs(struct gprs_rlcmac_trx *trx, - enum gprs_rlcmac_tbf_direction dir, + enum gprs_rlcmac_tbf_direction dir, size_t max_slots, uint8_t mask, const char *mask_reason) { unsigned ts; int valid_ts_set = 0; + int8_t last_tsc = -1; /* must be signed */ for (ts = 0; ts < ARRAY_SIZE(trx->pdch); ts++) { struct gprs_rlcmac_pdch *pdch; @@ -125,12 +126,53 @@ static int find_possible_pdchs(struct gprs_rlcmac_trx *trx, continue; } + if (max_slots > 1) { + /* 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, trx->trx_no); + continue; + } + } + valid_ts_set |= 1 << ts; } return valid_ts_set; } +static uint8_t filter_ts(uint8_t current, uint8_t mask, const char *mask_reason) +{ + unsigned ts; + uint8_t result; + uint8_t invalid; + + result = current & mask; + + if (result == current || !mask_reason) + return result; + + invalid = current & ~result; + + for (ts = 0; ts < 8; ts++) { + if (((1 << ts) & invalid) == 0) + continue; + + if (mask_reason) + LOGP(DRLCMAC, LOGL_DEBUG, + "- Skipping TS %d, because %s\n", + ts, mask_reason); + } + + return result; +} + static int find_least_busy_pdch(struct gprs_rlcmac_trx *trx, enum gprs_rlcmac_tbf_direction dir, uint8_t mask, @@ -326,7 +368,7 @@ int alloc_algorithm_a(struct gprs_rlcmac_bts *bts, mask_reason = "need to reuse TS"; else if ((ref_tbf = ms->tbf(reverse(tbf->direction)))) mask_reason = ref_tbf->direction == GPRS_RLCMAC_UL_TBF ? - "not an uplink TBF" : "not a downlink TBF"; + "not an uplink slot" : "not a downlink slot"; if (ref_tbf) ts = ref_tbf->first_common_ts; @@ -334,7 +376,7 @@ int alloc_algorithm_a(struct gprs_rlcmac_bts *bts, if (ts >= 0) mask = 1 << ts; - mask = find_possible_pdchs(tbf->trx, tbf->direction, mask, mask_reason); + mask = find_possible_pdchs(tbf->trx, tbf->direction, 1, mask, mask_reason); if (!mask) return -EINVAL; @@ -597,76 +639,80 @@ static void tx_win_from_rx(const int ms_type, * slots. */ static int select_ul_slots(gprs_rlcmac_trx *trx, - const int ms_type, const int ms_max_txslots, + const int ms_type, 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; + int ts; + uint16_t mask; + int first_ts; + int first_usf; - 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]; + mask = ((1 << tx_range) - 1) << tx_win_min; + tx_window = mask | (mask >> 8); /* wrap upper byte */ - /* 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; - 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; - 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; - 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; - continue; - } + tx_window = find_possible_pdchs(trx, GPRS_RLCMAC_UL_TBF, ms_max_txslots, + tx_window, NULL); - if (!tx_window) - *first_common_ts = ts_no; + tx_window = filter_ts(tx_window, rx_window, "not a downlink slot"); - tx_window |= (1 << ts_no); - LOGP(DRLCMAC, LOGL_DEBUG, "- Selected UL TS %d\n", ts_no); + if (ms_type == 1) { + ms_max_txslots = 1; + first_ts = find_least_busy_pdch(trx, GPRS_RLCMAC_UL_TBF, + tx_window, &first_usf); -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; + LOGP(DRLCMAC, LOGL_DEBUG, "- Selected UL TS %d\n", first_ts); + + tx_window = 1 << first_ts; + usf[first_ts] = first_usf; + *first_common_ts = first_ts; + + /* FIXME: multislot UL assignment */ + LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because 1 slot assigned\n"); + } else { + bool found = false; + mask = 0; + for (ts = tx_win_min; ts < tx_win_min + tx_range; ts++) { + gprs_rlcmac_pdch *pdch = &trx->pdch[ts]; + bool ts_valid = tx_window & (1 << (ts % 8)); + + usf[ts] = -1; + + if (!found && !ts_valid) + continue; + + if (ts_valid) { + /* check for free usf */ + usf[ts] = find_free_usf(pdch); + if (usf[ts] < 0) { + LOGP(DRLCMAC, LOGL_DEBUG, + "- Skipping TS %d, " + "because no USF available\n", ts); + continue; + } + + if (!found) + *first_common_ts = ts; + + found = true; + LOGP(DRLCMAC, LOGL_DEBUG, + "- Selected UL TS %d\n", ts); + mask |= 1 << ts; + } + + ms_max_txslots -= 1; + if (ms_max_txslots == 0) { + LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because " + "slots / window reached maximum " + "allowed Tx size\n"); + break; + } + + /* see 45.002, 6.4.2.2.1, note 0 */ } + + tx_window = mask; } LOGP(DRLCMAC, LOGL_DEBUG, "- Selected TX window: " |