/* * Copyright (c) 2016 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include #include "tests_thread_apis.h" static ZTEST_BMEM char tp1[8]; static ZTEST_DMEM int tp2 = 100; static ZTEST_BMEM struct k_sema *tp3; static ZTEST_BMEM int spawn_prio; static void thread_entry_params(void *p1, void *p2, void *p3) { /* checkpoint: check parameter 1, 2, 3 */ zassert_equal(p1, tp1); zassert_equal(POINTER_TO_INT(p2), tp2); zassert_equal(p3, tp3); } static void thread_entry_priority(void *p1, void *p2, void *p3) { /* checkpoint: check priority */ zassert_equal(k_thread_priority_get(k_current_get()), spawn_prio); } static void thread_entry_delay(void *p1, void *p2, void *p3) { tp2 = 100; } /* test cases */ /** * @ingroup kernel_thread_tests * @brief Check the parameters passed to thread entry function * * @details Create an user thread and pass 2 variables and a * semaphore to a thread entry function. Check for the correctness * of the parameters passed. * * @see k_thread_create() */ ZTEST_USER(threads_lifecycle, test_threads_spawn_params) { k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry_params, tp1, INT_TO_POINTER(tp2), tp3, 0, K_USER, K_NO_WAIT); k_msleep(100); } /** * @ingroup kernel_thread_tests * @brief Spawn thread with higher priority * * @details Create an user thread with priority greater than * current thread and check its behavior. * * @see k_thread_create() */ ZTEST(threads_lifecycle, test_threads_spawn_priority) { /* spawn thread with higher priority */ spawn_prio = k_thread_priority_get(k_current_get()) - 1; k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry_priority, NULL, NULL, NULL, spawn_prio, K_USER, K_NO_WAIT); k_msleep(100); } /** * @ingroup kernel_thread_tests * @brief Spawn thread with a delay * * @details Create a user thread with delay and check if the * thread entry function is executed only after the timeout occurs. * * @see k_thread_create() */ ZTEST_USER(threads_lifecycle, test_threads_spawn_delay) { /* spawn thread with higher priority */ tp2 = 10; k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry_delay, NULL, NULL, NULL, 0, K_USER, K_MSEC(120)); /* 100 < 120 ensure spawn thread not start */ k_msleep(100); /* checkpoint: check spawn thread not execute */ zassert_true(tp2 == 10); /* checkpoint: check spawn thread executed */ k_msleep(100); zassert_true(tp2 == 100); } /** * @ingroup kernel_thread_tests * @brief Spawn thread with forever delay and highest priority * * @details Create an user thread with forever delay and yield * the current thread. Even though the current thread has yielded, * the thread will not be put in ready queue since it has forever delay, * the thread is explicitly started using k_thread_start() and checked * if thread has started executing. * * @see k_thread_create() */ ZTEST(threads_lifecycle, test_threads_spawn_forever) { /* spawn thread with highest priority. It will run immediately once * started. */ tp2 = 10; k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry_delay, NULL, NULL, NULL, K_HIGHEST_THREAD_PRIO, K_USER, K_FOREVER); k_yield(); /* checkpoint: check spawn thread not execute */ zassert_true(tp2 == 10); /* checkpoint: check spawn thread executed */ k_thread_start(tid); k_yield(); zassert_true(tp2 == 100); k_thread_abort(tid); } /** * @ingroup kernel_thread_tests * @brief Validate behavior of multiple calls to k_thread_start() * * @details Call k_thread_start() on an already terminated thread * * @see k_thread_start() */ ZTEST(threads_lifecycle, test_thread_start) { tp2 = 5; k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry_delay, NULL, NULL, NULL, K_HIGHEST_THREAD_PRIO, K_USER, K_FOREVER); k_thread_start(tid); k_yield(); zassert_true(tp2 == 100); /* checkpoint: k_thread_start() should not start the * terminated thread */ tp2 = 50; k_thread_start(tid); k_yield(); zassert_false(tp2 == 100); } static void user_start_thread(void *p1, void *p2, void *p3) { *(int *)p1 = 100; } ZTEST_USER(threads_lifecycle, test_thread_start_user) { tp2 = 5; k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, user_start_thread, &tp2, NULL, NULL, 0, K_USER, K_FOREVER); k_thread_start(tid); k_msleep(100); zassert_true(tp2 == 100); k_thread_abort(tid); }