Linux Audio

Check our new training course

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

/**
 * @addtogroup t_sema_api
 * @{
 * @defgroup t_sema_api_basic test_sema_api_basic
 * @brief TestPurpose: verify zephyr sema apis across different context
 * - API coverage
 *   -# k_sem_init K_SEMA_DEFINE
 *   -# k_sem_take k_sema_give k_sema_reset
 *   -# k_sem_count_get
 * @}
 */

#include <ztest.h>
#include <irq_offload.h>

#define TIMEOUT 100
#define STACK_SIZE 512
#define SEM_INITIAL 0
#define SEM_LIMIT 2
/**TESTPOINT: init via K_SEM_DEFINE*/
K_SEM_DEFINE(ksema, SEM_INITIAL, SEM_LIMIT);
__kernel struct k_sem sema;
static K_THREAD_STACK_DEFINE(tstack, STACK_SIZE);
__kernel struct k_thread tdata;

/*entry of contexts*/
static void tisr_entry(void *p)
{
	k_sem_give((struct k_sem *)p);
}

static void thread_entry(void *p1, void *p2, void *p3)
{
	k_sem_give((struct k_sem *)p1);
}

static void tsema_thread_thread(struct k_sem *psem)
{
	/**TESTPOINT: thread-thread sync via sema*/
	k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
				      thread_entry, psem, NULL, NULL,
				      K_PRIO_PREEMPT(0),
				      K_USER | K_INHERIT_PERMS, 0);

	zassert_false(k_sem_take(psem, K_FOREVER), NULL);
	/*clean the spawn thread avoid side effect in next TC*/
	k_thread_abort(tid);
}

static void tsema_thread_isr(struct k_sem *psem)
{
	/**TESTPOINT: thread-isr sync via sema*/
	irq_offload(tisr_entry, psem);
	zassert_false(k_sem_take(psem, K_FOREVER), NULL);
}

/*test cases*/
void test_sema_thread2thread(void)
{
	/**TESTPOINT: test k_sem_init sema*/
	k_sem_init(&sema, SEM_INITIAL, SEM_LIMIT);

	tsema_thread_thread(&sema);

	/**TESTPOINT: test K_SEM_DEFINE sema*/
	tsema_thread_thread(&ksema);
}

void test_sema_thread2isr(void)
{
	/**TESTPOINT: test k_sem_init sema*/
	k_sem_init(&sema, SEM_INITIAL, SEM_LIMIT);
	tsema_thread_isr(&sema);

	/**TESTPOINT: test K_SEM_DEFINE sema*/
	tsema_thread_isr(&ksema);
}

void test_sema_reset(void)
{
	k_sem_init(&sema, SEM_INITIAL, SEM_LIMIT);
	k_sem_give(&sema);
	k_sem_reset(&sema);
	zassert_false(k_sem_count_get(&sema), NULL);
	/**TESTPOINT: sem take return -EBUSY*/
	zassert_equal(k_sem_take(&sema, K_NO_WAIT), -EBUSY, NULL);
	/**TESTPOINT: sem take return -EAGAIN*/
	zassert_equal(k_sem_take(&sema, TIMEOUT), -EAGAIN, NULL);
	k_sem_give(&sema);
	zassert_false(k_sem_take(&sema, K_FOREVER), NULL);
}

void test_sema_count_get(void)
{
	k_sem_init(&sema, SEM_INITIAL, SEM_LIMIT);
	/**TESTPOINT: sem count get upon init*/
	zassert_equal(k_sem_count_get(&sema), SEM_INITIAL, NULL);
	k_sem_give(&sema);
	/**TESTPOINT: sem count get after give*/
	zassert_equal(k_sem_count_get(&sema), SEM_INITIAL + 1, NULL);
	k_sem_take(&sema, K_FOREVER);
	/**TESTPOINT: sem count get after take*/
	for (int i = 0; i < SEM_LIMIT; i++) {
		zassert_equal(k_sem_count_get(&sema), SEM_INITIAL + i, NULL);
		k_sem_give(&sema);
	}
	/**TESTPOINT: sem give above limit*/
	k_sem_give(&sema);
	zassert_equal(k_sem_count_get(&sema), SEM_LIMIT, NULL);
}

/*test case main entry*/
void test_main(void)
{
	k_thread_access_grant(k_current_get(), &ksema, &tdata, &sema, &tstack,
			      NULL);

	ztest_test_suite(test_sema_api,
			 ztest_user_unit_test(test_sema_thread2thread),
			 ztest_unit_test(test_sema_thread2isr),
			 ztest_user_unit_test(test_sema_reset),
			 ztest_user_unit_test(test_sema_count_get));
	ztest_run_test_suite(test_sema_api);
}