1 /* 2 * Copyright 2016, General Dynamics C4 Systems 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 */ 6 7 #include <config.h> 8 #include <benchmark/benchmark_utilisation.h> 9 10 #ifdef CONFIG_BENCHMARK_TRACK_UTILISATION 11 12 timestamp_t ksEnter; 13 benchmark_track_utilisation_dump(void)14void benchmark_track_utilisation_dump(void) 15 { 16 uint64_t *buffer = ((uint64_t *) & (((seL4_IPCBuffer *)lookupIPCBuffer(true, NODE_STATE(ksCurThread)))->msg[0])); 17 tcb_t *tcb = NULL; 18 word_t tcb_cptr = getRegister(NODE_STATE(ksCurThread), capRegister); 19 lookupCap_ret_t lu_ret; 20 word_t cap_type; 21 22 lu_ret = lookupCap(NODE_STATE(ksCurThread), tcb_cptr); 23 /* ensure we got a TCB cap */ 24 cap_type = cap_get_capType(lu_ret.cap); 25 if (cap_type != cap_thread_cap) { 26 userError("SysBenchmarkFinalizeLog: cap is not a TCB, halting"); 27 return; 28 } 29 30 tcb = TCB_PTR(cap_thread_cap_get_capTCBPtr(lu_ret.cap)); 31 32 /* Selected TCB counters */ 33 buffer[BENCHMARK_TCB_UTILISATION] = tcb->benchmark.utilisation; /* Requested thread utilisation */ 34 buffer[BENCHMARK_TCB_NUMBER_SCHEDULES] = tcb->benchmark.number_schedules; /* Number of times scheduled */ 35 buffer[BENCHMARK_TCB_KERNEL_UTILISATION] = tcb->benchmark.kernel_utilisation; /* Utilisation spent in kernel */ 36 buffer[BENCHMARK_TCB_NUMBER_KERNEL_ENTRIES] = tcb->benchmark.number_kernel_entries; /* Number of kernel entries */ 37 38 /* Idle counters */ 39 buffer[BENCHMARK_IDLE_LOCALCPU_UTILISATION] = NODE_STATE( 40 ksIdleThread)->benchmark.utilisation; /* Idle thread utilisation of current CPU */ 41 #ifdef ENABLE_SMP_SUPPORT 42 buffer[BENCHMARK_IDLE_TCBCPU_UTILISATION] = NODE_STATE_ON_CORE(ksIdleThread, 43 tcb->tcbAffinity)->benchmark.utilisation; /* Idle thread utilisation of CPU the TCB is running on */ 44 #else 45 buffer[BENCHMARK_IDLE_TCBCPU_UTILISATION] = buffer[BENCHMARK_IDLE_LOCALCPU_UTILISATION]; 46 #endif 47 48 buffer[BENCHMARK_IDLE_NUMBER_SCHEDULES] = NODE_STATE( 49 ksIdleThread)->benchmark.number_schedules; /* Number of times scheduled */ 50 buffer[BENCHMARK_IDLE_KERNEL_UTILISATION] = NODE_STATE( 51 ksIdleThread)->benchmark.kernel_utilisation; /* Utilisation spent in kernel */ 52 buffer[BENCHMARK_IDLE_NUMBER_KERNEL_ENTRIES] = NODE_STATE( 53 ksIdleThread)->benchmark.number_kernel_entries; /* Number of kernel entries */ 54 55 56 /* Total counters */ 57 #ifdef CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT 58 buffer[BENCHMARK_TOTAL_UTILISATION] = 59 (NODE_STATE(ccnt_num_overflows) * 0xFFFFFFFFU) + NODE_STATE(benchmark_end_time) - NODE_STATE(benchmark_start_time); 60 #else 61 buffer[BENCHMARK_TOTAL_UTILISATION] = NODE_STATE(benchmark_end_time) - NODE_STATE( 62 benchmark_start_time); /* Overall time */ 63 #endif /* CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT */ 64 buffer[BENCHMARK_TOTAL_NUMBER_SCHEDULES] = NODE_STATE(benchmark_kernel_number_schedules); 65 buffer[BENCHMARK_TOTAL_KERNEL_UTILISATION] = NODE_STATE(benchmark_kernel_time); 66 buffer[BENCHMARK_TOTAL_NUMBER_KERNEL_ENTRIES] = NODE_STATE(benchmark_kernel_number_entries); 67 68 } 69 benchmark_track_reset_utilisation(tcb_t * tcb)70void benchmark_track_reset_utilisation(tcb_t *tcb) 71 { 72 tcb->benchmark.utilisation = 0; 73 tcb->benchmark.number_schedules = 0; 74 tcb->benchmark.number_kernel_entries = 0; 75 tcb->benchmark.kernel_utilisation = 0; 76 tcb->benchmark.schedule_start_time = 0; 77 } 78 #endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */ 79