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 | /* * Copyright (c) 2016 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include <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_sleep(K_MSEC(100)); /* checkpoint: created thread shouldn't be executed after suspend */ zassert_false(last_prio == create_prio, NULL); k_thread_resume(tid); k_sleep(K_MSEC(100)); /* checkpoint: created thread should be executed after resume */ zassert_true(last_prio == create_prio, NULL); } /*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() */ void test_threads_suspend_resume_cooperative(void) { 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() */ void test_threads_suspend_resume_preemptible(void) { 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. */ void test_threads_suspend(void) { 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_sleep(K_MSEC(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_sleep(K_MSEC(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. */ void test_threads_suspend_timeout(void) { 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_sleep(K_MSEC(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_sleep(K_MSEC(200)); zassert_false(after_suspend, "thread woke up unexpectedly"); k_thread_abort(tid); } |