1 /*
2 * Copyright (c) 2021 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/ztress.h>
9
10 volatile int ztress_dummy;
11
ztress_handler_busy(void * user_data,uint32_t cnt,bool last,int prio)12 bool ztress_handler_busy(void *user_data, uint32_t cnt, bool last, int prio)
13 {
14 /* On nios2 k_busy_wait in k_timer handler context is hanging. */
15 if (IS_ENABLED(CONFIG_NIOS2) && k_is_in_isr()) {
16 for (int i = 0; i < 1000; i++) {
17 ztress_dummy++;
18 }
19 } else {
20 k_busy_wait((prio+1) * 100);
21 }
22
23 return true;
24 }
25
ZTEST(ztress,test_timeout)26 ZTEST(ztress, test_timeout)
27 {
28 int64_t d;
29 uint32_t repeat = 1000000;
30 k_timeout_t t = Z_TIMEOUT_TICKS(20);
31 int err;
32 int timeout = 1000;
33
34 ztress_set_timeout(K_MSEC(timeout));
35
36 d = k_uptime_get();
37
38 /* Set of two threads */
39 ZTRESS_EXECUTE(ZTRESS_THREAD(ztress_handler_busy, NULL, repeat, 0, t),
40 ZTRESS_THREAD(ztress_handler_busy, NULL, repeat, 1000, t));
41
42 d = k_uptime_get() - d;
43 zassert_within(d, 1000, 200);
44
45 /* Set of two threads and timer. Test is setup manually, without helper macro. */
46 struct ztress_context_data timer_data =
47 ZTRESS_CONTEXT_INITIALIZER(ztress_handler_busy, NULL, repeat, 0, t);
48 struct ztress_context_data thread_data[] = {
49 ZTRESS_CONTEXT_INITIALIZER(ztress_handler_busy, NULL, repeat, 1000, t),
50 ZTRESS_CONTEXT_INITIALIZER(ztress_handler_busy, NULL, repeat, 1000, t)
51 };
52
53 d = k_uptime_get();
54 err = ztress_execute(&timer_data, thread_data, ARRAY_SIZE(thread_data));
55 zassert_equal(err, 0, "ztress_execute failed (err: %d)", err);
56 d = k_uptime_get() - d;
57 zassert_within(d, timeout + 500, 500);
58
59 ztress_set_timeout(K_NO_WAIT);
60 }
61
timeout_abort(struct k_timer * timer)62 static void timeout_abort(struct k_timer *timer)
63 {
64 ztress_abort();
65 }
66
ZTEST(ztress,test_abort)67 ZTEST(ztress, test_abort)
68 {
69 struct k_timer timer;
70 uint32_t repeat = 10000000;
71
72 k_timer_init(&timer, timeout_abort, NULL);
73 k_timer_start(&timer, K_MSEC(100), K_NO_WAIT);
74
75 ZTRESS_EXECUTE(ZTRESS_THREAD(ztress_handler_busy, NULL, repeat, 0, K_MSEC(1)),
76 ZTRESS_THREAD(ztress_handler_busy, NULL, repeat, 0, K_MSEC(1)));
77
78 zassert_true(ztress_exec_count(0) < repeat);
79 zassert_true(ztress_exec_count(1) < repeat);
80 }
81
ZTEST(ztress,test_repeat_completion)82 ZTEST(ztress, test_repeat_completion)
83 {
84 uint32_t repeat = 10;
85
86 /* Set of two threads */
87 ZTRESS_EXECUTE(ZTRESS_THREAD(ztress_handler_busy, NULL, repeat, 0, Z_TIMEOUT_TICKS(20)),
88 ZTRESS_THREAD(ztress_handler_busy, NULL, repeat, 0, Z_TIMEOUT_TICKS(20)));
89
90 for (int i = 0; i < 2; i++) {
91 uint32_t exec_cnt = ztress_exec_count(i);
92
93 zassert_true(exec_cnt >= repeat && exec_cnt < repeat + 10);
94 }
95
96 /* Set of two threads and timer */
97 ZTRESS_EXECUTE(ZTRESS_TIMER(ztress_handler_busy, NULL, repeat, Z_TIMEOUT_TICKS(30)),
98 ZTRESS_THREAD(ztress_handler_busy, NULL, repeat, 0, Z_TIMEOUT_TICKS(30)),
99 ZTRESS_THREAD(ztress_handler_busy, NULL, repeat, 0, Z_TIMEOUT_TICKS(30)));
100
101 for (int i = 0; i < 3; i++) {
102 uint32_t exec_cnt = ztress_exec_count(i);
103
104 zassert_true(exec_cnt >= repeat && exec_cnt < repeat + 10);
105 }
106 }
107
ZTEST(ztress,test_no_context_requirements)108 ZTEST(ztress, test_no_context_requirements)
109 {
110 uint32_t repeat = 10;
111
112 /* Set of two threads. First thread has no ending condition (exec_cnt and
113 * preempt_cnt are 0)
114 */
115 ZTRESS_EXECUTE(ZTRESS_THREAD(ztress_handler_busy, NULL, 0, 0, Z_TIMEOUT_TICKS(20)),
116 ZTRESS_THREAD(ztress_handler_busy, NULL, repeat, 0, Z_TIMEOUT_TICKS(20)));
117
118 uint32_t exec_cnt = ztress_exec_count(1);
119
120 zassert_true(exec_cnt >= repeat && exec_cnt < repeat + 10, "exec_cnt: %u", exec_cnt);
121
122 /* Set of two threads. Second thread and timer context has no ending
123 * condition (exec_cnt and preempt_cnt are 0).
124 */
125 ZTRESS_EXECUTE(ZTRESS_TIMER(ztress_handler_busy, NULL, 0, Z_TIMEOUT_TICKS(30)),
126 ZTRESS_THREAD(ztress_handler_busy, NULL, repeat, 0, Z_TIMEOUT_TICKS(30)),
127 ZTRESS_THREAD(ztress_handler_busy, NULL, 0, 0, Z_TIMEOUT_TICKS(30)));
128
129 exec_cnt = ztress_exec_count(1);
130 zassert_true(exec_cnt >= repeat && exec_cnt < repeat + 10);
131 }
132
ZTEST(ztress,test_too_many_threads)133 ZTEST(ztress, test_too_many_threads)
134 {
135 uint32_t repeat = 10;
136 k_timeout_t t = Z_TIMEOUT_TICKS(20);
137 int err;
138
139 /* Negative check on too many threads set and a timer.
140 * Assuming ZTRESS_MAX_THREADS=3
141 */
142 struct ztress_context_data timer_data =
143 ZTRESS_CONTEXT_INITIALIZER(ztress_handler_busy, NULL, repeat, 0, t);
144 struct ztress_context_data thread_data[] = {
145 ZTRESS_CONTEXT_INITIALIZER(ztress_handler_busy, NULL, repeat, 1000, t),
146 ZTRESS_CONTEXT_INITIALIZER(ztress_handler_busy, NULL, repeat, 1000, t),
147 ZTRESS_CONTEXT_INITIALIZER(ztress_handler_busy, NULL, repeat, 1000, t)
148 };
149
150 err = ztress_execute(&timer_data, thread_data, ARRAY_SIZE(thread_data));
151 zassert_equal(err, -EINVAL, "ztress_execute: unexpected err=%d (expected -EINVAL)", err);
152 }
153
154 ZTEST_SUITE(ztress, NULL, NULL, NULL, NULL, NULL);
155