1 /*
2  * Copyright (c) 2017 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/ztest.h>
8 #include <zephyr/irq_offload.h>
9 #include "test_sched.h"
10 
11 /* local variables */
12 static struct k_thread tdata;
13 static struct k_sem end_sema;
14 
tIsr(const void * data)15 static void tIsr(const void *data)
16 {
17 	/** TESTPOINT: The code is running at ISR. */
18 	zassert_false(k_is_preempt_thread());
19 }
20 
tpreempt_ctx(void * p1,void * p2,void * p3)21 static void tpreempt_ctx(void *p1, void *p2, void *p3)
22 {
23 	/** TESTPOINT: The thread's priority is in the preemptible range. */
24 	zassert_true(k_is_preempt_thread());
25 	k_sched_lock();
26 	/** TESTPOINT: The thread has locked the scheduler. */
27 	zassert_false(k_is_preempt_thread());
28 	k_sched_unlock();
29 	/** TESTPOINT: The thread has not locked the scheduler. */
30 	zassert_true(k_is_preempt_thread());
31 	k_thread_priority_set(k_current_get(), K_PRIO_COOP(1));
32 	/** TESTPOINT: The thread's priority is in the cooperative range. */
33 	zassert_false(k_is_preempt_thread());
34 	k_sem_give(&end_sema);
35 }
36 
tcoop_ctx(void * p1,void * p2,void * p3)37 static void tcoop_ctx(void *p1, void *p2, void *p3)
38 {
39 	/** TESTPOINT: The thread's priority is in the cooperative range. */
40 	zassert_false(k_is_preempt_thread());
41 	k_thread_priority_set(k_current_get(), K_PRIO_PREEMPT(1));
42 	/** TESTPOINT: The thread's priority is in the preemptible range. */
43 	zassert_true(k_is_preempt_thread());
44 	k_sched_lock();
45 	/** TESTPOINT: The thread has locked the scheduler. */
46 	zassert_false(k_is_preempt_thread());
47 	k_sched_unlock();
48 	/** TESTPOINT: The thread has not locked the scheduler. */
49 	zassert_true(k_is_preempt_thread());
50 	k_sem_give(&end_sema);
51 }
52 
53 /* test cases */
54 
55 /**
56  * @brief Validate the correctness of k_is_preempt_thread()
57  *
58  * @details Create a preemptive thread, lock the scheduler
59  * and call k_is_preempt_thread(). Unlock the scheduler and
60  * call k_is_preempt_thread() again. Create a cooperative
61  * thread and lock the scheduler k_is_preempt_thread() and
62  * unlock the scheduler and call k_is_preempt_thread().
63  *
64  * @see k_is_preempt_thread()
65  *
66  * @ingroup kernel_sched_tests
67  */
ZTEST(threads_scheduling,test_sched_is_preempt_thread)68 ZTEST(threads_scheduling, test_sched_is_preempt_thread)
69 {
70 	k_sem_init(&end_sema, 0, 1);
71 
72 	/* create preempt thread */
73 	k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
74 				      tpreempt_ctx, NULL, NULL, NULL,
75 				      K_PRIO_PREEMPT(1), 0, K_NO_WAIT);
76 	k_sem_take(&end_sema, K_FOREVER);
77 	k_thread_abort(tid);
78 
79 	/* create coop thread */
80 	tid = k_thread_create(&tdata, tstack, STACK_SIZE,
81 			      tcoop_ctx, NULL, NULL, NULL,
82 			      K_PRIO_COOP(1), 0, K_NO_WAIT);
83 	k_sem_take(&end_sema, K_FOREVER);
84 	k_thread_abort(tid);
85 
86 	/* invoke isr */
87 	irq_offload(tIsr, NULL);
88 }
89