1 /*
2  * Copyright (c) 2017 Wind River Systems, Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/sys/printk.h>
9 #include <zephyr/ztest.h>
10 
11 #define NUM_TIMEOUTS 3
12 
13 static struct k_timer timer[NUM_TIMEOUTS];
14 static struct k_sem sem[NUM_TIMEOUTS];
15 
16 static int results[NUM_TIMEOUTS], cur;
17 
thread(void * p1,void * p2,void * p3)18 static void thread(void *p1, void *p2, void *p3)
19 {
20 	ARG_UNUSED(p2);
21 	ARG_UNUSED(p3);
22 
23 	uintptr_t id = (uintptr_t)p1;
24 
25 	k_timer_status_sync(&timer[id]);
26 
27 	/* no need to protect cur, all threads have the same prio */
28 	results[cur++] = id;
29 
30 	k_sem_give(&sem[id]);
31 }
32 
33 #define STACKSIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
34 
35 static K_THREAD_STACK_ARRAY_DEFINE(stacks, NUM_TIMEOUTS, STACKSIZE);
36 static struct k_thread threads[NUM_TIMEOUTS];
37 
38 /**
39  * @defgroup kernel_timeout_tests Timeout Order
40  * @ingroup all_tests
41  * @{
42  * @}
43  *
44  * @addtogroup kernel_timeout_tests
45  * @{
46  */
47 
48 /**
49  * @brief Test timeout ordering
50  *
51  * @details Timeouts, when expiring on the same tick, should be handled
52  * in the same order they were queued.
53  *
54  * @see k_timer_start()
55  */
ZTEST(common_1cpu,test_timeout_order)56 ZTEST(common_1cpu, test_timeout_order)
57 {
58 	int ii, prio = k_thread_priority_get(k_current_get()) + 1;
59 
60 	for (ii = 0; ii < NUM_TIMEOUTS; ii++) {
61 		(void)k_thread_create(&threads[ii], stacks[ii], STACKSIZE,
62 				      thread, INT_TO_POINTER(ii), 0, 0,
63 				      prio, 0, K_NO_WAIT);
64 		k_timer_init(&timer[ii], 0, 0);
65 		k_sem_init(&sem[ii], 0, 1);
66 		results[ii] = -1;
67 	}
68 
69 
70 	uint32_t uptime = k_uptime_get_32();
71 
72 	/* sync on tick */
73 	while (uptime == k_uptime_get_32()) {
74 		Z_SPIN_DELAY(50);
75 	}
76 
77 	for (ii = 0; ii < NUM_TIMEOUTS; ii++) {
78 		k_timer_start(&timer[ii], K_MSEC(100), K_NO_WAIT);
79 	}
80 
81 	/* Wait for all timers to fire */
82 	k_msleep(125);
83 
84 	/* Check results */
85 	for (ii = 0; ii < NUM_TIMEOUTS; ii++) {
86 		zassert_equal(results[ii], ii, "");
87 	}
88 
89 	/* Clean up */
90 	for (ii = 0; ii < NUM_TIMEOUTS; ii++) {
91 		k_timer_stop(&timer[ii]);
92 		k_thread_join(&threads[ii], K_FOREVER);
93 	}
94 }
95 
96 /**
97  * @}
98  */
99 extern void *common_setup(void);
100 ZTEST_SUITE(common_1cpu, NULL, common_setup,
101 		ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL);
102