Linux Audio

Check our new training course

Loading...
/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */


#include <zephyr/ztest.h>

#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);
}