diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/osmo-bsc/Makefile.am | 1 | ||||
-rw-r--r-- | src/osmo-bsc/bsc_init.c | 8 | ||||
-rw-r--r-- | src/osmo-bsc/bsc_stats.c | 76 | ||||
-rw-r--r-- | src/osmo-bsc/bts.c | 8 | ||||
-rw-r--r-- | src/osmo-bsc/time_cc.c | 208 |
5 files changed, 46 insertions, 255 deletions
diff --git a/src/osmo-bsc/Makefile.am b/src/osmo-bsc/Makefile.am index cebbaeb4e..583fb79d9 100644 --- a/src/osmo-bsc/Makefile.am +++ b/src/osmo-bsc/Makefile.am @@ -105,7 +105,6 @@ libbsc_la_SOURCES = \ bssmap_reset.c \ system_information.c \ timeslot_fsm.c \ - time_cc.c \ smscb.c \ cbch_scheduler.c \ cbsp_link.c \ diff --git a/src/osmo-bsc/bsc_init.c b/src/osmo-bsc/bsc_init.c index 93287072d..0412f6b6b 100644 --- a/src/osmo-bsc/bsc_init.c +++ b/src/osmo-bsc/bsc_init.c @@ -120,7 +120,7 @@ static struct gsm_network *bsc_network_init(void *ctx) if (!net->bts_unknown_statg) goto err_free_all; - net->all_allocated_sdcch = (struct time_cc){ + net->all_allocated_sdcch = (struct osmo_time_cc){ .cfg = { .gran_usec = 1*1000000, .forget_sum_usec = 60*1000000, @@ -131,7 +131,7 @@ static struct gsm_network *bsc_network_init(void *ctx) .T_defs = net->T_defs, }, }; - net->all_allocated_static_sdcch = (struct time_cc){ + net->all_allocated_static_sdcch = (struct osmo_time_cc){ .cfg = { .gran_usec = 1*1000000, .forget_sum_usec = 60*1000000, @@ -142,7 +142,7 @@ static struct gsm_network *bsc_network_init(void *ctx) .T_defs = net->T_defs, }, }; - net->all_allocated_tch = (struct time_cc){ + net->all_allocated_tch = (struct osmo_time_cc){ .cfg = { .gran_usec = 1*1000000, .forget_sum_usec = 60*1000000, @@ -153,7 +153,7 @@ static struct gsm_network *bsc_network_init(void *ctx) .T_defs = net->T_defs, }, }; - net->all_allocated_static_tch = (struct time_cc){ + net->all_allocated_static_tch = (struct osmo_time_cc){ .cfg = { .gran_usec = 1*1000000, .forget_sum_usec = 60*1000000, diff --git a/src/osmo-bsc/bsc_stats.c b/src/osmo-bsc/bsc_stats.c index 0da3a6cef..c789aead4 100644 --- a/src/osmo-bsc/bsc_stats.c +++ b/src/osmo-bsc/bsc_stats.c @@ -215,46 +215,46 @@ void bsc_update_time_cc_all_allocated(struct gsm_network *net) chan_counts_add(&bts_counts, &trx_counts); } - time_cc_set_flag(&bts->all_allocated_sdcch, - bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_SDCCH] - && !bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_SDCCH]); - - time_cc_set_flag(&bts->all_allocated_static_sdcch, - bts_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_SDCCH] - && !bts_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_FREE][GSM_LCHAN_SDCCH]); - - time_cc_set_flag(&bts->all_allocated_tch, - (bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_F] - + bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_H]) - && !(bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_F] - + bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_H])); - - time_cc_set_flag(&bts->all_allocated_static_tch, - (bts_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_F] - + bts_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_H]) - && !(bts_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_F] - + bts_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_H])); + osmo_time_cc_set_flag(&bts->all_allocated_sdcch, + bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_SDCCH] + && !bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_SDCCH]); + + osmo_time_cc_set_flag(&bts->all_allocated_static_sdcch, + bts_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_SDCCH] + && !bts_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_FREE][GSM_LCHAN_SDCCH]); + + osmo_time_cc_set_flag(&bts->all_allocated_tch, + (bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_F] + + bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_H]) + && !(bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_F] + + bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_H])); + + osmo_time_cc_set_flag(&bts->all_allocated_static_tch, + (bts_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_F] + + bts_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_H]) + && !(bts_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_F] + + bts_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_H])); chan_counts_add(&bsc_counts, &bts_counts); } - time_cc_set_flag(&net->all_allocated_sdcch, - bsc_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_SDCCH] - && !bsc_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_SDCCH]); - - time_cc_set_flag(&net->all_allocated_static_sdcch, - bsc_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_SDCCH] - && !bsc_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_FREE][GSM_LCHAN_SDCCH]); - - time_cc_set_flag(&net->all_allocated_tch, - (bsc_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_F] - + bsc_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_H]) - && !(bsc_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_F] - + bsc_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_H])); - - time_cc_set_flag(&net->all_allocated_static_tch, - (bsc_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_F] - + bsc_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_H]) - && !(bsc_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_F] - + bsc_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_H])); + osmo_time_cc_set_flag(&net->all_allocated_sdcch, + bsc_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_SDCCH] + && !bsc_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_SDCCH]); + + osmo_time_cc_set_flag(&net->all_allocated_static_sdcch, + bsc_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_SDCCH] + && !bsc_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_FREE][GSM_LCHAN_SDCCH]); + + osmo_time_cc_set_flag(&net->all_allocated_tch, + (bsc_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_F] + + bsc_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_H]) + && !(bsc_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_F] + + bsc_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_H])); + + osmo_time_cc_set_flag(&net->all_allocated_static_tch, + (bsc_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_F] + + bsc_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_H]) + && !(bsc_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_F] + + bsc_counts.val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_H])); } diff --git a/src/osmo-bsc/bts.c b/src/osmo-bsc/bts.c index 8af125488..11b1ec384 100644 --- a/src/osmo-bsc/bts.c +++ b/src/osmo-bsc/bts.c @@ -211,7 +211,7 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, struct gsm_bts_sm *bts_sm } bts->bts_statg = osmo_stat_item_group_alloc(bts, &bts_statg_desc, bts->nr); - bts->all_allocated_sdcch = (struct time_cc){ + bts->all_allocated_sdcch = (struct osmo_time_cc){ .cfg = { .gran_usec = 1*1000000, .forget_sum_usec = 60*1000000, @@ -222,7 +222,7 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, struct gsm_bts_sm *bts_sm .T_defs = net->T_defs, }, }; - bts->all_allocated_static_sdcch = (struct time_cc){ + bts->all_allocated_static_sdcch = (struct osmo_time_cc){ .cfg = { .gran_usec = 1*1000000, .forget_sum_usec = 60*1000000, @@ -233,7 +233,7 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, struct gsm_bts_sm *bts_sm .T_defs = net->T_defs, }, }; - bts->all_allocated_tch = (struct time_cc){ + bts->all_allocated_tch = (struct osmo_time_cc){ .cfg = { .gran_usec = 1*1000000, .forget_sum_usec = 60*1000000, @@ -244,7 +244,7 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, struct gsm_bts_sm *bts_sm .T_defs = net->T_defs, }, }; - bts->all_allocated_static_tch = (struct time_cc){ + bts->all_allocated_static_tch = (struct osmo_time_cc){ .cfg = { .gran_usec = 1*1000000, .forget_sum_usec = 60*1000000, diff --git a/src/osmo-bsc/time_cc.c b/src/osmo-bsc/time_cc.c deleted file mode 100644 index e78e48d48..000000000 --- a/src/osmo-bsc/time_cc.c +++ /dev/null @@ -1,208 +0,0 @@ -/* Report the cumulative counter of time for which a flag is true as rate counter. */ -/* Copyright (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> - * - * All Rights Reserved - * - * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ - -#include <limits.h> - -#include <osmocom/core/tdef.h> -#include <osmocom/core/rate_ctr.h> - -#include <osmocom/bsc/time_cc.h> - -#define GRAN_USEC(TIME_CC) ((TIME_CC)->cfg.gran_usec ? : 1000000) -#define ROUND_THRESHOLD_USEC(TIME_CC) ((TIME_CC)->cfg.round_threshold_usec ? \ - OSMO_MIN((TIME_CC)->cfg.round_threshold_usec, GRAN_USEC(TIME_CC)) \ - : (GRAN_USEC(TIME_CC) / 2)) - -static uint64_t time_now_usec() -{ - struct timespec tp; - if (osmo_clock_gettime(CLOCK_MONOTONIC, &tp)) - return 0; - return (uint64_t)tp.tv_sec * 1000000 + tp.tv_nsec / 1000; -} - -static void time_cc_forget_sum(struct time_cc *tc, uint64_t now); - -static void time_cc_update_from_tdef(struct time_cc *tc, uint64_t now) -{ - bool do_forget_sum = false; - if (!tc->cfg.T_defs) - return; - if (tc->cfg.T_gran) { - uint64_t was = GRAN_USEC(tc); - tc->cfg.gran_usec = osmo_tdef_get(tc->cfg.T_defs, tc->cfg.T_gran, OSMO_TDEF_US, -1); - if (was != GRAN_USEC(tc)) - do_forget_sum = true; - } - if (tc->cfg.T_round_threshold) - tc->cfg.round_threshold_usec = osmo_tdef_get(tc->cfg.T_defs, tc->cfg.T_round_threshold, - OSMO_TDEF_US, -1); - if (tc->cfg.T_forget_sum) { - uint64_t was = tc->cfg.forget_sum_usec; - tc->cfg.forget_sum_usec = osmo_tdef_get(tc->cfg.T_defs, tc->cfg.T_forget_sum, OSMO_TDEF_US, -1); - if (tc->cfg.forget_sum_usec && was != tc->cfg.forget_sum_usec) - do_forget_sum = true; - } - - if (do_forget_sum && tc->sum) - time_cc_forget_sum(tc, now); -} - -static void time_cc_schedule_timer(struct time_cc *tc, uint64_t now); - -/* Clear out osmo_timer and internal counting state of struct time_cc. The .cfg remains unaffected. After calling, the - * time_cc instance can be used again to accumulate state as if it had just been initialized. */ -void time_cc_cleanup(struct time_cc *tc) -{ - osmo_timer_del(&tc->timer); - *tc = (struct time_cc){ - .cfg = tc->cfg, - }; -} - -static void time_cc_start(struct time_cc *tc, uint64_t now) -{ - time_cc_cleanup(tc); - /* Set the default of 1 second of granularity */ - tc->start_time = now; - tc->last_counted_time = now; - time_cc_update_from_tdef(tc, now); - time_cc_schedule_timer(tc, now); -} - -static void time_cc_count_time(struct time_cc *tc, uint64_t now) -{ - uint64_t time_delta = now - tc->last_counted_time; - tc->last_counted_time = now; - if (!tc->flag_state) - return; - /* Flag is currently true, cumulate the elapsed time */ - tc->total_sum += time_delta; - tc->sum += time_delta; -} - -static void time_cc_report(struct time_cc *tc, uint64_t now) -{ - uint64_t delta; - uint64_t n; - if (!tc->cfg.rate_ctr) - return; - /* We report a sum "rounded up", ahead of time. If the granularity period has not yet elapsed after the last - * reporting, do not report again yet. */ - if (tc->reported_sum > tc->sum) - return; - delta = tc->sum - tc->reported_sum; - /* elapsed full periods */ - n = delta / GRAN_USEC(tc); - /* If the delta has passed round_threshold (normally half of gran_usec), increment. */ - delta -= n * GRAN_USEC(tc); - if (delta >= ROUND_THRESHOLD_USEC(tc)) - n++; - if (!n) - return; - - /* integer sanity, since rate_ctr_add() takes an int argument. */ - if (n > INT_MAX) - n = INT_MAX; - rate_ctr_add(tc->cfg.rate_ctr, n); - /* Store the increments of gran_usec that were counted. */ - tc->reported_sum += n * GRAN_USEC(tc); -} - -static void time_cc_forget_sum(struct time_cc *tc, uint64_t now) -{ - tc->reported_sum = 0; - tc->sum = 0; - - if (tc->last_counted_time < now) - tc->last_counted_time = now; -} - -/* Initialize struct time_cc. Call this once before use, and before setting up the .cfg items. */ -void time_cc_init(struct time_cc *tc) -{ - *tc = (struct time_cc){0}; -} - -void time_cc_set_flag(struct time_cc *tc, bool flag) -{ - uint64_t now = time_now_usec(); - if (!tc->start_time) - time_cc_start(tc, now); - /* No flag change == no effect */ - if (flag == tc->flag_state) - return; - /* Sum up elapsed time, report increments for that. */ - time_cc_count_time(tc, now); - time_cc_report(tc, now); - tc->flag_state = flag; - time_cc_schedule_timer(tc, now); -} - -static void time_cc_timer_cb(void *data) -{ - struct time_cc *tc = data; - uint64_t now = time_now_usec(); - - time_cc_update_from_tdef(tc, now); - - if (tc->flag_state) { - time_cc_count_time(tc, now); - time_cc_report(tc, now); - } else if (tc->cfg.forget_sum_usec && tc->sum - && (now >= tc->last_counted_time + tc->cfg.forget_sum_usec)) { - time_cc_forget_sum(tc, now); - } - time_cc_schedule_timer(tc, now); -} - -static void time_cc_schedule_timer(struct time_cc *tc, uint64_t now) -{ - uint64_t next_event = UINT64_MAX; - - time_cc_update_from_tdef(tc, now); - - /* Figure out the next time we should do anything, if the flag state remains unchanged. */ - /* If it is required, when will the next forget_sum happen? */ - if (tc->cfg.forget_sum_usec && !tc->flag_state && tc->sum > 0) { - uint64_t next_forget_time = tc->last_counted_time + tc->cfg.forget_sum_usec; - next_event = OSMO_MIN(next_event, next_forget_time); - } - /* Next rate_ctr increment? */ - if (tc->flag_state && tc->cfg.rate_ctr) { - uint64_t next_inc = now + (tc->reported_sum - tc->sum) + ROUND_THRESHOLD_USEC(tc); - next_event = OSMO_MIN(next_event, next_inc); - } - - /* No event coming up? */ - if (next_event == UINT64_MAX) - return; - - if (next_event <= now) - next_event = 0; - else - next_event -= now; - - osmo_timer_setup(&tc->timer, time_cc_timer_cb, tc); - osmo_timer_del(&tc->timer); - osmo_timer_schedule(&tc->timer, next_event / 1000000, next_event % 1000000); -} |