blob: 9397a258b5ab8e64e4dfc91d33f0dfd84b1f8c18 [file] [log] [blame]
/*
* Copyright (c) 2023 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* @file
* This file contains routines for implementing a timestamp system call
* as well as routines for determining the overhead associated with it.
*/
#include <zephyr/kernel.h>
#include "utils.h"
#include "timing_sc.h"
BENCH_BMEM uint64_t timestamp_overhead;
#ifdef CONFIG_USERSPACE
BENCH_BMEM uint64_t user_timestamp_overhead;
#endif
timing_t z_impl_timing_timestamp_get(void)
{
return timing_counter_get();
}
#ifdef CONFIG_USERSPACE
timing_t z_vrfy_timing_timestamp_get(void)
{
return z_impl_timing_timestamp_get();
}
#include <syscalls/timing_timestamp_get_mrsh.c>
#endif
static void start_thread_entry(void *p1, void *p2, void *p3)
{
uint32_t num_iterations = (uint32_t)(uintptr_t)p1;
timing_t start;
timing_t finish;
ARG_UNUSED(p2);
ARG_UNUSED(p3);
start = timing_timestamp_get();
for (uint32_t i = 0; i < num_iterations; i++) {
timing_timestamp_get();
}
finish = timing_timestamp_get();
timestamp.cycles = timing_cycles_get(&start, &finish);
}
void timestamp_overhead_init(uint32_t num_iterations)
{
int priority;
priority = k_thread_priority_get(k_current_get());
k_thread_create(&start_thread, start_stack,
K_THREAD_STACK_SIZEOF(start_stack),
start_thread_entry,
(void *)(uintptr_t)num_iterations, NULL, NULL,
priority - 1, 0, K_FOREVER);
k_thread_start(&start_thread);
k_thread_join(&start_thread, K_FOREVER);
timestamp_overhead = timestamp.cycles;
#ifdef CONFIG_USERSPACE
k_thread_create(&start_thread, start_stack,
K_THREAD_STACK_SIZEOF(start_stack),
start_thread_entry,
(void *)(uintptr_t)num_iterations, NULL, NULL,
priority - 1, K_USER, K_FOREVER);
k_thread_start(&start_thread);
k_thread_join(&start_thread, K_FOREVER);
user_timestamp_overhead = timestamp.cycles;
#endif
}
uint64_t timestamp_overhead_adjustment(uint32_t options1, uint32_t options2)
{
#ifdef CONFIG_USERSPACE
if (((options1 | options2) & K_USER) == K_USER) {
if (((options1 & options2) & K_USER) == K_USER) {
/*
* Both start and finish timestamps were obtained
* from userspace.
*/
return user_timestamp_overhead;
}
/*
* One timestamp came from userspace, and the other came
* from kernel space. Estimate the overhead as the mean
* between the two.
*/
return (timestamp_overhead + user_timestamp_overhead) / 2;
}
#endif
/*
* Both start and finish timestamps were obtained
* from kernel space.
*/
return timestamp_overhead;
}