1 /*
2 * Copyright (c) 2017 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include "test_sched.h"
9
10 /* nrf 51 has lower ram, so creating less number of threads */
11 #if CONFIG_SRAM_SIZE <= 24
12 #define NUM_THREAD 2
13 #elif (CONFIG_SRAM_SIZE <= 32) \
14 || defined(CONFIG_SOC_EMSK_EM7D)
15 #define NUM_THREAD 3
16 #else
17 #define NUM_THREAD 10
18 #endif
19 #define ITERATION_COUNT 5
20 #define BASE_PRIORITY 1
21
22 BUILD_ASSERT(NUM_THREAD <= MAX_NUM_THREAD);
23
24 /* Semaphore on which Ztest thread wait */
25 static K_SEM_DEFINE(sema2, 0, NUM_THREAD);
26
27 /* Semaphore on which application threads wait */
28 static K_SEM_DEFINE(sema3, 0, NUM_THREAD);
29
30 static int thread_idx;
31 static struct k_thread t[NUM_THREAD];
32
33 /* Application thread */
thread_tslice(void * p1,void * p2,void * p3)34 static void thread_tslice(void *p1, void *p2, void *p3)
35 {
36 int idx = POINTER_TO_INT(p1);
37
38 /* Print New line for last thread */
39 int thread_parameter = (idx == (NUM_THREAD - 1)) ? '\n' :
40 (idx + 'A');
41
42 while (1) {
43 /* Printing alphabet corresponding to thread */
44 TC_PRINT("%c", thread_parameter);
45 /* Testing if threads are executed as per priority */
46 zassert_true((idx == thread_idx));
47 thread_idx = (thread_idx + 1) % (NUM_THREAD);
48
49 /* Release CPU and give chance to Ztest thread to run */
50 k_sem_give(&sema2);
51 /* Wait for release of semaphore from Ztest thread */
52 k_sem_take(&sema3, K_FOREVER);
53 }
54
55 }
56
57 /* test cases */
58
59 /**
60 * @brief Check the behavior of preemptive threads with different priorities
61 *
62 * @details Create multiple threads of different priorities - all are preemptive,
63 * current thread is also made preemptive. Check how the threads get chance to
64 * execute based on their priorities
65 *
66 * @ingroup kernel_sched_tests
67 */
ZTEST(threads_scheduling,test_priority_scheduling)68 ZTEST(threads_scheduling, test_priority_scheduling)
69 {
70 k_tid_t tid[NUM_THREAD];
71 int old_prio = k_thread_priority_get(k_current_get());
72 int count = 0;
73
74 /* update priority for current thread */
75 k_thread_priority_set(k_current_get(),
76 K_PRIO_PREEMPT(BASE_PRIORITY - 1));
77
78 /* Create Threads with different Priority */
79 for (int i = 0; i < NUM_THREAD; i++) {
80 tid[i] = k_thread_create(&t[i], tstacks[i], STACK_SIZE,
81 thread_tslice, INT_TO_POINTER(i), NULL, NULL,
82 K_PRIO_PREEMPT(BASE_PRIORITY + i), 0,
83 K_NO_WAIT);
84 }
85
86 while (count < ITERATION_COUNT) {
87
88 /* Wait for each thread to complete */
89 for (int i = 0; i < NUM_THREAD; i++) {
90 k_sem_take(&sema2, K_FOREVER);
91 }
92 /* Delay to give chance to last thread to run */
93 k_sleep(K_MSEC(1));
94
95 /* Giving Chance to other threads to run */
96 for (int i = 0; i < NUM_THREAD; i++) {
97 k_sem_give(&sema3);
98 }
99 count++;
100 }
101
102
103 /* test case teardown */
104 for (int i = 0; i < NUM_THREAD; i++) {
105 k_thread_abort(tid[i]);
106 }
107 /* Set priority of Main thread to its old value */
108 k_thread_priority_set(k_current_get(), old_prio);
109 }
110