bscc_sccp: Small optimiztion in bsc_sccp_inst_next_conn_id()
Refactor the double loop to check a code path matching the sccp_instance once instead of doing so for every subscr_conn. If for instance let's say we have 1000 concurrent calls in progress, which means we have 1000 subscr_conn, which means we at least do the extra check regarding SMLC vs MSC 1000 times (at least, xN times if N conn_id already used are already found). That overhead happens every time a new subscr_conn is created (which in a BSC with already 1000 concurrent calls can potentially happen quite frequently). Change-Id: Ic32b1eeb201fc51110e1ee130110824845f81e82
This commit is contained in:
parent
8958269ea9
commit
53cd4ad5fc
|
@ -47,6 +47,33 @@ uint32_t bsc_sccp_inst_next_conn_id(struct osmo_sccp_instance *sccp)
|
|||
/* This looks really suboptimal, but in most cases the static next_id should indicate exactly the next unused
|
||||
* conn_id, and we only iterate all conns once to make super sure that it is not already in use. */
|
||||
|
||||
/* SCCP towards SMLC: */
|
||||
if (bsc_gsmnet->smlc->sccp == sccp) {
|
||||
for (i = 0; i < SCCP_CONN_ID_MAX; i++) {
|
||||
struct gsm_subscriber_connection *conn;
|
||||
uint32_t conn_id = next_id;
|
||||
bool conn_id_already_used = false;
|
||||
|
||||
/* Optimized modulo operation (% SCCP_CONN_ID_MAX) using bitwise AND plus CMP: */
|
||||
next_id = (next_id + 1) & 0x00FFFFFF;
|
||||
if (OSMO_UNLIKELY(next_id == 0x00FFFFFF))
|
||||
next_id = 0;
|
||||
|
||||
llist_for_each_entry(conn, &bsc_gsmnet->subscr_conns, entry) {
|
||||
if (conn->lcs.lb.state != SUBSCR_SCCP_ST_NONE &&
|
||||
conn->lcs.lb.conn_id == conn_id) {
|
||||
conn_id_already_used = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!conn_id_already_used)
|
||||
return conn_id;
|
||||
}
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/* SCCP towards MSC: */
|
||||
for (i = 0; i < SCCP_CONN_ID_MAX; i++) {
|
||||
struct gsm_subscriber_connection *conn;
|
||||
uint32_t conn_id = next_id;
|
||||
|
@ -58,19 +85,10 @@ uint32_t bsc_sccp_inst_next_conn_id(struct osmo_sccp_instance *sccp)
|
|||
next_id = 0;
|
||||
|
||||
llist_for_each_entry(conn, &bsc_gsmnet->subscr_conns, entry) {
|
||||
if (conn->sccp.msc && conn->sccp.msc->a.sccp == sccp) {
|
||||
if (conn_id == conn->sccp.conn_id) {
|
||||
conn_id_already_used = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bsc_gsmnet->smlc->sccp == sccp
|
||||
&& conn->lcs.lb.state != SUBSCR_SCCP_ST_NONE) {
|
||||
if (conn_id == conn->lcs.lb.conn_id) {
|
||||
conn_id_already_used = true;
|
||||
break;
|
||||
}
|
||||
if (conn->sccp.msc && conn->sccp.msc->a.sccp == sccp &&
|
||||
conn->sccp.conn_id == conn_id) {
|
||||
conn_id_already_used = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue