Hello Jenkins Builder,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/3935

to look at the new patch set (#5).

Simplify TS alloc: move slot check into functions

Move timeslot applicability check outside of nested for loop into
separate functions and document them.

This allows us to clarify types used in TS-related computations.

Change-Id: Ic39e848da47dc11357782362fdf6206d2c1457c2
Related: OS#2282
---
M src/gprs_rlcmac_ts_alloc.cpp
1 file changed, 97 insertions(+), 112 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/35/3935/5

diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp
index 5fba5cc..4c96e9a 100644
--- a/src/gprs_rlcmac_ts_alloc.cpp
+++ b/src/gprs_rlcmac_ts_alloc.cpp
@@ -94,11 +94,11 @@
        return -1;
 }
 
-static int find_possible_pdchs(const struct gprs_rlcmac_trx *trx, size_t 
max_slots, uint8_t mask,
-                              const char *mask_reason = NULL)
+static uint8_t find_possible_pdchs(const struct gprs_rlcmac_trx *trx, uint8_t 
max_slots, uint8_t mask,
+                                  const char *mask_reason = NULL)
 {
        unsigned ts;
-       int valid_ts_set = 0;
+       uint8_t valid_ts_set = 0;
        int8_t last_tsc = -1; /* must be signed */
 
        for (ts = 0; ts < ARRAY_SIZE(trx->pdch); ts++) {
@@ -385,7 +385,7 @@
        int trx_no;
        int tfi = -1;
        int usf = -1;
-       int mask = 0xff;
+       uint8_t mask = 0xff;
        const char *mask_reason = NULL;
        const GprsMs *ms = ms_;
        const gprs_rlcmac_tbf *tbf = tbf_;
@@ -469,7 +469,7 @@
  *  \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)
+static inline unsigned compute_capacity(const struct gprs_rlcmac_trx *trx, 
int16_t rx_window, int16_t tx_window)
 {
        const struct gprs_rlcmac_pdch *pdch;
        unsigned ts, capacity = 0;
@@ -489,6 +489,85 @@
        return capacity;
 }
 
+/*! Decide if a given slot should be skipped by multislot allocator
+ *
+ *  \param[in] ms_class Pointer to MS Class object
+ *  \param[in] check_tr Flag indicating whether we should check for Tra or Tta 
parameters for a given MS class
+ *  \param[in] rx_window Receive window
+ *  \param[in] rx_slot_count Number of TS in RX
+ *  \param[in] tx_window Transmit window
+ *  \param[in] tx_slot_count Number of TS in TX
+ *  \param[in,out] checked_rx array with already checked RX timeslots
+ *  \returns true if the slot should be skipped, false otherwise
+ */
+static bool skip_slot(uint8_t mslot_class, bool check_tr,
+                     int16_t rx_window,uint8_t rx_slot_count,
+                     int16_t tx_window, uint8_t tx_slot_count, uint32_t 
*checked_rx)
+{
+       uint8_t common_slot_count, req_common_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 check_tr. Therefore this check must be done
+        * before doing the test_and_set_bit shortcut. */
+       if (mslot_class_get_type(mslot_class) == 1) {
+               uint16_t 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 (!check_tr)
+                               return true; /* Skip Tta */
+               } else if (slot_sum > 6 && tx_slot_count < 3) {
+                       if (check_tr)
+                               return true; /* Skip Tra */
+               } else
+                       return true; /* No supported row in TS 45.002, table 
6.4.2.2.1. */
+       }
+
+       /* Avoid repeated RX combination check */
+       if (test_and_set_bit(checked_rx, 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 (mslot_class_get_type(mslot_class) == 1)
+               req_common_slots = OSMO_MIN(req_common_slots, 2);
+
+       if (req_common_slots != common_slot_count)
+               return true;
+
+       return false;
+}
+
+/*! Filter out bad slots
+ *
+ *  \param[in] mask TS selection mask
+ *  \param[in] ul_slots set of UL timeslots
+ *  \param[in] dl_slots set of DL timeslots
+ *  \param[in] rx_valid_win Mask for valid RX window value
+ *  \returns negative error code or RX window on success
+ */
+static int16_t filter_bad_slots(uint8_t mask, uint8_t ul_slots, uint8_t 
dl_slots, uint16_t rx_valid_win)
+{
+       uint8_t rx_good;
+       uint16_t rx_bad = (uint16_t)(0xff & ~mask) << ul_slots;
+
+       /* TODO: CHECK this calculation -> separate function for unit testing */
+       rx_bad = (rx_bad | (rx_bad >> 8)) & 0xff;
+       rx_good = dl_slots & ~rx_bad;
+       if (!rx_good)
+               return -1;
+
+       return rx_good & rx_valid_win;
+}
+
+static inline uint16_t wrap_window(uint16_t win)
+{
+       return (win | win >> 8) & 0xFF;
+}
+
 /*! Find set of slots available for allocation while taking MS class into 
account
  *
  *  \param[in] trx Pointer to TRX object
@@ -502,18 +581,14 @@
        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;
+       uint8_t max_slots, num_tx, mask_sel, pdch_slots, ul_ts, dl_ts;
+       int16_t rx_window, tx_window;
        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;
-
-       unsigned ul_ts, dl_ts;
-       unsigned num_tx;
        enum {MASK_TT, MASK_TR};
-       unsigned mask_sel;
 
        if (mslot_class)
                LOGP(DRLCMAC, LOGL_DEBUG, "Slot Allocation (Algorithm B) for 
class %d\n",
@@ -587,13 +662,12 @@
 
        /* 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;
+               uint8_t tx_slot_count;
                uint16_t rx_valid_win;
                uint32_t checked_rx[256/32] = {0};
 
                /* Wrap valid window */
-               tx_valid_win = (tx_valid_win | tx_valid_win >> 8) & 0xff;
+               tx_valid_win = wrap_window(tx_valid_win);
 
                tx_window = tx_valid_win;
 
@@ -610,8 +684,7 @@
 
                tx_slot_count = pcu_bitcount(tx_window);
 
-               max_rx = OSMO_MIN(mslot_class_get_rx(mslot_class), Sum - 
num_tx);
-               rx_valid_win = (1 << max_rx) - 1;
+               rx_valid_win = (1 << OSMO_MIN(mslot_class_get_rx(mslot_class), 
Sum - num_tx)) - 1;
 
        /* Rotate group of RX slots: DDD-----, -DDD----, ..., DD-----D */
        for (dl_ts = 0; dl_ts < 8; dl_ts += 1, rx_valid_win <<= 1) {
@@ -620,107 +693,19 @@
 
        /* 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;
+               uint8_t rx_slot_count;
                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;
+               rx_window = filter_bad_slots(rx_mask[mask_sel], ul_ts, 
*dl_slots, rx_valid_win);
+               if (rx_window < 0)
+                       continue;
 
-               /* TODO: CHECK this calculation -> separate function for unit
-                * testing */
-
-               rx_window = rx_good & rx_valid_win;
                rx_slot_count = pcu_bitcount(rx_window);
 
-#if 0
-               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);
-#endif
-
-               /* 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 (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 table 6.4.2.2.1. */
-#ifdef ENABLE_TS_ALLOC_DEBUG
-                               LOGP(DRLCMAC, LOGL_DEBUG,
-                                       "- Skipping DL/UL slots: 
(TS=0)\"%s\"(TS=7), "
-                                       "combination not supported\n",
-                                       
set_flag_chars(set_flag_chars(set_flag_chars(
-                                                               slot_info,
-                                                               rx_bad, 'x', 
'.'),
-                                                       rx_window, 'D'),
-                                               tx_window, 'U'));
-#endif
-                               continue;
-                       }
-               }
-
-               /* Avoid repeated RX combination check */
-               if (test_and_set_bit(checked_rx, rx_window))
-                       continue;
-
-               if (!rx_good) {
-#ifdef ENABLE_TS_ALLOC_DEBUG
-                       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'));
-#endif
-                       continue;
-               }
-
-               if (!rx_window)
-                       continue;
-
-               /* Check number of common slots according to TS 54.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 (Type == 1)
-                       req_common_slots = OSMO_MIN(req_common_slots, 2);
-
-               if (req_common_slots != common_slot_count) {
-#ifdef ENABLE_TS_ALLOC_DEBUG
-                       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);
-#endif
-                       continue;
-               }
+               if (skip_slot(mslot_class, mask_sel != MASK_TT,
+                             rx_window, rx_slot_count,
+                             tx_window, tx_slot_count, checked_rx))
+                       continue;
 
                /* Compute capacity */
                capacity = compute_capacity(trx, rx_window, tx_window);

-- 
To view, visit https://gerrit.osmocom.org/3935
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: Ic39e848da47dc11357782362fdf6206d2c1457c2
Gerrit-PatchSet: 5
Gerrit-Project: osmo-pcu
Gerrit-Branch: master
Gerrit-Owner: Max <msur...@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder

Reply via email to