Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | /* * 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> /** * @brief Test the thread context * * @defgroup kernel_threadcontext_tests Thread Context Tests * * @ingroup all_tests * * @{ * @} */ #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]); } /** * @brief Verify thread context * * @ingroup kernel_threadcontext_tests * * @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_ARCH_POSIX /* The errno in native posix will be handled by native * operation system, 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. * * @ingroup kernel_threadcontext_tests */ 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); |