Skip to content

Commit cce1438

Browse files
Merge pull request #12008 from JulianHolzwarth/pr/xtimer_mutex_lock_timeout/new_test
tests/xtimer_mutex_lock_timeout: add new test with threads
2 parents 8c00e55 + 15349ea commit cce1438

3 files changed

Lines changed: 153 additions & 3 deletions

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
include ../Makefile.tests_common
22

3+
# copied from shell test
4+
BOARD_INSUFFICIENT_MEMORY = arduino-duemilanove \
5+
arduino-leonardo \
6+
arduino-nano \
7+
arduino-uno
8+
39
USEMODULE += xtimer
410
USEMODULE += shell
511

12+
#for testing
13+
#USEMODULE += ps
14+
#USEMODULE += shell_commands
15+
616
include $(RIOTBASE)/Makefile.include

tests/xtimer_mutex_lock_timeout/main.c

Lines changed: 132 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,32 +19,89 @@
1919
*/
2020

2121
#include <stdio.h>
22-
#include <stdlib.h>
2322
#include "shell.h"
2423
#include "xtimer.h"
24+
#include "thread.h"
25+
#include "msg.h"
26+
#include "irq.h"
2527

2628
/* timeout at one millisecond (1000 us) to make sure it does not spin. */
2729
#define LONG_MUTEX_TIMEOUT 1000
2830

31+
/* main Thread PID */
32+
static kernel_pid_t main_thread_pid;
33+
2934
/**
3035
* Foward declarations
3136
*/
3237
static int cmd_test_xtimer_mutex_lock_timeout_long_unlocked(int argc,
3338
char **argv);
3439
static int cmd_test_xtimer_mutex_lock_timeout_long_locked(int argc,
3540
char **argv);
41+
static int cmd_test_xtimer_mutex_lock_timeout_low_prio_thread(int argc,
42+
char **argv);
3643

3744
/**
3845
* @brief List of command for this application.
3946
*/
4047
static const shell_command_t shell_commands[] = {
41-
{ "mutex_timeout_long_unlocked", "unlocked mutex with long timeout",
48+
{ "mutex_timeout_long_unlocked", "unlocked mutex (no-spin timeout)",
4249
cmd_test_xtimer_mutex_lock_timeout_long_unlocked, },
43-
{ "mutex_timeout_long_locked", "locked mutex with long timeout",
50+
{ "mutex_timeout_long_locked", "locked mutex (no-spin timeout)",
4451
cmd_test_xtimer_mutex_lock_timeout_long_locked, },
52+
{ "mutex_timeout_long_locked_low",
53+
"lock low-prio-locked-mutex from high-prio-thread (no-spin timeout)",
54+
cmd_test_xtimer_mutex_lock_timeout_low_prio_thread, },
4555
{ NULL, NULL, NULL }
4656
};
4757

58+
/**
59+
* @brief stack for
60+
* cmd_test_xtimer_mutex_lock_timeout_low_prio_thread
61+
* not enough stack for doing printf only use puts
62+
*/
63+
static char t_stack[THREAD_STACKSIZE_DEFAULT];
64+
65+
/**
66+
* @brief send message and suicide thread
67+
*
68+
* This function will send a message to a thread without yielding
69+
* and terminates the calling thread. This can be used to wakeup a
70+
* thread and terminating yourself.
71+
* This function calls sched_task_exit()
72+
*
73+
* @param[in] m Pointer to preallocated @ref msg_t structure, must
74+
* not be NULL.
75+
* @param[in] target_pid PID of target thread
76+
*
77+
*/
78+
static NORETURN void msg_send_sched_task_exit(msg_t *m, kernel_pid_t target_pid)
79+
{
80+
(void)irq_disable();
81+
msg_send_int(m, target_pid);
82+
sched_task_exit();
83+
}
84+
85+
/**
86+
* @brief thread function for
87+
* cmd_test_xtimer_mutex_lock_timeout_low_prio_thread
88+
*/
89+
void *thread_low_prio_test(void *arg)
90+
{
91+
mutex_t *test_mutex = (mutex_t *)arg;
92+
msg_t msg;
93+
94+
puts("THREAD low prio: start");
95+
96+
mutex_lock(test_mutex);
97+
thread_wakeup(main_thread_pid);
98+
99+
mutex_unlock(test_mutex);
100+
101+
puts("THREAD low prio: exiting low");
102+
msg_send_sched_task_exit(&msg, main_thread_pid);
103+
}
104+
48105
/**
49106
* @brief shell command to test xtimer_mutex_lock_timeout
50107
*
@@ -77,6 +134,8 @@ static int cmd_test_xtimer_mutex_lock_timeout_long_unlocked(int argc,
77134
else {
78135
puts("error: mutex timed out");
79136
}
137+
/* to make the test easier to read */
138+
printf("\n");
80139

81140
return 0;
82141
}
@@ -114,6 +173,76 @@ static int cmd_test_xtimer_mutex_lock_timeout_long_locked(int argc,
114173
puts("error mutex not locked");
115174
}
116175
}
176+
/* to make the test easier to read */
177+
printf("\n");
178+
179+
return 0;
180+
}
181+
182+
/**
183+
* @brief shell command to test xtimer_mutex_lock_timeout
184+
*
185+
* This function will create a new thread with lower prio
186+
* than the main thread (this function should be called from
187+
* the main thread). The new thread will get a mutex and will
188+
* lock it. This function (main thread) calls xtimer_mutex_lock_timeout.
189+
* The other thread will then unlock the mutex. The main
190+
* thread gets the mutex and wakes up. The timer will not
191+
* trigger because the main threads gets the mutex.
192+
*
193+
* @param[in] argc Number of arguments
194+
* @param[in] argv Array of arguments
195+
*
196+
* @return 0 always
197+
*/
198+
static int cmd_test_xtimer_mutex_lock_timeout_low_prio_thread(int argc,
199+
char **argv)
200+
{
201+
(void)argc;
202+
(void)argv;
203+
puts("starting test: xtimer mutex lock timeout with thread");
204+
mutex_t test_mutex = MUTEX_INIT;
205+
main_thread_pid = thread_getpid();
206+
int current_thread_count = sched_num_threads;
207+
printf("threads = %d\n", current_thread_count);
208+
kernel_pid_t test_thread = thread_create(t_stack, sizeof(t_stack),
209+
THREAD_PRIORITY_MAIN + 1,
210+
THREAD_CREATE_STACKTEST,
211+
thread_low_prio_test,
212+
(void *)&test_mutex,
213+
"thread_low_prio_test");
214+
(void)test_thread;
215+
216+
thread_sleep();
217+
218+
puts("MAIN THREAD: calling xtimer_mutex_lock_timeout");
219+
220+
if (xtimer_mutex_lock_timeout(&test_mutex, LONG_MUTEX_TIMEOUT) == 0) {
221+
/* mutex has to be locked */
222+
if (mutex_trylock(&test_mutex) == 0) {
223+
puts("OK");
224+
}
225+
else {
226+
puts("error mutex not locked");
227+
}
228+
}
229+
else {
230+
puts("error: mutex timed out");
231+
}
232+
233+
current_thread_count = sched_num_threads;
234+
printf("threads = %d\n", current_thread_count);
235+
236+
/* to end the created thread */
237+
msg_t msg;
238+
puts("MAIN THREAD: waiting for created thread to end");
239+
msg_receive(&msg);
240+
241+
current_thread_count = sched_num_threads;
242+
printf("threads = %d\n", current_thread_count);
243+
244+
/* to make the test easier to read */
245+
printf("\n");
117246

118247
return 0;
119248
}

tests/xtimer_mutex_lock_timeout/tests/01-run.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,17 @@ def testfunc(child):
2727
child.expect("starting test: xtimer mutex lock timeout")
2828
child.expect("OK")
2929
child.expect_exact("> ")
30+
child.sendline("mutex_timeout_long_locked_low")
31+
child.expect("starting test: xtimer mutex lock timeout with thread")
32+
child.expect("threads = 2")
33+
child.expect("THREAD low prio: start")
34+
child.expect("MAIN THREAD: calling xtimer_mutex_lock_timeout")
35+
child.expect("OK")
36+
child.expect("threads = 3")
37+
child.expect("MAIN THREAD: waiting for created thread to end")
38+
child.expect("THREAD low prio: exiting low")
39+
child.expect("threads = 2")
40+
child.expect_exact("> ")
3041

3142

3243
if __name__ == "__main__":

0 commit comments

Comments
 (0)