Fix grouping and general doxygen fixups. Signed-off-by: Anas Nashif <anas.nashif@intel.com>
163 lines
3.1 KiB
C
163 lines
3.1 KiB
C
/*
|
|
* Copyright (c) 2017 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/ztest.h>
|
|
#include <zephyr/kernel.h>
|
|
#include <errno.h>
|
|
#include <zephyr/sys/errno_private.h>
|
|
|
|
|
|
#define N_THREADS 2
|
|
#define STACK_SIZE (384 + CONFIG_TEST_EXTRA_STACK_SIZE)
|
|
|
|
static K_THREAD_STACK_ARRAY_DEFINE(stacks, N_THREADS, STACK_SIZE);
|
|
static struct k_thread threads[N_THREADS];
|
|
|
|
K_THREAD_STACK_DEFINE(eno_stack, STACK_SIZE);
|
|
struct k_thread eno_thread;
|
|
|
|
static int errno_values[N_THREADS + 1] = {
|
|
0xbabef00d,
|
|
0xdeadbeef,
|
|
0xabad1dea,
|
|
};
|
|
|
|
struct result {
|
|
void *q;
|
|
int pass;
|
|
};
|
|
|
|
struct result result[N_THREADS];
|
|
|
|
struct k_fifo fifo;
|
|
|
|
static void errno_thread(void *_n, void *_my_errno, void *_unused)
|
|
{
|
|
int n = POINTER_TO_INT(_n);
|
|
int my_errno = POINTER_TO_INT(_my_errno);
|
|
|
|
errno = my_errno;
|
|
|
|
k_msleep(30 - (n * 10));
|
|
if (errno == my_errno) {
|
|
result[n].pass = TC_PASS;
|
|
}
|
|
|
|
zassert_equal(errno, my_errno);
|
|
|
|
k_fifo_put(&fifo, &result[n]);
|
|
}
|
|
/**
|
|
* @defgroup kernel_errno_tests Error Number
|
|
* @ingroup all_tests
|
|
* @{
|
|
* @}
|
|
*
|
|
* @addtogroup kernel_errno_tests
|
|
* @{
|
|
*/
|
|
/**
|
|
* @brief Verify thread context
|
|
*
|
|
* @details Check whether variable value per-thread are saved during
|
|
* context switch
|
|
*/
|
|
ZTEST(common_errno, test_thread_context)
|
|
{
|
|
int rv = TC_PASS, test_errno;
|
|
|
|
k_fifo_init(&fifo);
|
|
|
|
errno = errno_values[N_THREADS];
|
|
test_errno = errno;
|
|
|
|
for (int ii = 0; ii < N_THREADS; ii++) {
|
|
result[ii].pass = TC_FAIL;
|
|
}
|
|
|
|
/**TESTPOINT: thread- threads stacks are separate */
|
|
for (int ii = 0; ii < N_THREADS; ii++) {
|
|
k_thread_create(&threads[ii], stacks[ii], STACK_SIZE,
|
|
errno_thread, INT_TO_POINTER(ii),
|
|
INT_TO_POINTER(errno_values[ii]), NULL,
|
|
K_PRIO_PREEMPT(ii + 5), 0, K_NO_WAIT);
|
|
}
|
|
|
|
for (int ii = 0; ii < N_THREADS; ii++) {
|
|
struct result *p = k_fifo_get(&fifo, K_MSEC(100));
|
|
|
|
if (!p || (p->pass != TC_PASS)) {
|
|
rv = TC_FAIL;
|
|
}
|
|
}
|
|
|
|
zassert_equal(errno, test_errno);
|
|
|
|
if (errno != errno_values[N_THREADS]) {
|
|
rv = TC_FAIL;
|
|
}
|
|
|
|
/* Make sure all the test thread end. */
|
|
for (int ii = 0; ii < N_THREADS; ii++) {
|
|
k_thread_join(&threads[ii], K_FOREVER);
|
|
}
|
|
|
|
if (rv != TC_PASS) {
|
|
ztest_test_fail();
|
|
}
|
|
}
|
|
|
|
|
|
#define ERROR_ANY 0xfc
|
|
|
|
void thread_entry_user(void *p1, void *p2, void *p3)
|
|
{
|
|
#ifdef CONFIG_NATIVE_LIBC
|
|
/* The errno when using the host C library will be handled by it, so we skip it.
|
|
*/
|
|
ztest_test_skip();
|
|
#else
|
|
int got_errno;
|
|
|
|
/* assign the error number to C standard errno */
|
|
errno = ERROR_ANY;
|
|
|
|
/* got errno zephyr stored */
|
|
got_errno = *(z_errno());
|
|
|
|
zassert_equal(errno, got_errno, "errno is not corresponding.");
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief Verify errno works well
|
|
*
|
|
* @details Check whether a C standard errno can be stored successfully,
|
|
* no matter it is using tls or not.
|
|
*/
|
|
ZTEST_USER(common_errno, test_errno)
|
|
{
|
|
k_tid_t tid;
|
|
uint32_t perm = K_INHERIT_PERMS;
|
|
|
|
if (k_is_user_context()) {
|
|
perm = perm | K_USER;
|
|
}
|
|
|
|
tid = k_thread_create(&eno_thread, eno_stack, STACK_SIZE,
|
|
thread_entry_user, NULL, NULL, NULL,
|
|
K_PRIO_PREEMPT(1), perm,
|
|
K_NO_WAIT);
|
|
|
|
k_thread_join(tid, K_FOREVER);
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
extern void *common_setup(void);
|
|
ZTEST_SUITE(common_errno, NULL, common_setup, NULL, NULL, NULL);
|