Files
seL4/src/benchmark/benchmark.c
Nataliya Korovkina 756a37b7d3 benchmark: config opt. name to enable log buffer
The latest code updates introduced CONFIG_ENABLE_KERNEL_LOG_BUFFER
meanwhile other code and config.cmake keeps using
CONFIG_KERNEL_LOG_BUFFER

Signed-off-by: Nataliya Korovkina <malus.brandywine@gmail.com>
2022-03-31 08:56:06 +11:00

157 lines
5.2 KiB
C

/*
* Copyright 2016, General Dynamics C4 Systems
*
* SPDX-License-Identifier: GPL-2.0-only
*/
#include <config.h>
#ifdef CONFIG_ENABLE_BENCHMARKS
#include <types.h>
#include <mode/machine.h>
#include <benchmark/benchmark.h>
#include <benchmark/benchmark_utilisation.h>
exception_t handle_SysBenchmarkFlushCaches(void)
{
#ifdef CONFIG_ARCH_ARM
tcb_t *thread = NODE_STATE(ksCurThread);
if (getRegister(thread, capRegister)) {
arch_clean_invalidate_L1_caches(getRegister(thread, msgInfoRegister));
} else {
arch_clean_invalidate_caches();
}
#else
arch_clean_invalidate_caches();
#endif
return EXCEPTION_NONE;
}
exception_t handle_SysBenchmarkResetLog(void)
{
#ifdef CONFIG_KERNEL_LOG_BUFFER
if (ksUserLogBuffer == 0) {
userError("A user-level buffer has to be set before resetting benchmark.\
Use seL4_BenchmarkSetLogBuffer\n");
setRegister(NODE_STATE(ksCurThread), capRegister, seL4_IllegalOperation);
return EXCEPTION_SYSCALL_ERROR;
}
ksLogIndex = 0;
#endif /* CONFIG_KERNEL_LOG_BUFFER */
#ifdef CONFIG_BENCHMARK_TRACK_UTILISATION
NODE_STATE(benchmark_log_utilisation_enabled) = true;
benchmark_track_reset_utilisation(NODE_STATE(ksIdleThread));
NODE_STATE(ksCurThread)->benchmark.schedule_start_time = ksEnter;
NODE_STATE(ksCurThread)->benchmark.number_schedules++;
NODE_STATE(benchmark_start_time) = ksEnter;
NODE_STATE(benchmark_kernel_time) = 0;
NODE_STATE(benchmark_kernel_number_entries) = 0;
NODE_STATE(benchmark_kernel_number_schedules) = 1;
benchmark_arch_utilisation_reset();
#endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
setRegister(NODE_STATE(ksCurThread), capRegister, seL4_NoError);
return EXCEPTION_NONE;
}
exception_t handle_SysBenchmarkFinalizeLog(void)
{
#ifdef CONFIG_KERNEL_LOG_BUFFER
ksLogIndexFinalized = ksLogIndex;
setRegister(NODE_STATE(ksCurThread), capRegister, ksLogIndexFinalized);
#endif /* CONFIG_KERNEL_LOG_BUFFER */
#ifdef CONFIG_BENCHMARK_TRACK_UTILISATION
benchmark_utilisation_finalise();
#endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
return EXCEPTION_NONE;
}
#ifdef CONFIG_KERNEL_LOG_BUFFER
exception_t handle_SysBenchmarkSetLogBuffer(void)
{
word_t cptr_userFrame = getRegister(NODE_STATE(ksCurThread), capRegister);
if (benchmark_arch_map_logBuffer(cptr_userFrame) != EXCEPTION_NONE) {
setRegister(NODE_STATE(ksCurThread), capRegister, seL4_IllegalOperation);
return EXCEPTION_SYSCALL_ERROR;
}
setRegister(NODE_STATE(ksCurThread), capRegister, seL4_NoError);
return EXCEPTION_NONE;
}
#endif /* CONFIG_KERNEL_LOG_BUFFER */
#ifdef CONFIG_BENCHMARK_TRACK_UTILISATION
exception_t handle_SysBenchmarkGetThreadUtilisation(void)
{
benchmark_track_utilisation_dump();
return EXCEPTION_NONE;
}
exception_t handle_SysBenchmarkResetThreadUtilisation(void)
{
word_t tcb_cptr = getRegister(NODE_STATE(ksCurThread), capRegister);
lookupCap_ret_t lu_ret;
word_t cap_type;
lu_ret = lookupCap(NODE_STATE(ksCurThread), tcb_cptr);
/* ensure we got a TCB cap */
cap_type = cap_get_capType(lu_ret.cap);
if (cap_type != cap_thread_cap) {
userError("SysBenchmarkResetThreadUtilisation: cap is not a TCB, halting");
return EXCEPTION_NONE;
}
tcb_t *tcb = TCB_PTR(cap_thread_cap_get_capTCBPtr(lu_ret.cap));
benchmark_track_reset_utilisation(tcb);
return EXCEPTION_NONE;
}
#ifdef CONFIG_DEBUG_BUILD
exception_t handle_SysBenchmarkDumpAllThreadsUtilisation(void)
{
printf("{\n");
printf(" \"BENCHMARK_TOTAL_UTILISATION\":%lu,\n",
(word_t)(NODE_STATE(benchmark_end_time) - NODE_STATE(benchmark_start_time)));
printf(" \"BENCHMARK_TOTAL_KERNEL_UTILISATION\":%lu,\n", (word_t) NODE_STATE(benchmark_kernel_time));
printf(" \"BENCHMARK_TOTAL_NUMBER_KERNEL_ENTRIES\":%lu,\n", (word_t) NODE_STATE(benchmark_kernel_number_entries));
printf(" \"BENCHMARK_TOTAL_NUMBER_SCHEDULES\":%lu,\n", (word_t) NODE_STATE(benchmark_kernel_number_schedules));
printf(" \"BENCHMARK_TCB_\": [\n");
for (tcb_t *curr = NODE_STATE(ksDebugTCBs); curr != NULL; curr = TCB_PTR_DEBUG_PTR(curr)->tcbDebugNext) {
printf(" {\n");
printf(" \"NAME\":\"%s\",\n", TCB_PTR_DEBUG_PTR(curr)->tcbName);
printf(" \"UTILISATION\":%lu,\n", (word_t) curr->benchmark.utilisation);
printf(" \"NUMBER_SCHEDULES\":%lu,\n", (word_t) curr->benchmark.number_schedules);
printf(" \"KERNEL_UTILISATION\":%lu,\n", (word_t) curr->benchmark.kernel_utilisation);
printf(" \"NUMBER_KERNEL_ENTRIES\":%lu\n", (word_t) curr->benchmark.number_kernel_entries);
printf(" }");
if (TCB_PTR_DEBUG_PTR(curr)->tcbDebugNext != NULL) {
printf(",\n");
} else {
printf("\n");
}
}
printf(" ]\n}\n");
return EXCEPTION_NONE;
}
exception_t handle_SysBenchmarkResetAllThreadsUtilisation(void)
{
for (tcb_t *curr = NODE_STATE(ksDebugTCBs); curr != NULL; curr = TCB_PTR_DEBUG_PTR(curr)->tcbDebugNext) {
benchmark_track_reset_utilisation(curr);
}
return EXCEPTION_NONE;
}
#endif /* CONFIG_DEBUG_BUILD */
#endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
#endif /* CONFIG_ENABLE_BENCHMARKS */