Skip to content

Commit 95a97fd

Browse files
peter-mitsisnashif
authored andcommitted
tests: Port Thread-Metric benchmark from ThreadX
Ports the Thread-Metric suite of benchmarks from ThreadX to Zephyr. This makes it easier for others to run these benchmarks with the best set of configuration options for their board so that they can better compare Zephyr performance to another RTOS. Signed-off-by: Peter Mitsis <[email protected]>
1 parent c9ce311 commit 95a97fd

16 files changed

+2353
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
5+
project(thread_metric)
6+
7+
FILE(GLOB app_sources src/tm_porting_layer_zephyr.c)
8+
target_sources(app PRIVATE ${app_sources})
9+
target_sources_ifdef(CONFIG_TM_BASIC app PRIVATE src/tm_basic_processing_test.c)
10+
target_sources_ifdef(CONFIG_TM_COOPERATIVE app PRIVATE src/tm_cooperative_scheduling_test.c)
11+
target_sources_ifdef(CONFIG_TM_INTERRUPT app PRIVATE src/tm_interrupt_processing_test.c)
12+
target_sources_ifdef(CONFIG_TM_INTERRUPT_PREEMPTION app PRIVATE src/tm_interrupt_preemption_processing_test.c)
13+
target_sources_ifdef(CONFIG_TM_MEMORY_ALLOCATION app PRIVATE src/tm_memory_allocation_test.c)
14+
target_sources_ifdef(CONFIG_TM_MESSAGE app PRIVATE src/tm_message_processing_test.c)
15+
target_sources_ifdef(CONFIG_TM_PREEMPTIVE app PRIVATE src/tm_preemptive_scheduling_test.c)
16+
target_sources_ifdef(CONFIG_TM_SYNCHRONIZATION app PRIVATE src/tm_synchronization_processing_test.c)
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Copyright (c) 2024 Intel Corporation
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
mainmenu "Eclipse ThreadX Thread-Metric RTOS Test Suite"
5+
6+
source "Kconfig.zephyr"
7+
8+
choice TM_TEST
9+
prompt "Select a Thread-Metric test to execute"
10+
default TM_PREEMPTIVE
11+
help
12+
The Thread-Metric benchmark suite consists of eight RTOS tests.
13+
These tests measure the total number of RTOS events that can be
14+
processed during a 30 second time interval.
15+
16+
config TM_BASIC
17+
bool "Baseline basic benchmark"
18+
help
19+
The baseline basic benchmark consists of a single thread that counts
20+
the number of times it performs a set of calculations. This number
21+
is reported every 30 seconds.
22+
23+
config TM_COOPERATIVE
24+
bool "Cooperative context switching"
25+
help
26+
The cooperative context switching benchmark spawns five (5) threads
27+
of equal priority that yield to each other and increment counters
28+
on each context switch. The sum total of the counters is reported
29+
every 30 seconds.
30+
31+
config TM_INTERRUPT
32+
bool "Interrupt processing"
33+
select TEST
34+
select IRQ_OFFLOAD
35+
select IRQ_OFFLOAD_NESTED
36+
help
37+
The interrupt processing benchmark has a single thread that causes
38+
an interrupt which results in its ISR incrementing a counter and then
39+
posting a semaphore. The thread then increments its own counter and
40+
takes that semaphore. The sum total of the counters is reported
41+
every 30 seconds.
42+
43+
config TM_INTERRUPT_PREEMPTION
44+
bool "Interrupt processing preemption"
45+
select TEST
46+
select IRQ_OFFLOAD
47+
select IRQ_OFFLOAD_NESTED
48+
help
49+
The interrupt preemption benchmark counts the number of times that
50+
an ISR from a software generated interrupt results in the preemption
51+
of a thread. The total number of context switches is reported every
52+
30 seconds.
53+
54+
config TM_MEMORY_ALLOCATION
55+
bool "Memory allocation"
56+
help
57+
The memory allocation benchmark counts the number of times a thread
58+
is able to allocate and then release a 128-byte block. This number
59+
is reported every 30 seconds.
60+
61+
config TM_MESSAGE
62+
bool "Message processing"
63+
help
64+
The message processing benchmark counts the number of times that a
65+
thread can send and receive a 16-byte message from a message queue.
66+
This number is reported every 30 seconds.
67+
68+
config TM_PREEMPTIVE
69+
bool "Preemptive context switching"
70+
help
71+
The preemptive context switching benchmark creates five (5) threads
72+
of different priorities that suspend and resume each other in a
73+
cyclical pattern. The total number of context switches is reported
74+
every 30 seconds.
75+
76+
config TM_SYNCHRONIZATION
77+
bool "Synchronization"
78+
help
79+
The synchronization benchmark counts the number of times that a
80+
thread can give and take a semaphore without blocking. This number
81+
is reported every 30 seconds.
82+
83+
endchoice
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Default base configuration file
2+
3+
# Use a tickless kernel to minimize the number of timer interrupts
4+
CONFIG_TICKLESS_KERNEL=y
5+
CONFIG_SYS_CLOCK_TICKS_PER_SEC=100
6+
7+
# Optimize for speed
8+
CONFIG_SPEED_OPTIMIZATIONS=y
9+
10+
# Disable time slicing
11+
CONFIG_TIMESLICING=n
12+
13+
# Test is only designed for a single CPU
14+
CONFIG_MP_MAX_NUM_CPUS=1
15+
16+
# Disabling hardware stack protection can greatly
17+
# improve system performance.
18+
CONFIG_HW_STACK_PROTECTION=n
19+
20+
# Picolibc is faster than Zephyr's minimal libc memcpy
21+
CONFIG_PICOLIBC_SPEED_OPTIMIZATIONS=y
22+
CONFIG_PICOLIBC_USE_MODULE=y
23+
24+
# Disable Thread Local Storage for better context switching times
25+
CONFIG_THREAD_LOCAL_STORAGE=n
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/***************************************************************************
2+
* Copyright (c) 2024 Microsoft Corporation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the MIT License which is available at
6+
* https://opensource.org/licenses/MIT.
7+
*
8+
* SPDX-License-Identifier: MIT
9+
**************************************************************************/
10+
11+
/**************************************************************************/
12+
/**************************************************************************/
13+
/** */
14+
/** Thread-Metric Component */
15+
/** */
16+
/** Application Interface (API) */
17+
/** */
18+
/**************************************************************************/
19+
/**************************************************************************/
20+
21+
/**************************************************************************/
22+
/* */
23+
/* APPLICATION INTERFACE DEFINITION RELEASE */
24+
/* */
25+
/* tm_api.h PORTABLE C */
26+
/* 6.1.7 */
27+
/* AUTHOR */
28+
/* */
29+
/* William E. Lamie, Microsoft Corporation */
30+
/* */
31+
/* DESCRIPTION */
32+
/* */
33+
/* This file defines the basic Application Interface (API) */
34+
/* implementation source code for the Thread-Metrics performance */
35+
/* test suite. All service prototypes and data structure definitions */
36+
/* are defined in this file. */
37+
/* */
38+
/* RELEASE HISTORY */
39+
/* */
40+
/* DATE NAME DESCRIPTION */
41+
/* */
42+
/* 10-15-2021 William E. Lamie Initial Version 6.1.7 */
43+
/* */
44+
/**************************************************************************/
45+
46+
#ifndef TM_API_H
47+
#define TM_API_H
48+
49+
#include "tm_porting_layer.h"
50+
51+
/*
52+
* Determine if a C++ compiler is being used. If so, ensure that standard
53+
* C is used to process the API information.
54+
*/
55+
56+
#ifdef __cplusplus
57+
58+
/* Yes, C++ compiler is present. Use standard C. */
59+
extern "C" {
60+
61+
#endif
62+
63+
/* Define API constants. */
64+
65+
#define TM_SUCCESS 0
66+
#define TM_ERROR 1
67+
68+
/* Define the time interval in seconds. This can be changed with a -D compiler option. */
69+
70+
#ifndef TM_TEST_DURATION
71+
#define TM_TEST_DURATION 30
72+
#endif
73+
74+
/*
75+
* Define RTOS Neutral APIs. RTOS vendors should fill in the guts of the following
76+
* API. Once this is done the Thread-Metric tests can be successfully run.
77+
*/
78+
79+
void tm_initialize(void (*test_initialization_function)(void));
80+
int tm_thread_create(int thread_id, int priority, void (*entry_function)(void *, void *, void *));
81+
int tm_thread_resume(int thread_id);
82+
int tm_thread_suspend(int thread_id);
83+
void tm_thread_relinquish(void);
84+
void tm_thread_sleep(int seconds);
85+
int tm_queue_create(int queue_id);
86+
int tm_queue_send(int queue_id, unsigned long *message_ptr);
87+
int tm_queue_receive(int queue_id, unsigned long *message_ptr);
88+
int tm_semaphore_create(int semaphore_id);
89+
int tm_semaphore_get(int semaphore_id);
90+
int tm_semaphore_put(int semaphore_id);
91+
int tm_memory_pool_create(int pool_id);
92+
int tm_memory_pool_allocate(int pool_id, unsigned char **memory_ptr);
93+
int tm_memory_pool_deallocate(int pool_id, unsigned char *memory_ptr);
94+
95+
/*
96+
* Determine if a C++ compiler is being used. If so, complete the standard
97+
* C conditional started above.
98+
*/
99+
#ifdef __cplusplus
100+
}
101+
#endif
102+
103+
#endif

0 commit comments

Comments
 (0)