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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | /* * Copyright (c) 2016 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr/ztest.h> #include "tests_thread_apis.h" static ZTEST_BMEM int last_prio; static void thread_entry(void *p1, void *p2, void *p3) { last_prio = k_thread_priority_get(k_current_get()); } static void threads_suspend_resume(int prio) { /* set current thread */ last_prio = prio; k_thread_priority_set(k_current_get(), last_prio); /* create thread with lower priority */ int create_prio = last_prio + 1; k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry, NULL, NULL, NULL, create_prio, K_USER, K_NO_WAIT); /* checkpoint: suspend current thread */ k_thread_suspend(tid); k_msleep(100); /* checkpoint: created thread shouldn't be executed after suspend */ zassert_false(last_prio == create_prio); k_thread_resume(tid); k_msleep(100); /* checkpoint: created thread should be executed after resume */ zassert_true(last_prio == create_prio); } /*test cases*/ /** * @ingroup kernel_thread_tests * @brief Check the suspend and resume functionality in * a cooperative thread * * @details Create a thread with the priority lower than the current * thread which is cooperative and suspend it, make sure it doesn't * gets scheduled, and resume and check if the entry function is executed. * * @see k_thread_suspend(), k_thread_resume() */ ZTEST(threads_lifecycle_1cpu, test_threads_suspend_resume_cooperative) { threads_suspend_resume(-2); } /** * @ingroup kernel_thread_tests * @brief Check the suspend and resume functionality in * preemptive thread * * @details Create a thread with the priority lower than the current * thread which is preemptive and suspend it, make sure it doesn't gets * scheduled, and resume and check if the entry function is executed. * * @see k_thread_suspend(), k_thread_resume() */ ZTEST_USER(threads_lifecycle, test_threads_suspend_resume_preemptible) { threads_suspend_resume(1); } static bool after_suspend; void suspend_myself(void *arg0, void *arg1, void *arg2) { ARG_UNUSED(arg0); ARG_UNUSED(arg1); ARG_UNUSED(arg2); k_thread_suspend(k_current_get()); after_suspend = true; } /** * @ingroup kernel_thread_tests * * @brief Check that k_thread_suspend() is a schedule point when * called on the current thread. */ ZTEST(threads_lifecycle, test_threads_suspend) { after_suspend = false; k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, suspend_myself, NULL, NULL, NULL, 0, K_USER, K_NO_WAIT); /* Give the thread a chance to start and verify that it * stopped executing after suspending itself. */ k_msleep(100); zassert_false(after_suspend, "thread woke up unexpectedly"); k_thread_abort(tid); } void sleep_suspended(void *arg0, void *arg1, void *arg2) { ARG_UNUSED(arg0); ARG_UNUSED(arg1); ARG_UNUSED(arg2); /* Sleep a half second, then set the flag after we wake up. * If we are suspended, the wakeup should not occur */ k_msleep(100); after_suspend = true; } /** * @ingroup kernel_thread_tests * @brief Check that k_thread_suspend() cancels a preexisting thread timeout * * @details Suspended threads should not wake up unexpectedly if they * happened to have been sleeping when suspended. */ ZTEST(threads_lifecycle, test_threads_suspend_timeout) { after_suspend = false; k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, sleep_suspended, NULL, NULL, NULL, 0, K_USER, K_NO_WAIT); k_msleep(50); k_thread_suspend(tid); /* Give the timer long enough to expire, and verify that it * has not (i.e. that the thread didn't wake up, because it * has been suspended) */ k_msleep(200); zassert_false(after_suspend, "thread woke up unexpectedly"); k_thread_abort(tid); } /** * @ingroup kernel_thread_tests * @brief Check resume an unsuspend thread * * @details Use k_thread_state_str() to get thread state. * Resume an unsuspend thread will not change the thread state. */ ZTEST(threads_lifecycle, test_resume_unsuspend_thread) { char buffer[32]; const char *str; k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry, NULL, NULL, NULL, 0, K_USER, K_NO_WAIT); /* Resume an unsuspend thread will not change the thread state. */ str = k_thread_state_str(tid, buffer, sizeof(buffer)); zassert_str_equal(str, "queued"); k_thread_resume(tid); str = k_thread_state_str(tid, buffer, sizeof(buffer)); zassert_str_equal(str, "queued"); /* suspend created thread */ k_thread_suspend(tid); str = k_thread_state_str(tid, buffer, sizeof(buffer)); zassert_str_equal(str, "suspended"); /* Resume an suspend thread will make it to be next eligible.*/ k_thread_resume(tid); str = k_thread_state_str(tid, buffer, sizeof(buffer)); zassert_str_equal(str, "queued"); k_thread_abort(tid); } |