diff --git a/sys/xtimer/xtimer.c b/sys/xtimer/xtimer.c index 1ba5152dbc..787bf7d702 100644 --- a/sys/xtimer/xtimer.c +++ b/sys/xtimer/xtimer.c @@ -38,10 +38,14 @@ #define ENABLE_DEBUG 0 #include "debug.h" +/* + * @brief: struct for mutex lock with timeout + * xtimer_mutex_lock_timeout() uses it to give information to the timer callback function + */ typedef struct { mutex_t *mutex; thread_t *thread; - int timeout; + volatile int timeout; } mutex_thread_t; static void _callback_unlock_mutex(void* arg) diff --git a/tests/xtimer_mutex_lock_timeout/Makefile b/tests/xtimer_mutex_lock_timeout/Makefile new file mode 100644 index 0000000000..71206adce3 --- /dev/null +++ b/tests/xtimer_mutex_lock_timeout/Makefile @@ -0,0 +1,8 @@ +include ../Makefile.tests_common + +USEMODULE += xtimer +USEMODULE += shell + +TEST_ON_CI_WHITELIST += all + +include $(RIOTBASE)/Makefile.include diff --git a/tests/xtimer_mutex_lock_timeout/main.c b/tests/xtimer_mutex_lock_timeout/main.c new file mode 100644 index 0000000000..4630096575 --- /dev/null +++ b/tests/xtimer_mutex_lock_timeout/main.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2019 Freie Universität Berlin, + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup tests + * @{ + * + * @file + * @brief testing xtimer_mutex_lock_timeout function + * + * + * @author Julian Holzwarth + * + */ + +#include +#include +#include "shell.h" +#include "xtimer.h" + +/* timeout at one millisecond (1000 us) to make sure it does not spin. */ +#define LONG_MUTEX_TIMEOUT 1000 + +/** + * 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); + +/** + * @brief List of command for this application. + */ +static const shell_command_t shell_commands[] = { + { "mutex_timeout_long_unlocked", "unlocked mutex with long timeout", + 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, }, + { NULL, NULL, NULL } +}; + +/** + * @brief shell command to test xtimer_mutex_lock_timeout + * + * the mutex is not locked before the function call and + * the timer long. Meaning the timer will get removed + * before triggering. + * + * @param[in] argc Number of arguments + * @param[in] argv Array of arguments + * + * @return 0 on success + */ +static int cmd_test_xtimer_mutex_lock_timeout_long_unlocked(int argc, + char **argv) +{ + (void)argc; + (void)argv; + puts("starting test: xtimer mutex lock timeout"); + mutex_t test_mutex = MUTEX_INIT; + + 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"); + } + + return 0; +} + +/** + * @brief shell command to test xtimer_mutex_lock_timeout + * + * the mutex is locked before the function call and + * the timer long. Meaning the timer will trigger + * and remove the thread from the mutex waiting list. + * + * @param[in] argc Number of arguments + * @param[in] argv Array of arguments + * + * @return 0 on success + */ +static int cmd_test_xtimer_mutex_lock_timeout_long_locked(int argc, + char **argv) +{ + (void)argc; + (void)argv; + puts("starting test: xtimer mutex lock timeout"); + mutex_t test_mutex = MUTEX_INIT; + mutex_lock(&test_mutex); + + if (xtimer_mutex_lock_timeout(&test_mutex, LONG_MUTEX_TIMEOUT) == 0) { + puts("Error: mutex taken"); + } + else { + /* mutex has to be locked */ + if (mutex_trylock(&test_mutex) == 0) { + puts("OK"); + } + else { + puts("error mutex not locked"); + } + } + + return 0; +} + +/** + * @brief main function starting shell + * + * @return 0 on success + */ +int main(void) +{ + puts("Starting shell..."); + char line_buf[SHELL_DEFAULT_BUFSIZE]; + shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); + + return 0; +} diff --git a/tests/xtimer_mutex_lock_timeout/tests/01-run.py b/tests/xtimer_mutex_lock_timeout/tests/01-run.py new file mode 100755 index 0000000000..b56fe226f7 --- /dev/null +++ b/tests/xtimer_mutex_lock_timeout/tests/01-run.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2019 Freie Universität Berlin, +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. + +# @author Julian Holzwarth + +import sys +import pexpect +from testrunner import run + + +def testfunc(child): + # Try to wait for the shell + for _ in range(0, 10): + child.sendline("help") + if child.expect_exact(["> ", pexpect.TIMEOUT], timeout=1) == 0: + break + child.sendline("mutex_timeout_long_unlocked") + child.expect("starting test: xtimer mutex lock timeout") + child.expect("OK") + child.expect_exact("> ") + child.sendline("mutex_timeout_long_locked") + child.expect("starting test: xtimer mutex lock timeout") + child.expect("OK") + child.expect_exact("> ") + + +if __name__ == "__main__": + sys.exit(run(testfunc))