tests: latency_measure: Add events
Adds events to the latency_measure benchmark. Signed-off-by: Peter Mitsis <peter.mitsis@intel.com>
This commit is contained in:
parent
de855162a7
commit
a8914c56d2
5 changed files with 306 additions and 3 deletions
|
@ -27,3 +27,6 @@ CONFIG_APPLICATION_DEFINED_SYSCALL=y
|
|||
|
||||
# Disable time slicing
|
||||
CONFIG_TIMESLICING=n
|
||||
|
||||
# Enable events
|
||||
CONFIG_EVENTS=y
|
||||
|
|
|
@ -28,3 +28,6 @@ CONFIG_USERSPACE=y
|
|||
|
||||
# Disable time slicing
|
||||
CONFIG_TIMESLICING=n
|
||||
|
||||
# Enable events
|
||||
CONFIG_EVENTS=y
|
||||
|
|
282
tests/benchmarks/latency_measure/src/events.c
Normal file
282
tests/benchmarks/latency_measure/src/events.c
Normal file
|
@ -0,0 +1,282 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file measure time for various event operations
|
||||
*
|
||||
* This file contains the tests that measure the times for manipulating
|
||||
* event objects from both kernel and user threads:
|
||||
* 1. Immediately posting and setting events
|
||||
* 2. Immediately receiving any or all events.
|
||||
* 3. Blocking to receive either any or all events.
|
||||
* 4. Waking (and switching to) a thread waiting for any or all events.
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/timing/timing.h>
|
||||
#include "utils.h"
|
||||
#include "timing_sc.h"
|
||||
|
||||
#define BENCH_EVENT_SET 0x1234
|
||||
#define ALL_EVENTS 0xFFFFFFFF
|
||||
|
||||
static K_EVENT_DEFINE(event_set);
|
||||
|
||||
static void event_ops_entry(void *p1, void *p2, void *p3)
|
||||
{
|
||||
uint32_t num_iterations = (uint32_t)(uintptr_t)p1;
|
||||
uint32_t options = (uint32_t)(uintptr_t)p2;
|
||||
timing_t start;
|
||||
timing_t finish;
|
||||
uint32_t i;
|
||||
uint64_t cycles;
|
||||
char description[80];
|
||||
|
||||
k_event_clear(&event_set, ALL_EVENTS);
|
||||
|
||||
start = timing_timestamp_get();
|
||||
for (i = 0; i < num_iterations; i++) {
|
||||
k_event_post(&event_set, BENCH_EVENT_SET);
|
||||
}
|
||||
finish = timing_timestamp_get();
|
||||
|
||||
snprintf(description, sizeof(description),
|
||||
"EVENTS post.immediate.%s",
|
||||
(options & K_USER) ? "user" : "kernel");
|
||||
cycles = timing_cycles_get(&start, &finish);
|
||||
PRINT_STATS_AVG(description, (uint32_t)cycles,
|
||||
num_iterations, false, "");
|
||||
|
||||
start = timing_timestamp_get();
|
||||
for (i = 0; i < num_iterations; i++) {
|
||||
k_event_set(&event_set, BENCH_EVENT_SET);
|
||||
}
|
||||
finish = timing_timestamp_get();
|
||||
|
||||
snprintf(description, sizeof(description),
|
||||
"EVENTS set.immediate.%s",
|
||||
(options & K_USER) ? "user" : "kernel");
|
||||
cycles = timing_cycles_get(&start, &finish);
|
||||
PRINT_STATS_AVG(description, (uint32_t)cycles,
|
||||
num_iterations, false, "");
|
||||
|
||||
start = timing_timestamp_get();
|
||||
for (i = 0; i < num_iterations; i++) {
|
||||
k_event_wait(&event_set, BENCH_EVENT_SET, false, K_FOREVER);
|
||||
}
|
||||
finish = timing_timestamp_get();
|
||||
|
||||
snprintf(description, sizeof(description),
|
||||
"EVENTS wait.immediate.%s",
|
||||
(options & K_USER) ? "user" : "kernel");
|
||||
cycles = timing_cycles_get(&start, &finish);
|
||||
PRINT_STATS_AVG(description, (uint32_t)cycles,
|
||||
num_iterations, false, "");
|
||||
|
||||
start = timing_timestamp_get();
|
||||
for (i = 0; i < num_iterations; i++) {
|
||||
k_event_wait_all(&event_set, BENCH_EVENT_SET, false, K_FOREVER);
|
||||
}
|
||||
finish = timing_timestamp_get();
|
||||
|
||||
snprintf(description, sizeof(description),
|
||||
"EVENTS wait_all.immediate.%s",
|
||||
(options & K_USER) ? "user" : "kernel");
|
||||
cycles = timing_cycles_get(&start, &finish);
|
||||
PRINT_STATS_AVG(description, (uint32_t)cycles,
|
||||
num_iterations, false, "");
|
||||
}
|
||||
|
||||
static void start_thread_entry(void *p1, void *p2, void *p3)
|
||||
{
|
||||
uint32_t num_iterations = (uint32_t)(uintptr_t)p1;
|
||||
uint32_t options = (uint32_t)(uintptr_t)p2;
|
||||
uint32_t alt_options = (uint32_t)(uintptr_t)p3;
|
||||
uint32_t i;
|
||||
uint64_t cycles;
|
||||
char description[80];
|
||||
|
||||
k_thread_start(&alt_thread);
|
||||
|
||||
for (i = 0; i < num_iterations; i++) {
|
||||
|
||||
/* 2. Set the events to wake alt_thread */
|
||||
|
||||
timestamp.sample = timing_timestamp_get();
|
||||
k_event_set(&event_set, BENCH_EVENT_SET);
|
||||
}
|
||||
|
||||
snprintf(description, sizeof(description),
|
||||
"EVENTS wait.blocking.(%c -> %c)",
|
||||
(alt_options & K_USER) ? 'U' : 'K',
|
||||
(options & K_USER) ? 'U' : 'K');
|
||||
cycles = timestamp.cycles -
|
||||
timestamp_overhead_adjustment(options, alt_options);
|
||||
PRINT_STATS_AVG(description, (uint32_t)cycles,
|
||||
num_iterations, false, "");
|
||||
k_sem_give(&pause_sem);
|
||||
|
||||
snprintf(description, sizeof(description),
|
||||
"EVENTS set.wake+ctx.(%c -> %c)",
|
||||
(options & K_USER) ? 'U' : 'K',
|
||||
(alt_options & K_USER) ? 'U' : 'K');
|
||||
cycles = timestamp.cycles -
|
||||
timestamp_overhead_adjustment(options, alt_options);
|
||||
PRINT_STATS_AVG(description, (uint32_t)cycles,
|
||||
num_iterations, false, "");
|
||||
k_sem_give(&pause_sem);
|
||||
|
||||
for (i = 0; i < num_iterations; i++) {
|
||||
|
||||
/* 5. Post the events to wake alt_thread */
|
||||
|
||||
timestamp.sample = timing_timestamp_get();
|
||||
k_event_post(&event_set, BENCH_EVENT_SET);
|
||||
}
|
||||
|
||||
snprintf(description, sizeof(description),
|
||||
"EVENTS wait_all.blocking.(%c -> %c)",
|
||||
(alt_options & K_USER) ? 'U' : 'K',
|
||||
(options & K_USER) ? 'U' : 'K');
|
||||
cycles = timestamp.cycles;
|
||||
PRINT_STATS_AVG(description, (uint32_t)cycles,
|
||||
num_iterations, false, "");
|
||||
k_sem_give(&pause_sem);
|
||||
|
||||
snprintf(description, sizeof(description),
|
||||
"EVENTS post.wake+ctx.(%c -> %c)",
|
||||
(options & K_USER) ? 'U' : 'K',
|
||||
(alt_options & K_USER) ? 'U' : 'K');
|
||||
cycles = timestamp.cycles;
|
||||
PRINT_STATS_AVG(description, (uint32_t)cycles,
|
||||
num_iterations, false, "");
|
||||
|
||||
k_thread_join(&alt_thread, K_FOREVER);
|
||||
}
|
||||
|
||||
static void alt_thread_entry(void *p1, void *p2, void *p3)
|
||||
{
|
||||
uint32_t num_iterations = (uint32_t)(uintptr_t)p1;
|
||||
uint32_t i;
|
||||
timing_t start;
|
||||
timing_t mid;
|
||||
timing_t finish;
|
||||
uint64_t sum1 = 0ULL;
|
||||
uint64_t sum2 = 0ULL;
|
||||
|
||||
for (i = 0; i < num_iterations; i++) {
|
||||
|
||||
/* 1. Wait for any of the events */
|
||||
|
||||
start = timing_timestamp_get();
|
||||
k_event_wait(&event_set, BENCH_EVENT_SET, true, K_FOREVER);
|
||||
|
||||
/* 3. Record the final timestamp */
|
||||
|
||||
finish = timing_timestamp_get();
|
||||
mid = timestamp.sample;
|
||||
|
||||
sum1 += timing_cycles_get(&start, &mid);
|
||||
sum2 += timing_cycles_get(&mid, &finish);
|
||||
}
|
||||
|
||||
/* Let start_thread print the results */
|
||||
|
||||
timestamp.cycles = sum1;
|
||||
k_sem_take(&pause_sem, K_FOREVER);
|
||||
|
||||
timestamp.cycles = sum2;
|
||||
k_sem_take(&pause_sem, K_FOREVER);
|
||||
|
||||
sum1 = 0ULL;
|
||||
sum2 = 0ULL;
|
||||
|
||||
for (i = 0; i < num_iterations; i++) {
|
||||
|
||||
/* 4. Wait for all of the events */
|
||||
|
||||
start = timing_timestamp_get();
|
||||
k_event_wait_all(&event_set, BENCH_EVENT_SET, true, K_FOREVER);
|
||||
|
||||
/* 6. Record the final timestamp */
|
||||
|
||||
finish = timing_timestamp_get();
|
||||
mid = timestamp.sample;
|
||||
|
||||
sum1 += timing_cycles_get(&start, &mid);
|
||||
sum2 += timing_cycles_get(&mid, &finish);
|
||||
}
|
||||
|
||||
/* Let start_thread print the results */
|
||||
|
||||
timestamp.cycles = sum1;
|
||||
k_sem_take(&pause_sem, K_FOREVER);
|
||||
|
||||
timestamp.cycles = sum2;
|
||||
}
|
||||
|
||||
int event_ops(uint32_t num_iterations, uint32_t options)
|
||||
{
|
||||
int priority;
|
||||
|
||||
priority = k_thread_priority_get(k_current_get());
|
||||
|
||||
timing_start();
|
||||
|
||||
k_thread_create(&start_thread, start_stack,
|
||||
K_THREAD_STACK_SIZEOF(start_stack),
|
||||
event_ops_entry,
|
||||
(void *)(uintptr_t)num_iterations,
|
||||
(void *)(uintptr_t)options, NULL,
|
||||
priority - 1, options, K_FOREVER);
|
||||
|
||||
k_thread_access_grant(&start_thread, &event_set);
|
||||
|
||||
k_thread_start(&start_thread);
|
||||
|
||||
k_thread_join(&start_thread, K_FOREVER);
|
||||
|
||||
timing_stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int event_blocking_ops(uint32_t num_iterations, uint32_t start_options,
|
||||
uint32_t alt_options)
|
||||
{
|
||||
int priority;
|
||||
|
||||
priority = k_thread_priority_get(k_current_get());
|
||||
|
||||
timing_start();
|
||||
|
||||
k_thread_create(&start_thread, start_stack,
|
||||
K_THREAD_STACK_SIZEOF(start_stack),
|
||||
start_thread_entry,
|
||||
(void *)(uintptr_t)num_iterations,
|
||||
(void *)(uintptr_t)start_options,
|
||||
(void *)(uintptr_t)alt_options,
|
||||
priority - 1, start_options, K_FOREVER);
|
||||
|
||||
k_thread_create(&alt_thread, alt_stack,
|
||||
K_THREAD_STACK_SIZEOF(alt_stack),
|
||||
alt_thread_entry,
|
||||
(void *)(uintptr_t)num_iterations,
|
||||
(void *)(uintptr_t)alt_options, NULL,
|
||||
priority - 2, alt_options, K_FOREVER);
|
||||
|
||||
k_thread_access_grant(&start_thread, &alt_thread, &event_set,
|
||||
&pause_sem);
|
||||
k_thread_access_grant(&alt_thread, &event_set, &pause_sem);
|
||||
|
||||
k_thread_start(&start_thread);
|
||||
|
||||
k_thread_join(&start_thread, K_FOREVER);
|
||||
|
||||
timing_stop();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -29,7 +29,7 @@ K_APPMEM_PARTITION_DEFINE(bench_mem_partition);
|
|||
#endif
|
||||
|
||||
K_THREAD_STACK_DEFINE(start_stack, START_STACK_SIZE);
|
||||
K_THREAD_STACK_DEFINE(alt_stack, START_STACK_SIZE);
|
||||
K_THREAD_STACK_DEFINE(alt_stack, ALT_STACK_SIZE);
|
||||
|
||||
K_SEM_DEFINE(pause_sem, 0, 1);
|
||||
|
||||
|
@ -52,6 +52,9 @@ extern int fifo_blocking_ops(uint32_t num_iterations, uint32_t start_options,
|
|||
extern int lifo_ops(uint32_t num_iterations, uint32_t options);
|
||||
extern int lifo_blocking_ops(uint32_t num_iterations, uint32_t start_options,
|
||||
uint32_t alt_options);
|
||||
extern int event_ops(uint32_t num_iterations, uint32_t options);
|
||||
extern int event_blocking_ops(uint32_t num_iterations, uint32_t start_options,
|
||||
uint32_t alt_options);
|
||||
extern void heap_malloc_free(void);
|
||||
|
||||
static void test_thread(void *arg1, void *arg2, void *arg3)
|
||||
|
@ -120,6 +123,18 @@ static void test_thread(void *arg1, void *arg2, void *arg3)
|
|||
lifo_blocking_ops(NUM_ITERATIONS, K_USER, K_USER);
|
||||
#endif
|
||||
|
||||
event_ops(NUM_ITERATIONS, 0);
|
||||
#ifdef CONFIG_USERSPACE
|
||||
event_ops(NUM_ITERATIONS, K_USER);
|
||||
#endif
|
||||
|
||||
event_blocking_ops(NUM_ITERATIONS, 0, 0);
|
||||
#ifdef CONFIG_USERSPACE
|
||||
event_blocking_ops(NUM_ITERATIONS, 0, K_USER);
|
||||
event_blocking_ops(NUM_ITERATIONS, K_USER, 0);
|
||||
event_blocking_ops(NUM_ITERATIONS, K_USER, K_USER);
|
||||
#endif
|
||||
|
||||
sema_test_signal(NUM_ITERATIONS, 0);
|
||||
#ifdef CONFIG_USERSPACE
|
||||
sema_test_signal(NUM_ITERATIONS, K_USER);
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
#include <zephyr/timestamp.h>
|
||||
#include <zephyr/app_memory/app_memdomain.h>
|
||||
|
||||
#define START_STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
|
||||
#define ALT_STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
|
||||
#define START_STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE)
|
||||
#define ALT_STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE)
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
#define BENCH_BMEM K_APP_BMEM(bench_mem_partition)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue