osmo-bsc/include/osmocom/bsc/chan_counts.h

112 lines
3.5 KiB
C
Raw Normal View History

refactor lchan counting Add chan_counts_for_trx() and chan_counts_for_bts(). Drop bts_count_free_ts() and trx_count_free_ts(). Rationale: The bts_count_free_ts() and trx_count_free_ts() always returned the number of free lchans, not timeslots. Hence, passing the pchan type as argument never really matched the semantics. Especially, when looking for free SDCCH, there is no clear match on a gsm_phys_chan_config enum value: SDCCH8_SACCH8C, CCCH_SDCCH4, CCCH_SDCCH4_CBCH, SDCCH8_SACCH8C_CBCH? -- GSM_LCHAN_SDCCH is clear. ==> Rather count free lchans by enum gsm_chan_t. Counting lchans of distinct types required separate iterations for each lchan type. ==> Rather compose an array of counts for all types, in one go. I need to count the amount of free SDCCH lchans in an upcoming patch to implement the performance indicator allAvailableAllocatedSDCCH (cumulate time for which no SDCCH are available). To implement allAvailableAllocated{SDCCH,TCH}, I need a count of both the used as well as the total lchans for a type: it does not make sense to flag "all available allocated" if none are ever available. To properly count dynamic ts, I need the maximum total that can be possible at any time. And to count currently free lchans, I need the current total. This may seem counter intuitive, but consider, e.g.: - Obviously, if a cell has only static TCH/F timeslots, it does not make sense to flag that all available TCH/H are occupied, because no TCH/H are available ever. Just stating this as contrast to dyn TS. - If a cell has OSMO_DYN timeslots, I *do* want to flag that all TCH/H are occupied when all dyn timeslots are fully occupied. - If those OSMO_DYN however are all used as TCH/F, the current total of TCH/H becomes zero, and it seems like TCH/H should not be considered. - To count the nr of currently free lchans, I need the currently possible total of lchans and the nr of occupied lchans. So return both a maximum total and a current total of lchans. In above example, the maximum total shows that there would be TCH/H possible. BTW, it would be nice to keep a chan_counts array on trx, bts and bsc level and update as channels are allocated and released, instead of counting them all over periodically. But it's less error prone this way. Related: SYS#4878 Change-Id: I2fb48c549186db812b1e9d6b735a92e80f27b8d3
2021-09-27 08:50:37 +00:00
/* API to count total, allocated and free channels of all types */
#pragma once
struct gsm_bts;
struct gsm_bts_trx;
struct gsm_bts_trx_ts;
struct gsm_lchan;
void chan_counts_sig_init(void);
void chan_counts_ts_update(struct gsm_bts_trx_ts *ts);
void chan_counts_ts_clear(struct gsm_bts_trx_ts *ts);
void chan_counts_trx_update(struct gsm_bts_trx *trx);
void chan_counts_bsc_verify(void);
refactor lchan counting Add chan_counts_for_trx() and chan_counts_for_bts(). Drop bts_count_free_ts() and trx_count_free_ts(). Rationale: The bts_count_free_ts() and trx_count_free_ts() always returned the number of free lchans, not timeslots. Hence, passing the pchan type as argument never really matched the semantics. Especially, when looking for free SDCCH, there is no clear match on a gsm_phys_chan_config enum value: SDCCH8_SACCH8C, CCCH_SDCCH4, CCCH_SDCCH4_CBCH, SDCCH8_SACCH8C_CBCH? -- GSM_LCHAN_SDCCH is clear. ==> Rather count free lchans by enum gsm_chan_t. Counting lchans of distinct types required separate iterations for each lchan type. ==> Rather compose an array of counts for all types, in one go. I need to count the amount of free SDCCH lchans in an upcoming patch to implement the performance indicator allAvailableAllocatedSDCCH (cumulate time for which no SDCCH are available). To implement allAvailableAllocated{SDCCH,TCH}, I need a count of both the used as well as the total lchans for a type: it does not make sense to flag "all available allocated" if none are ever available. To properly count dynamic ts, I need the maximum total that can be possible at any time. And to count currently free lchans, I need the current total. This may seem counter intuitive, but consider, e.g.: - Obviously, if a cell has only static TCH/F timeslots, it does not make sense to flag that all available TCH/H are occupied, because no TCH/H are available ever. Just stating this as contrast to dyn TS. - If a cell has OSMO_DYN timeslots, I *do* want to flag that all TCH/H are occupied when all dyn timeslots are fully occupied. - If those OSMO_DYN however are all used as TCH/F, the current total of TCH/H becomes zero, and it seems like TCH/H should not be considered. - To count the nr of currently free lchans, I need the currently possible total of lchans and the nr of occupied lchans. So return both a maximum total and a current total of lchans. In above example, the maximum total shows that there would be TCH/H possible. BTW, it would be nice to keep a chan_counts array on trx, bts and bsc level and update as channels are allocated and released, instead of counting them all over periodically. But it's less error prone this way. Related: SYS#4878 Change-Id: I2fb48c549186db812b1e9d6b735a92e80f27b8d3
2021-09-27 08:50:37 +00:00
/* First array index to chan_counts.val. */
refactor lchan counting Add chan_counts_for_trx() and chan_counts_for_bts(). Drop bts_count_free_ts() and trx_count_free_ts(). Rationale: The bts_count_free_ts() and trx_count_free_ts() always returned the number of free lchans, not timeslots. Hence, passing the pchan type as argument never really matched the semantics. Especially, when looking for free SDCCH, there is no clear match on a gsm_phys_chan_config enum value: SDCCH8_SACCH8C, CCCH_SDCCH4, CCCH_SDCCH4_CBCH, SDCCH8_SACCH8C_CBCH? -- GSM_LCHAN_SDCCH is clear. ==> Rather count free lchans by enum gsm_chan_t. Counting lchans of distinct types required separate iterations for each lchan type. ==> Rather compose an array of counts for all types, in one go. I need to count the amount of free SDCCH lchans in an upcoming patch to implement the performance indicator allAvailableAllocatedSDCCH (cumulate time for which no SDCCH are available). To implement allAvailableAllocated{SDCCH,TCH}, I need a count of both the used as well as the total lchans for a type: it does not make sense to flag "all available allocated" if none are ever available. To properly count dynamic ts, I need the maximum total that can be possible at any time. And to count currently free lchans, I need the current total. This may seem counter intuitive, but consider, e.g.: - Obviously, if a cell has only static TCH/F timeslots, it does not make sense to flag that all available TCH/H are occupied, because no TCH/H are available ever. Just stating this as contrast to dyn TS. - If a cell has OSMO_DYN timeslots, I *do* want to flag that all TCH/H are occupied when all dyn timeslots are fully occupied. - If those OSMO_DYN however are all used as TCH/F, the current total of TCH/H becomes zero, and it seems like TCH/H should not be considered. - To count the nr of currently free lchans, I need the currently possible total of lchans and the nr of occupied lchans. So return both a maximum total and a current total of lchans. In above example, the maximum total shows that there would be TCH/H possible. BTW, it would be nice to keep a chan_counts array on trx, bts and bsc level and update as channels are allocated and released, instead of counting them all over periodically. But it's less error prone this way. Related: SYS#4878 Change-Id: I2fb48c549186db812b1e9d6b735a92e80f27b8d3
2021-09-27 08:50:37 +00:00
enum chan_counts_dim1 {
CHAN_COUNTS1_ALL = 0,
CHAN_COUNTS1_STATIC = 1,
CHAN_COUNTS1_DYNAMIC = 2,
_CHAN_COUNTS1_NUM
};
/* Second array index to chan_counts.val. */
refactor lchan counting Add chan_counts_for_trx() and chan_counts_for_bts(). Drop bts_count_free_ts() and trx_count_free_ts(). Rationale: The bts_count_free_ts() and trx_count_free_ts() always returned the number of free lchans, not timeslots. Hence, passing the pchan type as argument never really matched the semantics. Especially, when looking for free SDCCH, there is no clear match on a gsm_phys_chan_config enum value: SDCCH8_SACCH8C, CCCH_SDCCH4, CCCH_SDCCH4_CBCH, SDCCH8_SACCH8C_CBCH? -- GSM_LCHAN_SDCCH is clear. ==> Rather count free lchans by enum gsm_chan_t. Counting lchans of distinct types required separate iterations for each lchan type. ==> Rather compose an array of counts for all types, in one go. I need to count the amount of free SDCCH lchans in an upcoming patch to implement the performance indicator allAvailableAllocatedSDCCH (cumulate time for which no SDCCH are available). To implement allAvailableAllocated{SDCCH,TCH}, I need a count of both the used as well as the total lchans for a type: it does not make sense to flag "all available allocated" if none are ever available. To properly count dynamic ts, I need the maximum total that can be possible at any time. And to count currently free lchans, I need the current total. This may seem counter intuitive, but consider, e.g.: - Obviously, if a cell has only static TCH/F timeslots, it does not make sense to flag that all available TCH/H are occupied, because no TCH/H are available ever. Just stating this as contrast to dyn TS. - If a cell has OSMO_DYN timeslots, I *do* want to flag that all TCH/H are occupied when all dyn timeslots are fully occupied. - If those OSMO_DYN however are all used as TCH/F, the current total of TCH/H becomes zero, and it seems like TCH/H should not be considered. - To count the nr of currently free lchans, I need the currently possible total of lchans and the nr of occupied lchans. So return both a maximum total and a current total of lchans. In above example, the maximum total shows that there would be TCH/H possible. BTW, it would be nice to keep a chan_counts array on trx, bts and bsc level and update as channels are allocated and released, instead of counting them all over periodically. But it's less error prone this way. Related: SYS#4878 Change-Id: I2fb48c549186db812b1e9d6b735a92e80f27b8d3
2021-09-27 08:50:37 +00:00
enum chan_counts_dim2 {
/* The maximum possible nr of lchans of this type. Counts all dynamic timeslots as if they are fully available
* for this type, regardless of the current pchan mode. (For CHAN_COUNTS1_STATIC, of course no dyn TS are counted
* at all.) */
CHAN_COUNTS2_MAX_TOTAL = 0,
/* Like MAX_TOTAL, but as soon as dynamic timeslots are switched to a specific pchan kind, current_total shrinks
* to count only currently present lchans (used and unused). */
CHAN_COUNTS2_CURRENT_TOTAL = 1,
/* Currently used lchans of this type. To get currently free lchans, calculate CURRENT_TOTAL - ALLOCATED. */
CHAN_COUNTS2_ALLOCATED = 2,
/* Currently assignable lchans of this type, same as CURRENT_TOTAL - ALLOCATED. */
CHAN_COUNTS2_FREE = 3,
_CHAN_COUNTS2_NUM
};
struct chan_counts {
/* Signed type, so that chan_counts_diff() can return negative values. */
int val[_CHAN_COUNTS1_NUM][_CHAN_COUNTS2_NUM][_GSM_LCHAN_MAX];
refactor lchan counting Add chan_counts_for_trx() and chan_counts_for_bts(). Drop bts_count_free_ts() and trx_count_free_ts(). Rationale: The bts_count_free_ts() and trx_count_free_ts() always returned the number of free lchans, not timeslots. Hence, passing the pchan type as argument never really matched the semantics. Especially, when looking for free SDCCH, there is no clear match on a gsm_phys_chan_config enum value: SDCCH8_SACCH8C, CCCH_SDCCH4, CCCH_SDCCH4_CBCH, SDCCH8_SACCH8C_CBCH? -- GSM_LCHAN_SDCCH is clear. ==> Rather count free lchans by enum gsm_chan_t. Counting lchans of distinct types required separate iterations for each lchan type. ==> Rather compose an array of counts for all types, in one go. I need to count the amount of free SDCCH lchans in an upcoming patch to implement the performance indicator allAvailableAllocatedSDCCH (cumulate time for which no SDCCH are available). To implement allAvailableAllocated{SDCCH,TCH}, I need a count of both the used as well as the total lchans for a type: it does not make sense to flag "all available allocated" if none are ever available. To properly count dynamic ts, I need the maximum total that can be possible at any time. And to count currently free lchans, I need the current total. This may seem counter intuitive, but consider, e.g.: - Obviously, if a cell has only static TCH/F timeslots, it does not make sense to flag that all available TCH/H are occupied, because no TCH/H are available ever. Just stating this as contrast to dyn TS. - If a cell has OSMO_DYN timeslots, I *do* want to flag that all TCH/H are occupied when all dyn timeslots are fully occupied. - If those OSMO_DYN however are all used as TCH/F, the current total of TCH/H becomes zero, and it seems like TCH/H should not be considered. - To count the nr of currently free lchans, I need the currently possible total of lchans and the nr of occupied lchans. So return both a maximum total and a current total of lchans. In above example, the maximum total shows that there would be TCH/H possible. BTW, it would be nice to keep a chan_counts array on trx, bts and bsc level and update as channels are allocated and released, instead of counting them all over periodically. But it's less error prone this way. Related: SYS#4878 Change-Id: I2fb48c549186db812b1e9d6b735a92e80f27b8d3
2021-09-27 08:50:37 +00:00
};
static inline void chan_counts_zero(struct chan_counts *counts)
{
*counts = (struct chan_counts){0};
}
static inline bool chan_counts_is_zero(const struct chan_counts *counts)
{
int i1, i2, i3;
for (i1 = 0; i1 < _CHAN_COUNTS1_NUM; i1++) {
for (i2 = 0; i2 < _CHAN_COUNTS2_NUM; i2++) {
for (i3 = 0; i3 < _GSM_LCHAN_MAX; i3++) {
if (counts->val[i1][i2][i3])
return false;
}
}
}
return true;
}
refactor lchan counting Add chan_counts_for_trx() and chan_counts_for_bts(). Drop bts_count_free_ts() and trx_count_free_ts(). Rationale: The bts_count_free_ts() and trx_count_free_ts() always returned the number of free lchans, not timeslots. Hence, passing the pchan type as argument never really matched the semantics. Especially, when looking for free SDCCH, there is no clear match on a gsm_phys_chan_config enum value: SDCCH8_SACCH8C, CCCH_SDCCH4, CCCH_SDCCH4_CBCH, SDCCH8_SACCH8C_CBCH? -- GSM_LCHAN_SDCCH is clear. ==> Rather count free lchans by enum gsm_chan_t. Counting lchans of distinct types required separate iterations for each lchan type. ==> Rather compose an array of counts for all types, in one go. I need to count the amount of free SDCCH lchans in an upcoming patch to implement the performance indicator allAvailableAllocatedSDCCH (cumulate time for which no SDCCH are available). To implement allAvailableAllocated{SDCCH,TCH}, I need a count of both the used as well as the total lchans for a type: it does not make sense to flag "all available allocated" if none are ever available. To properly count dynamic ts, I need the maximum total that can be possible at any time. And to count currently free lchans, I need the current total. This may seem counter intuitive, but consider, e.g.: - Obviously, if a cell has only static TCH/F timeslots, it does not make sense to flag that all available TCH/H are occupied, because no TCH/H are available ever. Just stating this as contrast to dyn TS. - If a cell has OSMO_DYN timeslots, I *do* want to flag that all TCH/H are occupied when all dyn timeslots are fully occupied. - If those OSMO_DYN however are all used as TCH/F, the current total of TCH/H becomes zero, and it seems like TCH/H should not be considered. - To count the nr of currently free lchans, I need the currently possible total of lchans and the nr of occupied lchans. So return both a maximum total and a current total of lchans. In above example, the maximum total shows that there would be TCH/H possible. BTW, it would be nice to keep a chan_counts array on trx, bts and bsc level and update as channels are allocated and released, instead of counting them all over periodically. But it's less error prone this way. Related: SYS#4878 Change-Id: I2fb48c549186db812b1e9d6b735a92e80f27b8d3
2021-09-27 08:50:37 +00:00
static inline void chan_counts_dim3_add(struct chan_counts *dst,
enum chan_counts_dim1 dst_dim1, enum chan_counts_dim2 dst_dim2,
const struct chan_counts *add,
enum chan_counts_dim1 add_dim1, enum chan_counts_dim2 add_dim2)
{
int i;
for (i = 0; i < _GSM_LCHAN_MAX; i++)
dst->val[dst_dim1][dst_dim2][i] += add->val[add_dim1][add_dim2][i];
}
static inline void chan_counts_dim3_sub(struct chan_counts *dst,
enum chan_counts_dim1 dst_dim1, enum chan_counts_dim2 dst_dim2,
const struct chan_counts *sub,
enum chan_counts_dim1 sub_dim1, enum chan_counts_dim2 sub_dim2)
{
int i;
for (i = 0; i < _GSM_LCHAN_MAX; i++)
dst->val[dst_dim1][dst_dim2][i] -= sub->val[sub_dim1][sub_dim2][i];
}
static inline void chan_counts_dim2_add(struct chan_counts *dst, enum chan_counts_dim1 dst_dim1,
const struct chan_counts *add, enum chan_counts_dim1 add_dim1)
{
int i;
for (i = 0; i < _CHAN_COUNTS2_NUM; i++)
chan_counts_dim3_add(dst, dst_dim1, i, add, add_dim1, i);
}
static inline void chan_counts_dim2_sub(struct chan_counts *dst, enum chan_counts_dim1 dst_dim1,
const struct chan_counts *sub, enum chan_counts_dim1 sub_dim1)
{
int i;
for (i = 0; i < _CHAN_COUNTS2_NUM; i++)
chan_counts_dim3_sub(dst, dst_dim1, i, sub, sub_dim1, i);
}
refactor lchan counting Add chan_counts_for_trx() and chan_counts_for_bts(). Drop bts_count_free_ts() and trx_count_free_ts(). Rationale: The bts_count_free_ts() and trx_count_free_ts() always returned the number of free lchans, not timeslots. Hence, passing the pchan type as argument never really matched the semantics. Especially, when looking for free SDCCH, there is no clear match on a gsm_phys_chan_config enum value: SDCCH8_SACCH8C, CCCH_SDCCH4, CCCH_SDCCH4_CBCH, SDCCH8_SACCH8C_CBCH? -- GSM_LCHAN_SDCCH is clear. ==> Rather count free lchans by enum gsm_chan_t. Counting lchans of distinct types required separate iterations for each lchan type. ==> Rather compose an array of counts for all types, in one go. I need to count the amount of free SDCCH lchans in an upcoming patch to implement the performance indicator allAvailableAllocatedSDCCH (cumulate time for which no SDCCH are available). To implement allAvailableAllocated{SDCCH,TCH}, I need a count of both the used as well as the total lchans for a type: it does not make sense to flag "all available allocated" if none are ever available. To properly count dynamic ts, I need the maximum total that can be possible at any time. And to count currently free lchans, I need the current total. This may seem counter intuitive, but consider, e.g.: - Obviously, if a cell has only static TCH/F timeslots, it does not make sense to flag that all available TCH/H are occupied, because no TCH/H are available ever. Just stating this as contrast to dyn TS. - If a cell has OSMO_DYN timeslots, I *do* want to flag that all TCH/H are occupied when all dyn timeslots are fully occupied. - If those OSMO_DYN however are all used as TCH/F, the current total of TCH/H becomes zero, and it seems like TCH/H should not be considered. - To count the nr of currently free lchans, I need the currently possible total of lchans and the nr of occupied lchans. So return both a maximum total and a current total of lchans. In above example, the maximum total shows that there would be TCH/H possible. BTW, it would be nice to keep a chan_counts array on trx, bts and bsc level and update as channels are allocated and released, instead of counting them all over periodically. But it's less error prone this way. Related: SYS#4878 Change-Id: I2fb48c549186db812b1e9d6b735a92e80f27b8d3
2021-09-27 08:50:37 +00:00
static inline void chan_counts_add(struct chan_counts *dst, const struct chan_counts *add)
{
int i;
for (i = 0; i < _CHAN_COUNTS1_NUM; i++)
chan_counts_dim2_add(dst, i, add, i);
}
static inline void chan_counts_sub(struct chan_counts *dst, const struct chan_counts *sub)
{
int i;
for (i = 0; i < _CHAN_COUNTS1_NUM; i++)
chan_counts_dim2_sub(dst, i, sub, i);
}