Skip to content

Commit

Permalink
tests/xtimer_mutex_lock_timeout/ new test with thread (lower prio tha…
Browse files Browse the repository at this point in the history
…n main thread) locking and unlocking mutex

cmd_test_xtimer_mutex_lock_timeout_low_prio_thread and thread_low_prio_test is added

This testfunction will test xtimer_mutex_lock_timeout with two threads (main and lower prio than main thread).

The main thread creates another thread and sleeps. While the main thread sleeps the other thread takes the mutex
and wakes the main thread up. Then calls xtimer_mutex_lock_timeout then the second thread unlockes the mutex and
the main thread gets it and waits for the created thread to end.

Has test messages showing the thread count. To make sure the created thread ends.
(test messages may be removed in the future)
  • Loading branch information
JulianHolzwarth committed Aug 14, 2019
1 parent 7198dff commit 17c6311
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 3 deletions.
109 changes: 106 additions & 3 deletions tests/xtimer_mutex_lock_timeout/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,28 @@
#include <stdio.h>
#include "shell.h"
#include "xtimer.h"
#include "thread.h"
#include "msg.h"
#include "irq.h"

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

/* timeout smaller than XTIMER_BACKOFF to make sure it spins. */
#define SHORT_MUTEX_TIMEOUT ((1 << XTIMER_SHIFT) + 1)

/* main Thread PID */
kernel_pid_t main_thread_pid;

/**
* Foward declarations
*/
static int cmd_test_xtimer_mutex_lock_timeout_long_unlocked(int argc,
char **argv);
static int cmd_test_xtimer_mutex_lock_timeout_long_locked(int argc,
char **argv);
static int cmd_test_xtimer_mutex_lock_timeout_low_prio_thread(int argc,
char **argv);
static int cmd_test_xtimer_mutex_lock_timeout_short_unlocked(int argc,
char **argv);
static int cmd_test_xtimer_mutex_lock_timeout_short_locked(int argc,
Expand All @@ -49,13 +57,42 @@ static const shell_command_t shell_commands[] = {
cmd_test_xtimer_mutex_lock_timeout_long_unlocked, },
{ "mutex_timeout_long_locked", "locked mutex with long timeout",
cmd_test_xtimer_mutex_lock_timeout_long_locked, },
{ "mutex_timeout_long_locked_low",
"locked mutex from lower prio thread function with long timeout",
cmd_test_xtimer_mutex_lock_timeout_low_prio_thread, },
{ "mutex_timeout_short_unlocked", "unlocked mutex with short timeout",
cmd_test_xtimer_mutex_lock_timeout_short_unlocked, },
{ "mutex_timeout_short_locked", "locked mutex with short timeout",
cmd_test_xtimer_mutex_lock_timeout_short_locked, },
{ NULL, NULL, NULL }
};

/**
* @brief thread function and stack for
* cmd_test_xtimer_mutex_lock_timeout_low_prio_thread
*/

char t_stack[THREAD_STACKSIZE_MAIN];

void *thread_low_prio_test(void *arg)
{
mutex_t *test_mutex = (mutex_t *)arg;
msg_t msg;

puts("THREAD low prio: start");

mutex_lock(test_mutex);
thread_wakeup(main_thread_pid);
while (msg_try_receive(&msg) == -1) {}

mutex_unlock(test_mutex);
(void)irq_disable();
puts("THREAD low prio: exiting low");
msg_send_int(&msg, main_thread_pid);

sched_task_exit();
}

/**
* @brief shell command to test xtimer_mutex_lock_timeout
*
Expand Down Expand Up @@ -88,7 +125,6 @@ static int cmd_test_xtimer_mutex_lock_timeout_long_unlocked(int argc,
else {
puts("error: mutex timed out");
}

/* to make the test easier to read */
printf("\n");

Expand Down Expand Up @@ -128,6 +164,75 @@ static int cmd_test_xtimer_mutex_lock_timeout_long_locked(int argc,
puts("error mutex not locked");
}
}
/* to make the test easier to read */
printf("\n");

return 0;
}

/**
* @brief shell command to test xtimer_mutex_lock_timeout
*
* This function will create a new thread with lower prio.
* than the main thread (this function should be called from
* the main thread). The new thread will get a mutex and will
* lock it. This function (main thread) messages the other
* thread and calls xtimer_mutex_lock_timeout.
* The other thread will then unlock the mutex. The main
* thread gets the mutex and wakes up. The timer will not
* trigger because the main threads gets the mutex.
*
* @param[in] argc Number of arguments
* @param[in] argv Array of arguments
*
* @return 0 on success
*/
static int cmd_test_xtimer_mutex_lock_timeout_low_prio_thread(int argc,
char **argv)
{
(void)argc;
(void)argv;
puts("starting test: xtimer mutex lock timeout with thread");
mutex_t test_mutex = MUTEX_INIT;
main_thread_pid = thread_getpid();
int current_thread_count = sched_num_threads;
printf("threads = %d\n", current_thread_count);
kernel_pid_t test_thread = thread_create(t_stack, sizeof(t_stack),
THREAD_PRIORITY_MAIN + 1,
THREAD_CREATE_STACKTEST,
thread_low_prio_test,
(void *)&test_mutex,
"thread_low_prio_test");

thread_sleep();

msg_t msg;

puts("MAIN THREAD: calling xtimer_mutex_lock_timeout");

msg_send(&msg, test_thread);
if (xtimer_mutex_lock_timeout(&test_mutex, LONG_MUTEX_TIMEOUT) == 0) {
/* mutex has to be locked */
if (mutex_trylock(&test_mutex) == 0) {
puts("OK");
}
else {
puts("error mutex not locked");
}
}
else {
puts("error: mutex timed out");
}

current_thread_count = sched_num_threads;
printf("threads = %d\n", current_thread_count);

/* to end the created thread */
puts("MAIN THREAD: waiting for created thread to end");
msg_receive(&msg);

current_thread_count = sched_num_threads;
printf("threads = %d\n", current_thread_count);

/* to make the test easier to read */
printf("\n");
Expand Down Expand Up @@ -169,7 +274,6 @@ static int cmd_test_xtimer_mutex_lock_timeout_short_locked(int argc,
puts("error mutex not locked");
}
}

/* to make the test easier to read */
printf("\n");

Expand Down Expand Up @@ -209,7 +313,6 @@ static int cmd_test_xtimer_mutex_lock_timeout_short_unlocked(int argc,
else {
puts("Error: mutex timed out");
}

/* to make the test easier to read */
printf("\n");

Expand Down
11 changes: 11 additions & 0 deletions tests/xtimer_mutex_lock_timeout/tests/01-run.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ def testfunc(child):
child.expect("starting test: xtimer mutex lock timeout")
child.expect("OK")
child.expect_exact("> ")
child.sendline("mutex_timeout_long_locked_low")
child.expect("starting test: xtimer mutex lock timeout with thread")
child.expect("threads = 2")
child.expect("THREAD low prio: start")
child.expect("MAIN THREAD: calling xtimer_mutex_lock_timeout")
child.expect("OK")
child.expect("threads = 3")
child.expect("MAIN THREAD: waiting for created thread to end")
child.expect("THREAD low prio: exiting low")
child.expect("threads = 2")
child.expect_exact("> ")
child.sendline("mutex_timeout_short_locked")
child.expect("starting test: xtimer mutex lock timeout with short timeout and locked mutex")
child.expect("OK")
Expand Down

0 comments on commit 17c6311

Please sign in to comment.