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.

Change-Id: I9dfbcc5e4b4c61ce217020e533d68fbcfa6b9f56
Related: SYS#6161
This commit is contained in:
Pau Espin 2022-11-15 13:23:38 +01:00
parent a55bfdc436
commit 310e41cdf3
2 changed files with 30 additions and 9 deletions

View File

@ -734,26 +734,46 @@ int osmux_cid_pool_count_used(void)
return used;
}
/*! take 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 */
int osmux_cid_pool_get_next(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;
}
/*! take a specific OSMUX cid.

View File

@ -1632,7 +1632,8 @@ static void test_osmux_cid(void)
for (i = 0; i < 256; ++i) {
id = osmux_cid_pool_get_next();
OSMO_ASSERT(id == i);
/* We called osmux_cid_pool_get_next() above, so next CID is i+1. */
OSMO_ASSERT(id == ((i + 1) & 0xff));
OSMO_ASSERT(osmux_cid_pool_count_used() == i + 1);
}