blob: b744616a81f687597ffe89cf0c3213a8292e7321 [file] [log] [blame]
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <ztest.h>
#include <kernel.h>
/* Very simple (and limited) test of the SMP cpu mask API. Runs on
* just one CPU. Creates a thread, sets the CPU mask, starts it,
* checks if it ran (or didn't run) as expected.
*/
struct k_thread child_thread;
extern size_t tstack_size;
K_THREAD_STACK_EXTERN(tstack);
bool child_has_run;
void child_fn(void *a, void *b, void *c)
{
child_has_run = true;
}
void test_threads_cpu_mask(void)
{
#ifdef CONFIG_SCHED_CPU_MASK
k_tid_t thread;
int ret, pass, prio;
/* Shouldn't be able to operate on a running thread */
ret = k_thread_cpu_mask_clear(k_current_get());
zassert_true(ret == -EINVAL, "");
ret = k_thread_cpu_mask_enable_all(k_current_get());
zassert_true(ret == -EINVAL, "");
ret = k_thread_cpu_mask_enable(k_current_get(), 0);
zassert_true(ret == -EINVAL, "");
ret = k_thread_cpu_mask_disable(k_current_get(), 0);
zassert_true(ret == -EINVAL, "");
for (pass = 0; pass < 4; pass++) {
child_has_run = false;
/* Create a thread at a higher priority, don't start
* it yet.
*/
prio = k_thread_priority_get(k_current_get());
zassert_true(prio > K_HIGHEST_APPLICATION_THREAD_PRIO, "");
thread = k_thread_create(&child_thread,
tstack, tstack_size,
child_fn, NULL, NULL, NULL,
K_HIGHEST_APPLICATION_THREAD_PRIO,
0, K_FOREVER);
/* Set up the CPU mask */
if (pass == 0) {
ret = k_thread_cpu_mask_clear(thread);
zassert_true(ret == 0, "");
} else if (pass == 1) {
ret = k_thread_cpu_mask_enable_all(thread);
zassert_true(ret == 0, "");
} else if (pass == 2) {
ret = k_thread_cpu_mask_disable(thread, 0);
zassert_true(ret == 0, "");
} else {
ret = k_thread_cpu_mask_enable(thread, 0);
zassert_true(ret == 0, "");
}
/* Start it. If it is runnable, it will do so
* immediately when we yield. Check to see if it ran.
*/
zassert_false(child_has_run, "");
k_thread_start(thread);
k_yield();
if (pass == 1 || pass == 3) {
zassert_true(child_has_run, "");
} else {
zassert_false(child_has_run, "");
}
k_thread_abort(thread);
}
#endif
}