1 /*
2  * Copyright (c) 2025 Analog Devices, Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/logging/log.h>
9 
10 LOG_MODULE_REGISTER(cpu_load_metric, CONFIG_CPU_LOAD_LOG_LEVEL);
11 
12 static uint64_t execution_cycles_prev[CONFIG_MP_MAX_NUM_CPUS];
13 static uint64_t total_cycles_prev[CONFIG_MP_MAX_NUM_CPUS];
14 
15 static struct k_spinlock lock[CONFIG_MP_MAX_NUM_CPUS];
16 
cpu_load_metric_get(int cpu_id)17 int cpu_load_metric_get(int cpu_id)
18 {
19 	int ret;
20 	int load;
21 	uint64_t execution_cycles;
22 	uint64_t total_cycles;
23 	k_spinlock_key_t key;
24 
25 	struct k_thread_runtime_stats cpu_query;
26 
27 	ret = k_thread_runtime_stats_cpu_get(cpu_id, &cpu_query);
28 	if (ret) {
29 		LOG_ERR("Could not retrieve runtime statistics from scheduler");
30 		return ret;
31 	}
32 
33 	key = k_spin_lock(&lock[cpu_id]);
34 
35 	execution_cycles = cpu_query.execution_cycles - execution_cycles_prev[cpu_id];
36 	total_cycles = cpu_query.total_cycles - total_cycles_prev[cpu_id];
37 
38 	execution_cycles_prev[cpu_id] = cpu_query.execution_cycles;
39 	total_cycles_prev[cpu_id] = cpu_query.total_cycles;
40 
41 	k_spin_unlock(&lock[cpu_id], key);
42 
43 	LOG_DBG("CPU%d Execution cycles: %llu, Total cycles: %llu",
44 		cpu_id, execution_cycles, total_cycles);
45 
46 	if (execution_cycles == 0) {
47 		load = 0;
48 	} else {
49 		load = (int)((100 * total_cycles) / execution_cycles);
50 	}
51 
52 	return load;
53 }
54