<p>neels has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bsc/+/21978">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">hodec2: cosmetic: clarify afs_bias, simplify pick_better_lchan_to_move()<br><br>Instead of passing the TCH/H -> TCH/F bias (AFS bias) in local<br>variables, rather store it in the ho_candidate struct next to the other<br>rxlev related values.<br><br>Add the AFS bias to the compared rxlev in pick_better_lchan_to_move().<br><br>Modify pick_better_lchan_to_move() to simpler semantics of returning<br>either a or b.<br><br>No functional change.<br><br>Change-Id: I73860abdf2a77270ca4851ad58c09767d1bb08f1<br>---<br>M src/osmo-bsc/handover_decision_2.c<br>1 file changed, 36 insertions(+), 50 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/78/21978/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/osmo-bsc/handover_decision_2.c b/src/osmo-bsc/handover_decision_2.c</span><br><span>index ae9435f..eb72e11 100644</span><br><span>--- a/src/osmo-bsc/handover_decision_2.c</span><br><span>+++ b/src/osmo-bsc/handover_decision_2.c</span><br><span>@@ -106,6 +106,7 @@</span><br><span>   uint8_t requirements;           /* what is fulfilled */</span><br><span>      int rxlev_current;</span><br><span>   int rxlev_target;</span><br><span style="color: hsl(120, 100%, 40%);">+     int rxlev_afs_bias;</span><br><span> };</span><br><span> </span><br><span> enum ho_reason {</span><br><span>@@ -1398,63 +1399,55 @@</span><br><span> /* Given two candidates, pick the one that should rather be moved during handover.</span><br><span>  * Return the better candidate in out-parameters best_cand and best_avg_db.</span><br><span>  */</span><br><span style="color: hsl(0, 100%, 40%);">-static bool pick_better_lchan_to_move(bool want_highest_db,</span><br><span style="color: hsl(0, 100%, 40%);">-                                    struct ho_candidate **best_cand_p, unsigned int *best_avg_db_p,</span><br><span style="color: hsl(0, 100%, 40%);">-                                 struct ho_candidate *other_cand, unsigned int other_avg_db)</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ho_candidate *pick_better_lchan_to_move(bool want_highest_db,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                      struct ho_candidate *a,</span><br><span style="color: hsl(120, 100%, 40%);">+                                               struct ho_candidate *b)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      if (!*best_cand_p)</span><br><span style="color: hsl(0, 100%, 40%);">-              goto return_other;</span><br><span style="color: hsl(120, 100%, 40%);">+    int a_rxlev;</span><br><span style="color: hsl(120, 100%, 40%);">+  int b_rxlev;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        if (want_highest_db && (*best_avg_db_p < other_avg_db))</span><br><span style="color: hsl(0, 100%, 40%);">-              goto return_other;</span><br><span style="color: hsl(0, 100%, 40%);">-      if (!want_highest_db && (*best_avg_db_p > other_avg_db))</span><br><span style="color: hsl(0, 100%, 40%);">-             goto return_other;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!a)</span><br><span style="color: hsl(120, 100%, 40%);">+               return b;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!b)</span><br><span style="color: hsl(120, 100%, 40%);">+               return a;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   a_rxlev = a->rxlev_target + a->rxlev_afs_bias;</span><br><span style="color: hsl(120, 100%, 40%);">+  b_rxlev = b->rxlev_target + b->rxlev_afs_bias;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (want_highest_db && a_rxlev < b_rxlev)</span><br><span style="color: hsl(120, 100%, 40%);">+          return b;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!want_highest_db && a_rxlev > b_rxlev)</span><br><span style="color: hsl(120, 100%, 40%);">+         return b;</span><br><span> </span><br><span>        /* The two lchans have identical ratings, prefer picking a dynamic timeslot: free PDCH and allow more timeslot</span><br><span>        * type flexibility for further congestion resolution. */</span><br><span style="color: hsl(0, 100%, 40%);">-       if (lchan_is_on_dynamic_ts(other_cand->lchan)) {</span><br><span style="color: hsl(120, 100%, 40%);">+   if (lchan_is_on_dynamic_ts(b->lchan)) {</span><br><span>           /* If both are dynamic, prefer one that completely (or to a higher degree) frees its timeslot. */</span><br><span style="color: hsl(0, 100%, 40%);">-               if (lchan_is_on_dynamic_ts((*best_cand_p)->lchan)</span><br><span style="color: hsl(0, 100%, 40%);">-                && ts_usage_count((*best_cand_p)->lchan->ts) < ts_usage_count(other_cand->lchan->ts))</span><br><span style="color: hsl(0, 100%, 40%);">-                        return false;</span><br><span style="color: hsl(120, 100%, 40%);">+         if (lchan_is_on_dynamic_ts(a->lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+                   && ts_usage_count(a->lchan->ts) < ts_usage_count(b->lchan->ts))</span><br><span style="color: hsl(120, 100%, 40%);">+                    return a;</span><br><span>            /* If both equally satisfy these preferences, it does not matter which one is picked.</span><br><span>                 * Give slight preference to moving later dyn TS, so that a free dyn TS may group with following static</span><br><span>               * PDCH, though this depends on how the user configured the TS -- not harmful to do so anyway. */</span><br><span style="color: hsl(0, 100%, 40%);">-               goto return_other;</span><br><span style="color: hsl(120, 100%, 40%);">+            return b;</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* keep the same candidate. */</span><br><span style="color: hsl(0, 100%, 40%);">-  return false;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-return_other:</span><br><span style="color: hsl(0, 100%, 40%);">-      *best_cand_p = other_cand;</span><br><span style="color: hsl(0, 100%, 40%);">-      *best_avg_db_p = other_avg_db;</span><br><span style="color: hsl(0, 100%, 40%);">-  return true;</span><br><span style="color: hsl(120, 100%, 40%);">+  return a;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static struct ho_candidate *pick_best_candidate(int *applied_afs_bias,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                struct ho_candidate *clist, int clist_len,</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ho_candidate *pick_best_candidate(struct ho_candidate *clist, int clist_len,</span><br><span>                                               bool want_highest_db,</span><br><span>                                                bool omit_intra_cell_upgrade_to_tchf,</span><br><span>                                                bool only_intra_cell_upgrade_to_tchf,</span><br><span>                                                uint8_t for_requirement)</span><br><span> {</span><br><span>        struct ho_candidate *result = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-     unsigned int result_avg_rxlev;</span><br><span style="color: hsl(0, 100%, 40%);">-  int result_afs_bias = 0;</span><br><span>     int i;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      if (applied_afs_bias)</span><br><span style="color: hsl(0, 100%, 40%);">-           *applied_afs_bias = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  result_avg_rxlev = want_highest_db ? 0 : INT_MAX;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    for (i = 0; i < clist_len; i++) {</span><br><span>                 struct ho_candidate *c = &clist[i];</span><br><span>              bool intra_cell;</span><br><span>             bool upgrade_to_tch_f;</span><br><span style="color: hsl(0, 100%, 40%);">-          int avg_rxlev;</span><br><span style="color: hsl(0, 100%, 40%);">-          int afs_bias;</span><br><span> </span><br><span>            /* For multiple passes of congestion resolution, already handovered candidates are marked by lchan =</span><br><span>                  * NULL. (though at the time of writing, multiple passes of congestion resolution are DISABLED.) */</span><br><span>@@ -1478,21 +1471,15 @@</span><br><span>                    && (intra_cell && upgrade_to_tch_f))</span><br><span>                     continue;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           avg_rxlev = c->rxlev_target;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>              /* improve AHS */</span><br><span>            if (upgrade_to_tch_f)</span><br><span style="color: hsl(0, 100%, 40%);">-                   afs_bias = ho_get_hodec2_afs_bias_rxlev(c->bts->ho);</span><br><span style="color: hsl(120, 100%, 40%);">+                    c->rxlev_afs_bias = ho_get_hodec2_afs_bias_rxlev(c->bts->ho);</span><br><span>               else</span><br><span style="color: hsl(0, 100%, 40%);">-                    afs_bias = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-           avg_rxlev += afs_bias;</span><br><span style="color: hsl(120, 100%, 40%);">+                        c->rxlev_afs_bias = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           if (pick_better_lchan_to_move(want_highest_db, &result, &result_avg_rxlev, c, avg_rxlev))</span><br><span style="color: hsl(0, 100%, 40%);">-                       result_afs_bias = afs_bias;</span><br><span style="color: hsl(120, 100%, 40%);">+           result = pick_better_lchan_to_move(want_highest_db, result, c);</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (applied_afs_bias)</span><br><span style="color: hsl(0, 100%, 40%);">-           *applied_afs_bias = result_afs_bias;</span><br><span>         return result;</span><br><span> }</span><br><span> </span><br><span>@@ -1556,7 +1543,6 @@</span><br><span>      struct ho_candidate *best_cand = NULL;</span><br><span>       int rc = 0;</span><br><span>  int any_ho = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- int is_improved = 0;</span><br><span> </span><br><span>     if (tchf_congestion < 0)</span><br><span>          tchf_congestion = 0;</span><br><span>@@ -1657,7 +1643,7 @@</span><br><span>         /* TODO: attempt inter-BSC HO if no local cells qualify, and rely on the remote BSS to</span><br><span>        * deny receiving the handover if it also considers itself congested. Maybe do that only</span><br><span>      * when the cell is absolutely full, i.e. not only min-free-slots. (x) */</span><br><span style="color: hsl(0, 100%, 40%);">-       best_cand = pick_best_candidate(&is_improved, clist, candidates,</span><br><span style="color: hsl(120, 100%, 40%);">+  best_cand = pick_best_candidate(clist, candidates,</span><br><span>                                   /* want_highest_db */ true,</span><br><span>                                  /* omit_intra_cell_upgrade_to_tchf */ true,</span><br><span>                                  /* only_intra_cell_upgrade_to_tchf */ false,</span><br><span>@@ -1666,7 +1652,7 @@</span><br><span>                 any_ho = 1;</span><br><span>          LOGPHOCAND(best_cand, LOGL_DEBUG, "Best candidate: RX level %d%s\n",</span><br><span>                          rxlev2dbm(best_cand->rxlev_target),</span><br><span style="color: hsl(0, 100%, 40%);">-                          is_improved ? " (applied AHS->AFS bias)" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+                        best_cand->rxlev_afs_bias ? " (applied AHS->AFS bias)" : "");</span><br><span>           trigger_ho(best_cand, best_cand->requirements & REQUIREMENT_B_MASK);</span><br><span> #if 0</span><br><span>                 /* if there is still congestion, mark lchan as deleted</span><br><span>@@ -1698,7 +1684,7 @@</span><br><span>        * but simply pick the lowest one.</span><br><span>    * Upgrading TCH/H channels obviously only applies when TCH/H is actually congested. */</span><br><span>      if (tchh_congestion > 0)</span><br><span style="color: hsl(0, 100%, 40%);">-             best_cand = pick_best_candidate(&is_improved, clist, candidates,</span><br><span style="color: hsl(120, 100%, 40%);">+          best_cand = pick_best_candidate(clist, candidates,</span><br><span>                                           /* want_highest_db */ false,</span><br><span>                                                 /* omit_intra_cell_upgrade_to_tchf */ false,</span><br><span>                                                 /* only_intra_cell_upgrade_to_tchf */ true,</span><br><span>@@ -1707,7 +1693,7 @@</span><br><span>          any_ho = 1;</span><br><span>          LOGPHOCAND(best_cand, LOGL_INFO, "Worst candidate: RX level %d from TCH/H -> TCH/F%s\n",</span><br><span>                           rxlev2dbm(best_cand->rxlev_target),</span><br><span style="color: hsl(0, 100%, 40%);">-                          is_improved ? " (applied AHS -> AFS rxlev bias)" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+                        best_cand->rxlev_afs_bias ? " (applied AHS -> AFS rxlev bias)" : "");</span><br><span>           trigger_ho(best_cand, best_cand->requirements & REQUIREMENT_B_MASK);</span><br><span> #if 0</span><br><span>                 /* if there is still congestion, mark lchan as deleted</span><br><span>@@ -1733,7 +1719,7 @@</span><br><span>       /* Select best candidate that balances congestion.</span><br><span>    * Again no remote BSS.</span><br><span>       * Again no TCH/H -> F upgrades within the same cell. */</span><br><span style="color: hsl(0, 100%, 40%);">-     best_cand = pick_best_candidate(&is_improved, clist, candidates,</span><br><span style="color: hsl(120, 100%, 40%);">+  best_cand = pick_best_candidate(clist, candidates,</span><br><span>                                   /* want_highest_db */ true,</span><br><span>                                  /* omit_intra_cell_upgrade_to_tchf */ true,</span><br><span>                                  /* only_intra_cell_upgrade_to_tchf */ false,</span><br><span>@@ -1742,7 +1728,7 @@</span><br><span>                 any_ho = 1;</span><br><span>          LOGPHOCAND(best_cand, LOGL_INFO, "Best candidate: RX level %d%s\n",</span><br><span>                           rxlev2dbm(best_cand->rxlev_target),</span><br><span style="color: hsl(0, 100%, 40%);">-                          is_improved ? " (applied AHS -> AFS rxlev bias)" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+                        best_cand->rxlev_afs_bias ? " (applied AHS -> AFS rxlev bias)" : "");</span><br><span>           trigger_ho(best_cand, best_cand->requirements & REQUIREMENT_C_MASK);</span><br><span> #if 0</span><br><span>                 /* if there is still congestion, mark lchan as deleted</span><br><span>@@ -1774,7 +1760,7 @@</span><br><span>       /* Look for upgrading TCH/H to TCH/F within the same cell, which balances congestion, again upgrade the TCH/H</span><br><span>         * lchan that has the worst reception: */</span><br><span>    if (tchh_congestion > 0)</span><br><span style="color: hsl(0, 100%, 40%);">-             best_cand = pick_best_candidate(&is_improved, clist, candidates,</span><br><span style="color: hsl(120, 100%, 40%);">+          best_cand = pick_best_candidate(clist, candidates,</span><br><span>                                           /* want_highest_db */ false,</span><br><span>                                                 /* omit_intra_cell_upgrade_to_tchf */ false,</span><br><span>                                                 /* only_intra_cell_upgrade_to_tchf */ true,</span><br><span>@@ -1785,7 +1771,7 @@</span><br><span>          any_ho = 1;</span><br><span>          LOGPHOCAND(best_cand, LOGL_INFO, "Worst candidate: RX level %d from TCH/H -> TCH/F%s\n",</span><br><span>                           rxlev2dbm(best_cand->rxlev_target),</span><br><span style="color: hsl(0, 100%, 40%);">-                          is_improved ? " (applied AHS -> AFS rxlev bias)" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+                        best_cand->rxlev_afs_bias ? " (applied AHS -> AFS rxlev bias)" : "");</span><br><span>           trigger_ho(best_cand, best_cand->requirements & REQUIREMENT_C_MASK);</span><br><span> #if 0</span><br><span>                 /* if there is still congestion, mark lchan as deleted</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bsc/+/21978">change 21978</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-bsc/+/21978"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-bsc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I73860abdf2a77270ca4851ad58c09767d1bb08f1 </div>
<div style="display:none"> Gerrit-Change-Number: 21978 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>