From: Florian Forster Date: Fri, 5 Jan 2024 10:16:23 +0000 (+0100) Subject: cpu plugin: Move aggregation into a central finalize() function. X-Git-Tag: 6.0.0-rc0~5^2~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=65deccada65ba6d149c4b1a12471909af803d7a5;p=thirdparty%2Fcollectd.git cpu plugin: Move aggregation into a central finalize() function. --- diff --git a/src/cpu.c b/src/cpu.c index 3d364443b..4472e044b 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -343,8 +343,13 @@ typedef struct { typedef struct { cdtime_t time; + cdtime_t interval; + bool finalized; + usage_state_t *states; size_t states_num; + + usage_state_t global[STATE_MAX]; } usage_t; __attribute__((unused)) static int usage_init(usage_t *u, cdtime_t now) { @@ -352,10 +357,20 @@ __attribute__((unused)) static int usage_init(usage_t *u, cdtime_t now) { return EINVAL; } + if (u->time != 0 && u->time < now) { + u->interval = now - u->time; + } u->time = now; + u->finalized = false; for (size_t i = 0; i < u->states_num; i++) { + u->states[i].rate = 0; u->states[i].has_value = false; } + for (state_t s = 0; s < STATE_MAX; s++) { + u->global[s].rate = 0; + u->global[s].has_value = false; + } + return 0; } @@ -402,80 +417,85 @@ __attribute__((unused)) static int usage_record(usage_t *u, size_t cpu, return 0; } -static gauge_t usage_rate(usage_t u, size_t cpu, state_t state); - -static gauge_t usage_active_rate(usage_t u, size_t cpu) { - size_t index = (cpu * STATE_MAX) + STATE_ACTIVE; - if (index >= u.states_num) { - return NAN; +static void usage_finalize(usage_t *u) { + if (u->finalized) { + return; } - usage_state_t us = u.states[index]; - if (us.has_value) { - return us.rate; - } + size_t cpu_num = u->states_num / STATE_MAX; + for (size_t cpu = 0; cpu < cpu_num; cpu++) { + size_t active_index = (cpu * STATE_MAX) + STATE_ACTIVE; + usage_state_t *active = u->states + active_index; - us.rate = 0; - for (state_t s = 0; s < STATE_IDLE; s++) { - gauge_t rate = usage_rate(u, cpu, s); - if (isnan(rate)) { - continue; - } + active->rate = 0; + active->has_value = false; - us.rate += rate; - us.has_value = true; - } + for (state_t s = 0; s < STATE_ACTIVE; s++) { + size_t index = (cpu * STATE_MAX) + s; + usage_state_t *us = u->states + index; - return us.has_value ? us.rate : NAN; -} + if (!us->has_value) { + continue; + } -static gauge_t usage_global_rate(usage_t u, state_t state) { - size_t cpu_num = u.states_num / STATE_MAX; - usage_state_t us = {0}; - for (size_t i = 0; i < cpu_num; i++) { - gauge_t rate = usage_rate(u, i, state); - if (isnan(rate)) { - continue; + u->global[s].rate += us->rate; + u->global[s].has_value = true; + + if (s != STATE_IDLE) { + active->rate += us->rate; + active->has_value = true; + } } - us.rate += rate; - us.has_value = true; + if (active->has_value) { + u->global[STATE_ACTIVE].rate += active->rate; + u->global[STATE_ACTIVE].has_value = true; + } } - return us.has_value ? us.rate : NAN; + u->finalized = true; } -static gauge_t usage_rate(usage_t u, size_t cpu, state_t state) { - if (state == STATE_ACTIVE) { - return usage_active_rate(u, cpu); - } +static gauge_t usage_rate(usage_t *u, size_t cpu, state_t state) { + usage_finalize(u); size_t index = (cpu * STATE_MAX) + state; - if (index >= u.states_num) { + if (index >= u->states_num) { return NAN; } - usage_state_t us = u.states[index]; + usage_state_t us = u->states[index]; return us.has_value ? us.rate : NAN; } +__attribute__((unused)) static gauge_t usage_active_rate(usage_t *u, + size_t cpu) { + return usage_rate(u, cpu, STATE_ACTIVE); +} + +static gauge_t usage_global_rate(usage_t *u, state_t state) { + usage_finalize(u); + + return u->global[state].has_value ? u->global[state].rate : NAN; +} + __attribute__((unused)) static void usage_reset(usage_t *u) { if (u == NULL) { return; } free(u->states); - u->states = NULL; - u->states_num = 0; + memset(u, 0, sizeof(*u)); } -__attribute__((unused)) static gauge_t usage_ratio(usage_t u, size_t cpu, +__attribute__((unused)) static gauge_t usage_ratio(usage_t *u, size_t cpu, state_t state) { gauge_t global_rate = usage_global_rate(u, STATE_ACTIVE) + usage_global_rate(u, STATE_IDLE); return usage_rate(u, cpu, state) / global_rate; } -__attribute__((unused)) static gauge_t usage_global_ratio(usage_t u, state_t state) { +__attribute__((unused)) static gauge_t usage_global_ratio(usage_t *u, + state_t state) { gauge_t global_rate = usage_global_rate(u, STATE_ACTIVE) + usage_global_rate(u, STATE_IDLE); return usage_global_rate(u, state) / global_rate; diff --git a/src/cpu_test.c b/src/cpu_test.c index 08fe87019..df4c577bf 100644 --- a/src/cpu_test.c +++ b/src/cpu_test.c @@ -32,8 +32,8 @@ DEF_TEST(usage_rate) { usage_record(&usage, 0, STATE_USER, count_t0); // Unable to calculate a rate with a single data point. - EXPECT_EQ_DOUBLE(NAN, usage_rate(usage, 0, STATE_USER)); - EXPECT_EQ_DOUBLE(NAN, usage_rate(usage, 0, STATE_ACTIVE)); + EXPECT_EQ_DOUBLE(NAN, usage_rate(&usage, 0, STATE_USER)); + EXPECT_EQ_DOUBLE(NAN, usage_rate(&usage, 0, STATE_ACTIVE)); cdtime_t t1 = t0 + TIME_T_TO_CDTIME_T(10); derive_t count_t1 = count_t0 + 100; @@ -42,15 +42,15 @@ DEF_TEST(usage_rate) { usage_init(&usage, t1); usage_record(&usage, 0, STATE_USER, count_t1); - EXPECT_EQ_DOUBLE(want_rate, usage_rate(usage, 0, STATE_USER)); - EXPECT_EQ_DOUBLE(want_rate, usage_rate(usage, 0, STATE_ACTIVE)); + EXPECT_EQ_DOUBLE(want_rate, usage_rate(&usage, 0, STATE_USER)); + EXPECT_EQ_DOUBLE(want_rate, usage_rate(&usage, 0, STATE_ACTIVE)); // States that we have not set should be NAN for (state_t s = 0; s < STATE_ACTIVE; s++) { if (s == STATE_USER) { continue; } - EXPECT_EQ_DOUBLE(NAN, usage_rate(usage, 0, s)); + EXPECT_EQ_DOUBLE(NAN, usage_rate(&usage, 0, s)); } usage_reset(&usage); @@ -87,17 +87,17 @@ DEF_TEST(usage_ratio) { active_increment += increment; } gauge_t want_ratio = ((gauge_t)increment) / ((gauge_t)global_increment); - EXPECT_EQ_DOUBLE(want_ratio, usage_ratio(usage, cpu, s)); + EXPECT_EQ_DOUBLE(want_ratio, usage_ratio(&usage, cpu, s)); } gauge_t want_active_ratio = ((gauge_t)active_increment) / ((gauge_t)global_increment); - EXPECT_EQ_DOUBLE(want_active_ratio, usage_ratio(usage, cpu, STATE_ACTIVE)); + EXPECT_EQ_DOUBLE(want_active_ratio, usage_ratio(&usage, cpu, STATE_ACTIVE)); } gauge_t sum = 0; for (size_t cpu = 0; cpu < 4; cpu++) { for (state_t s = 0; s < STATE_ACTIVE; s++) { - gauge_t rate = usage_ratio(usage, cpu, s); + gauge_t rate = usage_ratio(&usage, cpu, s); sum += rate; } } @@ -121,11 +121,11 @@ DEF_TEST(usage_active_rate) { usage_record(&usage, 0, STATE_IDLE, idle_t0); // Unable to calculate a rate with a single data point. - EXPECT_EQ_DOUBLE(NAN, usage_rate(usage, 0, STATE_USER)); - EXPECT_EQ_DOUBLE(NAN, usage_rate(usage, 0, STATE_SYSTEM)); - EXPECT_EQ_DOUBLE(NAN, usage_rate(usage, 0, STATE_IDLE)); - EXPECT_EQ_DOUBLE(NAN, usage_rate(usage, 0, STATE_ACTIVE)); - EXPECT_EQ_DOUBLE(NAN, usage_active_rate(usage, 0)); + EXPECT_EQ_DOUBLE(NAN, usage_rate(&usage, 0, STATE_USER)); + EXPECT_EQ_DOUBLE(NAN, usage_rate(&usage, 0, STATE_SYSTEM)); + EXPECT_EQ_DOUBLE(NAN, usage_rate(&usage, 0, STATE_IDLE)); + EXPECT_EQ_DOUBLE(NAN, usage_rate(&usage, 0, STATE_ACTIVE)); + EXPECT_EQ_DOUBLE(NAN, usage_active_rate(&usage, 0)); cdtime_t t1 = t0 + TIME_T_TO_CDTIME_T(10); derive_t user_t1 = user_t0 + 200; @@ -142,11 +142,11 @@ DEF_TEST(usage_active_rate) { usage_record(&usage, 0, STATE_SYSTEM, syst_t1); usage_record(&usage, 0, STATE_IDLE, idle_t1); - EXPECT_EQ_DOUBLE(want_user_rate, usage_rate(usage, 0, STATE_USER)); - EXPECT_EQ_DOUBLE(want_syst_rate, usage_rate(usage, 0, STATE_SYSTEM)); - EXPECT_EQ_DOUBLE(want_idle_rate, usage_rate(usage, 0, STATE_IDLE)); - EXPECT_EQ_DOUBLE(want_active_rate, usage_rate(usage, 0, STATE_ACTIVE)); - EXPECT_EQ_DOUBLE(want_active_rate, usage_active_rate(usage, 0)); + EXPECT_EQ_DOUBLE(want_user_rate, usage_rate(&usage, 0, STATE_USER)); + EXPECT_EQ_DOUBLE(want_syst_rate, usage_rate(&usage, 0, STATE_SYSTEM)); + EXPECT_EQ_DOUBLE(want_idle_rate, usage_rate(&usage, 0, STATE_IDLE)); + EXPECT_EQ_DOUBLE(want_active_rate, usage_rate(&usage, 0, STATE_ACTIVE)); + EXPECT_EQ_DOUBLE(want_active_rate, usage_active_rate(&usage, 0)); usage_reset(&usage); return 0; @@ -164,10 +164,10 @@ DEF_TEST(usage_global_rate) { usage_record(&usage, 1, STATE_USER, cpu1_t0); // Unable to calculate a rate with a single data point. - EXPECT_EQ_DOUBLE(NAN, usage_rate(usage, 0, STATE_USER)); - EXPECT_EQ_DOUBLE(NAN, usage_rate(usage, 1, STATE_USER)); - EXPECT_EQ_DOUBLE(NAN, usage_global_rate(usage, STATE_USER)); - EXPECT_EQ_DOUBLE(NAN, usage_global_rate(usage, STATE_ACTIVE)); + EXPECT_EQ_DOUBLE(NAN, usage_rate(&usage, 0, STATE_USER)); + EXPECT_EQ_DOUBLE(NAN, usage_rate(&usage, 1, STATE_USER)); + EXPECT_EQ_DOUBLE(NAN, usage_global_rate(&usage, STATE_USER)); + EXPECT_EQ_DOUBLE(NAN, usage_global_rate(&usage, STATE_ACTIVE)); cdtime_t t1 = t0 + TIME_T_TO_CDTIME_T(10); derive_t cpu0_t1 = cpu0_t0 + 300; @@ -181,10 +181,10 @@ DEF_TEST(usage_global_rate) { usage_record(&usage, 0, STATE_USER, cpu0_t1); usage_record(&usage, 1, STATE_USER, cpu1_t1); - EXPECT_EQ_DOUBLE(want_cpu0_rate, usage_rate(usage, 0, STATE_USER)); - EXPECT_EQ_DOUBLE(want_cpu1_rate, usage_rate(usage, 1, STATE_USER)); - EXPECT_EQ_DOUBLE(want_global_rate, usage_global_rate(usage, STATE_USER)); - EXPECT_EQ_DOUBLE(want_global_rate, usage_global_rate(usage, STATE_ACTIVE)); + EXPECT_EQ_DOUBLE(want_cpu0_rate, usage_rate(&usage, 0, STATE_USER)); + EXPECT_EQ_DOUBLE(want_cpu1_rate, usage_rate(&usage, 1, STATE_USER)); + EXPECT_EQ_DOUBLE(want_global_rate, usage_global_rate(&usage, STATE_USER)); + EXPECT_EQ_DOUBLE(want_global_rate, usage_global_rate(&usage, STATE_ACTIVE)); usage_reset(&usage); return 0; @@ -221,7 +221,7 @@ DEF_TEST(usage_global_ratio) { } gauge_t want_state_ratio = ((gauge_t)state_increment) / ((gauge_t)global_increment); - EXPECT_EQ_DOUBLE(want_state_ratio, usage_global_ratio(usage, s)); + EXPECT_EQ_DOUBLE(want_state_ratio, usage_global_ratio(&usage, s)); if (s != STATE_IDLE) { global_active_increment += state_increment; @@ -230,10 +230,10 @@ DEF_TEST(usage_global_ratio) { gauge_t want_global_active_ratio = ((gauge_t)global_active_increment) / ((gauge_t)global_increment); EXPECT_EQ_DOUBLE(want_global_active_ratio, - usage_global_ratio(usage, STATE_ACTIVE)); + usage_global_ratio(&usage, STATE_ACTIVE)); EXPECT_EQ_DOUBLE(1.0 - want_global_active_ratio, - usage_global_ratio(usage, STATE_IDLE)); + usage_global_ratio(&usage, STATE_IDLE)); usage_reset(&usage); return 0;