aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2022-11-15 13:15:45 +0100
committerPau Espin Pedrol <pespin@sysmocom.de>2022-11-15 18:10:14 +0100
commit035080e4f439a0536dd4865d54713a9df77b0ee3 (patch)
tree736582abdee596870ff4f79cb054d5b1d5512659
parenta590b1a15a27c308dad4be7498c6bb07d7dea16f (diff)
osmux: Rotate over available Osmux CID when allocating a new one
Before this patch, the free CID with the smallest number was always selected to be used. This caused more or less the same subset of CIDs to be used all the time, while the CIDs with bigger numbers were mostly unused. Let's distribute the use so that all CIDs are used roughly the same. This has the advantage, among others, that the same CID will not be re-used immediatelly after being freed if a new call is established. It is useful to leave the CIDs unused for some time since the other end peer may know of the call being tear down with some delay. Hence if a new call is established immediately after the CID was released, the same CID would be allocated and passed at the peer, which would then detect that the old call (in its view still active) would already make use of that remote CID. Related: SYS#6161 Change-Id: I72803fb172accbabfc81923572890f8ecb06cefd
-rw-r--r--src/common/osmux.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/src/common/osmux.c b/src/common/osmux.c
index 83730cec..fa0f7cc3 100644
--- a/src/common/osmux.c
+++ b/src/common/osmux.c
@@ -43,26 +43,46 @@
/* Bitmask containing Allocated Osmux circuit ID. +7 to round up to 8 bit boundary. */
static uint8_t osmux_cid_bitmap[OSMO_BYTES_FOR_BITS(OSMUX_CID_MAX + 1)];
-/*! Find and reserve a free OSMUX cid.
+/*! Find and reserve a free OSMUX cid. Keep state of last allocated CID to
+ * rotate allocated CIDs over time. This helps in letting CIDs unused for some
+ * time after last use.
* \returns OSMUX cid */
static int osmux_get_local_cid(void)
{
- int i, j;
+ static uint8_t next_free_osmux_cid_lookup = 0;
+ uint8_t start_i, start_j;
+ uint8_t i, j, cid;
- for (i = 0; i < sizeof(osmux_cid_bitmap); i++) {
- for (j = 0; j < 8; j++) {
+ /* i = octet index, j = bit index inside ith octet */
+ start_i = next_free_osmux_cid_lookup >> 3;
+ start_j = next_free_osmux_cid_lookup & 0x07;
+
+ for (i = start_i; i < sizeof(osmux_cid_bitmap); i++) {
+ for (j = start_j; j < 8; j++) {
if (osmux_cid_bitmap[i] & (1 << j))
continue;
+ goto found;
+ }
+ }
- osmux_cid_bitmap[i] |= (1 << j);
- LOGP(DOSMUX, LOGL_DEBUG,
- "Allocating Osmux CID %u from pool\n", (i * 8) + j);
- return (i * 8) + j;
+ for (i = 0; i <= start_i; i++) {
+ for (j = 0; j < start_j; j++) {
+ if (osmux_cid_bitmap[i] & (1 << j))
+ continue;
+ goto found;
}
}
LOGP(DOSMUX, LOGL_ERROR, "All Osmux circuits are in use!\n");
return -1;
+
+found:
+ osmux_cid_bitmap[i] |= (1 << j);
+ cid = (i << 3) | j;
+ next_free_osmux_cid_lookup = (cid + 1) & 0xff;
+ LOGP(DOSMUX, LOGL_DEBUG,
+ "Allocating Osmux CID %u from pool\n", cid);
+ return cid;
}
/*! put back a no longer used OSMUX cid.