Skip to content

Commit 972a4d9

Browse files
aescolarcarlescufi
authored andcommitted
tests/kernel/context: Improve to resist parallel threads interrupting
This test assumes that nothing will wake the CPU apart from the timer set by the test. But that is not necessarily the case. Some other platform thread started at boot may be waking the CPU every now and then. Let's allow for some spurious wakes while we are testing k_cpu_idle, while at the same time ensuring we are not just busy waiting all the way. Signed-off-by: Alberto Escolar Piedras <[email protected]>
1 parent 6876f9e commit 972a4d9

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

tests/kernel/context/Kconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright (c) 2024 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config MAX_IDLE_WAKES
5+
int "Maximum number of spurious wakes during k_cpu_idle() test"
6+
default 1 if NRF53_SYNC_RTC
7+
default 0
8+
help
9+
The platform may have some component running in the background while the k_cpu_idle test is
10+
running causing the CPU to awake. With this option we allow for a maximum number of wakes
11+
for each 10ms idle test, which by default should be 0.
12+
13+
# Include Zephyr's Kconfig
14+
source "Kconfig"

tests/kernel/context/src/main.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,12 @@ void irq_enable_wrapper(int irq)
212212
#if defined(CONFIG_TICKLESS_KERNEL)
213213
static struct k_timer idle_timer;
214214

215+
static volatile bool idle_timer_done;
216+
215217
static void idle_timer_expiry_function(struct k_timer *timer_id)
216218
{
217219
k_timer_stop(&idle_timer);
220+
idle_timer_done = true;
218221
}
219222

220223
static void _test_kernel_cpu_idle(int atomic)
@@ -223,20 +226,25 @@ static void _test_kernel_cpu_idle(int atomic)
223226
unsigned int i, key;
224227
uint32_t dur = k_ms_to_ticks_ceil32(10);
225228
uint32_t slop = 1 + k_ms_to_ticks_ceil32(1);
229+
int idle_loops;
226230

227231
/* Set up a time to trigger events to exit idle mode */
228232
k_timer_init(&idle_timer, idle_timer_expiry_function, NULL);
229233

230234
for (i = 0; i < 5; i++) {
231235
k_usleep(1);
232236
t0 = k_uptime_ticks();
237+
idle_loops = 0;
238+
idle_timer_done = false;
233239
k_timer_start(&idle_timer, K_TICKS(dur), K_NO_WAIT);
234240
key = irq_lock();
235-
if (atomic) {
236-
k_cpu_atomic_idle(key);
237-
} else {
238-
k_cpu_idle();
239-
}
241+
do {
242+
if (atomic) {
243+
k_cpu_atomic_idle(key);
244+
} else {
245+
k_cpu_idle();
246+
}
247+
} while ((idle_loops++ < CONFIG_MAX_IDLE_WAKES) && (idle_timer_done == false));
240248
dt = k_uptime_ticks() - t0;
241249
zassert_true(abs((int32_t) (dt - dur)) <= slop,
242250
"Inaccurate wakeup, idled for %d ticks, expected %d",

0 commit comments

Comments
 (0)