-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added test application for reentrant mutexes
* fixed BOARD_INSUFFICIENT_MEMORY for rmutex
- Loading branch information
1 parent
b9c2fc8
commit b9bb22b
Showing
4 changed files
with
231 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
APPLICATION = rmutex | ||
include ../Makefile.tests_common | ||
|
||
BOARD_INSUFFICIENT_MEMORY := stm32f0discovery weio nucleo-f030 nucleo32-f042 | ||
|
||
include $(RIOTBASE)/Makefile.include |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
Expected result | ||
=============== | ||
|
||
When successful, you should see 5 different threads printing their | ||
PID, priority and recursion depth. The thread with the lowest priority | ||
should be able to lock (and unlock) the mutex first, followed by the | ||
other threads in the order of their priority (highest next). If two | ||
threads have the same priority the lower thread id should acquire the | ||
lock. The output should look like the following: | ||
|
||
``` | ||
main(): This is RIOT! (Version: xxx) | ||
Recursive Mutex test | ||
Please refer to the README.md for more information | ||
Recursive Mutex test | ||
Please refer to the README.md for more information | ||
T3 (prio 6, depth 0): trying to lock rmutex now | ||
T4 (prio 4, depth 0): trying to lock rmutex now | ||
T5 (prio 5, depth 0): trying to lock rmutex now | ||
T6 (prio 2, depth 0): trying to lock rmutex now | ||
T7 (prio 3, depth 0): trying to lock rmutex now | ||
main: unlocking recursive mutex | ||
T6 (prio 2, depth 0): locked rmutex now | ||
T6 (prio 2, depth 1): trying to lock rmutex now | ||
T6 (prio 2, depth 1): locked rmutex now | ||
T6 (prio 2, depth 2): trying to lock rmutex now | ||
T6 (prio 2, depth 2): locked rmutex now | ||
T6 (prio 2, depth 3): trying to lock rmutex now | ||
T6 (prio 2, depth 3): locked rmutex now | ||
T6 (prio 2, depth 3): unlocked rmutex | ||
T6 (prio 2, depth 2): unlocked rmutex | ||
T6 (prio 2, depth 1): unlocked rmutex | ||
T6 (prio 2, depth 0): unlocked rmutex | ||
T7 (prio 3, depth 0): locked rmutex now | ||
T7 (prio 3, depth 1): trying to lock rmutex now | ||
T7 (prio 3, depth 1): locked rmutex now | ||
T7 (prio 3, depth 2): trying to lock rmutex now | ||
T7 (prio 3, depth 2): locked rmutex now | ||
T7 (prio 3, depth 3): trying to lock rmutex now | ||
T7 (prio 3, depth 3): locked rmutex now | ||
T7 (prio 3, depth 4): trying to lock rmutex now | ||
T7 (prio 3, depth 4): locked rmutex now | ||
T7 (prio 3, depth 4): unlocked rmutex | ||
T7 (prio 3, depth 3): unlocked rmutex | ||
T7 (prio 3, depth 2): unlocked rmutex | ||
T7 (prio 3, depth 1): unlocked rmutex | ||
T7 (prio 3, depth 0): unlocked rmutex | ||
T4 (prio 4, depth 0): locked rmutex now | ||
T4 (prio 4, depth 1): trying to lock rmutex now | ||
T4 (prio 4, depth 1): locked rmutex now | ||
T4 (prio 4, depth 2): trying to lock rmutex now | ||
T4 (prio 4, depth 2): locked rmutex now | ||
T4 (prio 4, depth 2): unlocked rmutex | ||
T4 (prio 4, depth 1): unlocked rmutex | ||
T4 (prio 4, depth 0): unlocked rmutex | ||
T5 (prio 5, depth 0): locked rmutex now | ||
T5 (prio 5, depth 1): trying to lock rmutex now | ||
T5 (prio 5, depth 1): locked rmutex now | ||
T5 (prio 5, depth 2): trying to lock rmutex now | ||
T5 (prio 5, depth 2): locked rmutex now | ||
T5 (prio 5, depth 2): unlocked rmutex | ||
T5 (prio 5, depth 1): unlocked rmutex | ||
T5 (prio 5, depth 0): unlocked rmutex | ||
T3 (prio 6, depth 0): locked rmutex now | ||
T3 (prio 6, depth 1): trying to lock rmutex now | ||
T3 (prio 6, depth 1): locked rmutex now | ||
T3 (prio 6, depth 2): trying to lock rmutex now | ||
T3 (prio 6, depth 2): locked rmutex now | ||
T3 (prio 6, depth 3): trying to lock rmutex now | ||
T3 (prio 6, depth 3): locked rmutex now | ||
T3 (prio 6, depth 4): trying to lock rmutex now | ||
T3 (prio 6, depth 4): locked rmutex now | ||
T3 (prio 6, depth 4): unlocked rmutex | ||
T3 (prio 6, depth 3): unlocked rmutex | ||
T3 (prio 6, depth 2): unlocked rmutex | ||
T3 (prio 6, depth 1): unlocked rmutex | ||
T3 (prio 6, depth 0): unlocked rmutex | ||
Test END, check the order of priorities above. | ||
``` | ||
|
||
Background | ||
========== | ||
This test application stresses a mutex with a number of threads waiting on it. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* | ||
* Copyright (C) 2016 Theobroma Systems Design & Consulting GmbH | ||
* | ||
* 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 Test application for testing recursive mutexes | ||
* | ||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de> | ||
* @author Martin Elshuber <martin.elshuber@theobroma-systems.com> | ||
* @} | ||
*/ | ||
|
||
#include <stdio.h> | ||
|
||
#include "rmutex.h" | ||
#include "thread.h" | ||
|
||
#define THREAD_NUMOF (5U) | ||
|
||
extern volatile thread_t *sched_active_thread; | ||
|
||
static char stacks[THREAD_NUMOF][THREAD_STACKSIZE_MAIN]; | ||
|
||
static const char prios[THREAD_NUMOF] = {THREAD_PRIORITY_MAIN - 1, 4, 5, 2, 4}; | ||
static const char depth[THREAD_NUMOF] = {5, 3, 3, 4, 5}; | ||
|
||
static rmutex_t testlock; | ||
|
||
static void lock_recursive(char n, char depth) | ||
{ | ||
volatile thread_t *t = sched_active_thread; | ||
|
||
printf("T%i (prio %i, depth %i): trying to lock rmutex now\n", | ||
(int)t->pid, (int)t->priority, (int)n); | ||
rmutex_lock(&testlock); | ||
|
||
printf("T%i (prio %i, depth %i): locked rmutex now\n", | ||
(int)t->pid, (int)t->priority, (int)n); | ||
|
||
if (n + 1 < depth) | ||
lock_recursive(n + 1, depth); | ||
|
||
thread_yield(); | ||
|
||
rmutex_unlock(&testlock); | ||
|
||
printf("T%i (prio %i, depth %i): unlocked rmutex\n", | ||
(int)t->pid, (int)t->priority, (int)n); | ||
} | ||
|
||
static void *lockme(void *arg) | ||
{ | ||
intptr_t depth = (intptr_t)arg; | ||
|
||
lock_recursive(0, depth); | ||
|
||
return NULL; | ||
} | ||
|
||
int main(void) | ||
{ | ||
puts("Recursive Mutex test"); | ||
puts("Please refer to the README.md for more information\n"); | ||
|
||
rmutex_init(&testlock); | ||
|
||
/* lock mutex, so that spawned threads have to wait */ | ||
rmutex_lock(&testlock); | ||
/* create threads */ | ||
for (unsigned i = 0; i < THREAD_NUMOF; i++) { | ||
thread_create(stacks[i], sizeof(stacks[i]), prios[i], 0, | ||
lockme, (void*)(intptr_t)depth[i], "t"); | ||
} | ||
/* allow threads to lock the mutex */ | ||
printf("main: unlocking recursive mutex\n"); | ||
|
||
rmutex_unlock(&testlock); | ||
|
||
rmutex_lock(&testlock); | ||
puts("\nTest END, check the order of priorities above."); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#!/usr/bin/env python3 | ||
|
||
# Copyright (C) 2016 Theobroma Systems Design & Consulting GmbH | ||
# | ||
# 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: Martin Elshuber <martin.elshuber@theobroma-systems.com> | ||
|
||
import os | ||
import sys | ||
|
||
sys.path.append(os.path.join(os.environ['RIOTBASE'], 'dist/tools/testrunner')) | ||
import testrunner | ||
|
||
thread_prio = { | ||
3: 6, | ||
4: 4, | ||
5: 5, | ||
6: 2, | ||
7: 4 | ||
} | ||
|
||
lock_depth = { | ||
3: 5, | ||
4: 3, | ||
5: 3, | ||
6: 4, | ||
7: 5 | ||
} | ||
|
||
def thread_prio_sort(x): | ||
return thread_prio.get(x)*1000 + x | ||
|
||
def testfunc(child): | ||
for k in thread_prio.keys(): | ||
child.expect(u"T%i \(prio %i, depth 0\): trying to lock rmutex now" % | ||
(k, thread_prio[k])) | ||
|
||
pri_sorted = sorted(thread_prio, key=thread_prio_sort); | ||
for T in pri_sorted: | ||
for depth in range(lock_depth[T]): | ||
child.expect(u"T%i \(prio %i, depth %i\): locked rmutex now" % | ||
(T, thread_prio[T], depth)) | ||
|
||
if __name__ == "__main__": | ||
sys.exit(testrunner.run(testfunc)) |