1 /*
2  * Copyright 2016, General Dynamics C4 Systems
3  *
4  * SPDX-License-Identifier: GPL-2.0-only
5  */
6 
7 #pragma once
8 
9 #include <config.h>
10 #include <arch/benchmark.h>
11 #include <sel4/benchmark_utilisation_types.h>
12 #include <sel4/arch/constants.h>
13 #include <model/statedata.h>
14 
15 #ifdef CONFIG_BENCHMARK_TRACK_UTILISATION
16 extern timestamp_t ksEnter;
17 
18 void benchmark_track_utilisation_dump(void);
19 
20 void benchmark_track_reset_utilisation(tcb_t *tcb);
21 /* Calculate and add the utilisation time from when the heir started to run i.e. scheduled
22  * and until it's being kicked off
23  */
benchmark_utilisation_switch(tcb_t * heir,tcb_t * next)24 static inline void benchmark_utilisation_switch(tcb_t *heir, tcb_t *next)
25 {
26     /* Add heir thread utilisation */
27     if (likely(NODE_STATE(benchmark_log_utilisation_enabled))) {
28 
29         /* Check if an overflow occurred while we have been in the kernel */
30         if (likely(ksEnter > heir->benchmark.schedule_start_time)) {
31 
32             heir->benchmark.utilisation += (ksEnter - heir->benchmark.schedule_start_time);
33 
34         } else {
35 #ifdef CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT
36             heir->benchmark.utilisation += (UINT32_MAX - heir->benchmark.schedule_start_time) + ksEnter;
37             armv_handleOverflowIRQ();
38 #endif /* CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT */
39         }
40 
41         /* Reset next thread utilisation */
42         next->benchmark.schedule_start_time = ksEnter;
43         next->benchmark.number_schedules++;
44         NODE_STATE(benchmark_kernel_number_schedules)++;
45 
46     }
47 }
48 
49 /* Add the time between the last thread got scheduled and when to stop
50  * benchmarks
51  */
benchmark_utilisation_finalise(void)52 static inline void benchmark_utilisation_finalise(void)
53 {
54     /* Add the time between when NODE_STATE(ksCurThread), and benchmark finalise */
55     benchmark_utilisation_switch(NODE_STATE(ksCurThread), NODE_STATE(ksIdleThread));
56 
57     NODE_STATE(benchmark_end_time) = ksEnter;
58     NODE_STATE(benchmark_log_utilisation_enabled) = false;
59 }
60 
61 #endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
62