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