From fc3f5f562b23161fcbbfdb8e94297d51dde29dec Mon Sep 17 00:00:00 2001 From: Karl Fessel Date: Thu, 15 Apr 2021 15:02:41 +0200 Subject: [PATCH] test/sys_sched_round_robin: add test for sys_sched_round_robin with README.md --- tests/sys_sched_round_robin/Makefile | 10 +++ tests/sys_sched_round_robin/Makefile.ci | 14 +++++ tests/sys_sched_round_robin/README.md | 54 ++++++++++++++++ tests/sys_sched_round_robin/main.c | 70 +++++++++++++++++++++ tests/sys_sched_round_robin/tests/01-run.py | 21 +++++++ 5 files changed, 169 insertions(+) create mode 100644 tests/sys_sched_round_robin/Makefile create mode 100644 tests/sys_sched_round_robin/Makefile.ci create mode 100644 tests/sys_sched_round_robin/README.md create mode 100644 tests/sys_sched_round_robin/main.c create mode 100755 tests/sys_sched_round_robin/tests/01-run.py diff --git a/tests/sys_sched_round_robin/Makefile b/tests/sys_sched_round_robin/Makefile new file mode 100644 index 0000000000..26e633d071 --- /dev/null +++ b/tests/sys_sched_round_robin/Makefile @@ -0,0 +1,10 @@ +include ../Makefile.tests_common + +# Set to 1 to disable the round-robin scheduling module +NORR ?= 0 + +ifneq (1,$(NORR)) + USEMODULE += sched_round_robin +endif + +include $(RIOTBASE)/Makefile.include diff --git a/tests/sys_sched_round_robin/Makefile.ci b/tests/sys_sched_round_robin/Makefile.ci new file mode 100644 index 0000000000..a387bf522a --- /dev/null +++ b/tests/sys_sched_round_robin/Makefile.ci @@ -0,0 +1,14 @@ +BOARD_INSUFFICIENT_MEMORY := \ + arduino-duemilanove \ + arduino-leonardo \ + arduino-nano \ + arduino-uno \ + atmega328p \ + atmega328p-xplained-mini\ + nucleo-f031k6 \ + nucleo-f042k6 \ + nucleo-l011k4 \ + samd10-xmini \ + stk3200 \ + stm32f030f4-demo \ + # diff --git a/tests/sys_sched_round_robin/README.md b/tests/sys_sched_round_robin/README.md new file mode 100644 index 0000000000..fca8b35058 --- /dev/null +++ b/tests/sys_sched_round_robin/README.md @@ -0,0 +1,54 @@ +Round Robing Scheduling Test +======================== + +This application is a simple test case for round-robin scheduling. +Two threads are started with the same priority. +The first thread is a busy loop and is started first. +The second thread unlocks a mutex allowing the main thread to continue and exit. + +Without Round Robin scheduling the busy loop thread would run indefinitely, +with round-robin in eventually getting de-scheduled allowing the main thread to run and exit. + +Usage +===== + +By default `sched_round_robin` is included: + +`make tests/sys_sched_round_robin flash term` + +``` +...Board Initialisation... + +Help: Press s to start test, r to print it is ready +s +START +main(): This is RIOT! (Version: ...) +starting threads +double locking mutex +mutex_thread yield +bad thread looping +unlock mutex +[SUCCESS] + +``` + +It can be excluded from the build by setting the command-line argument `NORR=1`: + + +`NORR=1 make tests/sys_sched_round_robin flash term` + +``` +...Board Initialisation... + +Help: Press s to start test, r to print it is ready +s +START +main(): This is RIOT! (Version: ...) +starting threads +double locking mutex +mutex_thread yield +bad thread looping +``` + +This will loop endlessly as the bad thread does not release the CPU, +`make test` will timeout in that case. diff --git a/tests/sys_sched_round_robin/main.c b/tests/sys_sched_round_robin/main.c new file mode 100644 index 0000000000..61b30d2272 --- /dev/null +++ b/tests/sys_sched_round_robin/main.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 TUBA Freiberg + * + * 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 sys/sched_round_robin + * @author Karl Fessel + * @} + */ + +#include +#include + +#include "thread.h" +#include "mutex.h" + +static mutex_t _shared_mutex; + +void * thread_mutex_unlock(void *d) +{ + (void) d; + puts("mutex_thread yield"); + thread_yield(); + puts("unlock mutex"); + mutex_unlock(&_shared_mutex); + return NULL; +} + +void * thread_bad(void *d) +{ + (void) d; + puts("bad thread looping"); + for (;;) { + /* I'm a bad thread I do nothing and I do that all the time */ + } +} + +/* each thread gets a stack */ +static char stack[2][THREAD_STACKSIZE_DEFAULT]; + +/* with priority inversion this should be set to THREAD_PRIORITY_MAIN + * until then a lower priority (higher number) is the better choice */ +const uint8_t shared_prio = THREAD_PRIORITY_MAIN + 1; + +int main(void) +{ + puts("starting threads"); + + mutex_init(&_shared_mutex); + thread_create(stack[0], sizeof(stack[0]), shared_prio, THREAD_CREATE_STACKTEST, + thread_mutex_unlock, NULL, "TMutex"); + thread_create(stack[1], sizeof(stack[1]), shared_prio, THREAD_CREATE_STACKTEST, + thread_bad, NULL, "TBad"); + + puts("double locking mutex"); + + mutex_lock(&_shared_mutex); + mutex_lock(&_shared_mutex); + + /* success: mutex got unlocked, which means thread "TMutex" got cpu time + * even though "TBad" was trying to hog the whole CPU */ + puts("[SUCCESS]"); +} diff --git a/tests/sys_sched_round_robin/tests/01-run.py b/tests/sys_sched_round_robin/tests/01-run.py new file mode 100755 index 0000000000..7a9289e5c9 --- /dev/null +++ b/tests/sys_sched_round_robin/tests/01-run.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2021 TUBA Freiberg +# +# 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. + +import sys +from testrunner import run + + +def testfunc(child): + child.expect_exact("starting threads") + child.expect_exact("double locking mutex") + child.expect_exact("unlock mutex") + child.expect_exact("[SUCCESS]") + + +if __name__ == "__main__": + sys.exit(run(testfunc))