Added test application for reentrant mutexes
* fixed BOARD_INSUFFICIENT_MEMORY for rmutex
This commit is contained in:
parent
b9c2fc8254
commit
b9bb22b393
6
tests/rmutex/Makefile
Normal file
6
tests/rmutex/Makefile
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
APPLICATION = rmutex
|
||||||
|
include ../Makefile.tests_common
|
||||||
|
|
||||||
|
BOARD_INSUFFICIENT_MEMORY := stm32f0discovery weio nucleo-f030 nucleo32-f042
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.include
|
||||||
86
tests/rmutex/README.md
Normal file
86
tests/rmutex/README.md
Normal file
@ -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.
|
||||||
91
tests/rmutex/main.c
Normal file
91
tests/rmutex/main.c
Normal file
@ -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;
|
||||||
|
}
|
||||||
48
tests/rmutex/tests/01-run.py
Executable file
48
tests/rmutex/tests/01-run.py
Executable file
@ -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))
|
||||||
Loading…
x
Reference in New Issue
Block a user