From 4b670bd4f511377a1118d37597ca016633a414d3 Mon Sep 17 00:00:00 2001 From: Andy Ross Date: Thu, 6 Feb 2020 12:54:17 -0800 Subject: [PATCH] tests/kernel/smp: current CPU is not atomic This test was whiteboxing the _current_cpu pointer to extract the CPU ID. That's actually racy: the thread can be preempted and migrated to another CPU between the _current_cpu expression and the read of the ID field. Do it right. Signed-off-by: Andy Ross --- tests/kernel/smp/src/main.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tests/kernel/smp/src/main.c b/tests/kernel/smp/src/main.c index 629b97ef041..7d5dd87e529 100644 --- a/tests/kernel/smp/src/main.c +++ b/tests/kernel/smp/src/main.c @@ -45,6 +45,16 @@ static struct k_thread tthread[THREADS_NUM]; static K_THREAD_STACK_ARRAY_DEFINE(tstack, THREADS_NUM, STACK_SIZE); static volatile int thread_started[THREADS_NUM - 1]; + +static int curr_cpu(void) +{ + unsigned int k = arch_irq_lock(); + int ret = arch_curr_cpu()->id; + + arch_irq_unlock(k); + return ret; +} + /** * @brief Tests for SMP * @defgroup kernel_smp_tests SMP Tests @@ -120,7 +130,7 @@ static void child_fn(void *p1, void *p2, void *p3) ARG_UNUSED(p3); int parent_cpu_id = POINTER_TO_INT(p1); - zassert_true(parent_cpu_id != arch_curr_cpu()->id, + zassert_true(parent_cpu_id != curr_cpu(), "Parent isn't on other core"); sync_count++; @@ -140,7 +150,7 @@ void test_cpu_id_threads(void) /* Make sure idle thread runs on each core */ k_sleep(K_MSEC(1000)); - int parent_cpu_id = arch_curr_cpu()->id; + int parent_cpu_id = curr_cpu(); k_tid_t tid = k_thread_create(&t2, t2_stack, T2_STACK_SIZE, child_fn, INT_TO_POINTER(parent_cpu_id), NULL, @@ -161,7 +171,7 @@ static void thread_entry(void *p1, void *p2, void *p3) int count = 0; tinfo[thread_num].executed = 1; - tinfo[thread_num].cpu_id = arch_curr_cpu()->id; + tinfo[thread_num].cpu_id = curr_cpu(); while (count++ < 5) { k_busy_wait(DELAY_US);