diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2022-11-15 13:15:45 +0100 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2022-11-15 18:10:14 +0100 |
commit | 035080e4f439a0536dd4865d54713a9df77b0ee3 (patch) | |
tree | 736582abdee596870ff4f79cb054d5b1d5512659 | |
parent | a590b1a15a27c308dad4be7498c6bb07d7dea16f (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.c | 36 |
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. |