1/* 2 * Copyright 2016, General Dynamics C4 Systems 3 * 4 * This software may be distributed and modified according to the terms of 5 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 6 * See "LICENSE_GPLv2.txt" for details. 7 * 8 * @TAG(GD_GPL) 9 */ 10 11#ifndef BENCHMARK_UTILISATION_H 12#define BENCHMARK_UTILISATION_H 13 14#include <config.h> 15#include <arch/benchmark.h> 16#include <benchmark/benchmark_utilisation_types.h> 17#include <arch/api/constants.h> 18#include <model/statedata.h> 19 20#ifdef CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT 21#include <armv/benchmark_irqHandler.h> 22#endif /* CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT */ 23 24#ifdef CONFIG_BENCHMARK_TRACK_UTILISATION 25extern bool_t benchmark_log_utilisation_enabled; 26extern timestamp_t ksEnter; 27extern timestamp_t benchmark_start_time; 28extern timestamp_t benchmark_end_time; 29 30void benchmark_track_utilisation_dump(void); 31 32void benchmark_track_reset_utilisation(void); 33/* Calculate and add the utilisation time from when the heir started to run i.e. scheduled 34 * and until it's being kicked off 35 */ 36static inline void benchmark_utilisation_switch(tcb_t *heir, tcb_t *next) 37{ 38 /* Add heir thread utilisation */ 39 if (likely(benchmark_log_utilisation_enabled)) { 40 41 /* Check if an overflow occurred while we have been in the kernel */ 42 if (likely(ksEnter > heir->benchmark.schedule_start_time)) { 43 44 heir->benchmark.utilisation += (ksEnter - heir->benchmark.schedule_start_time); 45 46 } else { 47#ifdef CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT 48 heir->benchmark.utilisation += (0xFFFFFFFFU - heir->benchmark.schedule_start_time) + ksEnter; 49 armv_handleOverflowIRQ(); 50#endif /* CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT */ 51 } 52 53 /* Reset next thread utilisation */ 54 next->benchmark.schedule_start_time = ksEnter; 55 56 } 57} 58 59static inline void benchmark_utilisation_kentry_stamp(void) 60{ 61 ksEnter = timestamp(); 62} 63 64/* Add the time between the last thread got scheduled and when to stop 65 * benchmarks 66 */ 67static inline void benchmark_utilisation_finalise(void) 68{ 69 /* Add the time between when NODE_STATE(ksCurThread), and benchmark finalise */ 70 benchmark_utilisation_switch(NODE_STATE(ksCurThread), NODE_STATE(ksIdleThread)); 71 72 benchmark_end_time = ksEnter; 73 benchmark_log_utilisation_enabled = false; 74} 75 76#endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */ 77#endif /* BENCHMARK_UTILISATION_H */ 78