summaryrefslogtreecommitdiffstats
path: root/testsuites/sptests/spmrsp01
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-05-21 10:33:43 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-05-28 10:50:41 +0200
commit8fcafdd553f3a564ecb5ab5093d01b29971418da (patch)
tree7807b3a4ae28e62f0218f8e20051b1b7e0143206 /testsuites/sptests/spmrsp01
parentbsps/sparc: Change tabs to spaces. (diff)
downloadrtems-8fcafdd553f3a564ecb5ab5093d01b29971418da.tar.bz2
score: Multiprocessor Resource Sharing Protocol
Add basic support for the Multiprocessor Resource Sharing Protocol (MrsP). The Multiprocessor Resource Sharing Protocol (MrsP) is defined in A. Burns and A.J. Wellings, A Schedulability Compatible Multiprocessor Resource Sharing Protocol - MrsP, Proceedings of the 25th Euromicro Conference on Real-Time Systems (ECRTS 2013), July 2013. It is a generalization of the Priority Ceiling Protocol to SMP systems. Each MrsP semaphore uses a ceiling priority per scheduler instance. These ceiling priorities can be specified with rtems_semaphore_set_priority(). A task obtaining or owning a MrsP semaphore will execute with the ceiling priority for its scheduler instance as specified by the MrsP semaphore object. Tasks waiting to get ownership of a MrsP semaphore will not relinquish the processor voluntarily. In case the owner of a MrsP semaphore gets preempted it can ask all tasks waiting for this semaphore to help out and temporarily borrow the right to execute on one of their assigned processors. The help out feature is not implemented with this patch.
Diffstat (limited to 'testsuites/sptests/spmrsp01')
-rw-r--r--testsuites/sptests/spmrsp01/Makefile.am19
-rw-r--r--testsuites/sptests/spmrsp01/init.c329
-rw-r--r--testsuites/sptests/spmrsp01/spmrsp01.doc13
-rw-r--r--testsuites/sptests/spmrsp01/spmrsp01.scn7
4 files changed, 368 insertions, 0 deletions
diff --git a/testsuites/sptests/spmrsp01/Makefile.am b/testsuites/sptests/spmrsp01/Makefile.am
new file mode 100644
index 0000000000..122b2a9018
--- /dev/null
+++ b/testsuites/sptests/spmrsp01/Makefile.am
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = spmrsp01
+spmrsp01_SOURCES = init.c
+
+dist_rtems_tests_DATA = spmrsp01.scn spmrsp01.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(spmrsp01_OBJECTS)
+LINK_LIBS = $(spmrsp01_LDLIBS)
+
+spmrsp01$(EXEEXT): $(spmrsp01_OBJECTS) $(spmrsp01_DEPENDENCIES)
+ @rm -f spmrsp01$(EXEEXT)
+ $(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/sptests/spmrsp01/init.c b/testsuites/sptests/spmrsp01/init.c
new file mode 100644
index 0000000000..d8da7871b1
--- /dev/null
+++ b/testsuites/sptests/spmrsp01/init.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/libcsupport.h>
+
+#include "tmacros.h"
+
+const char rtems_test_name[] = "SPMRSP 1";
+
+typedef struct {
+ rtems_id semaphore_id;
+ rtems_id task_id;
+} test_mrsp_context;
+
+static void create_not_defined(rtems_attribute attr)
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ sc = rtems_semaphore_create(
+ rtems_build_name('M', 'R', 'S', 'P'),
+ 1,
+ attr,
+ 0,
+ &id
+ );
+ rtems_test_assert(sc == RTEMS_NOT_DEFINED);
+}
+
+static void test_mrsp_create_errors(void)
+{
+ puts("test MrsP create errors");
+
+ create_not_defined(
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
+ | RTEMS_COUNTING_SEMAPHORE
+ );
+
+ create_not_defined(
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
+ | RTEMS_SIMPLE_BINARY_SEMAPHORE
+ );
+
+ create_not_defined(
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
+ | RTEMS_BINARY_SEMAPHORE
+ | RTEMS_PRIORITY
+ );
+
+ create_not_defined(
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
+ | RTEMS_INHERIT_PRIORITY
+ | RTEMS_BINARY_SEMAPHORE
+ );
+
+ create_not_defined(
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
+ | RTEMS_PRIORITY_CEILING
+ | RTEMS_BINARY_SEMAPHORE
+ );
+
+ create_not_defined(
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
+ | RTEMS_INHERIT_PRIORITY
+ | RTEMS_PRIORITY_CEILING
+ | RTEMS_BINARY_SEMAPHORE
+ );
+}
+
+static void assert_prio(rtems_task_priority expected_prio)
+{
+ rtems_status_code sc;
+ rtems_task_priority prio;
+
+ sc = rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &prio);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(prio == expected_prio);
+}
+
+static void test_mrsp_obtain_release(void)
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ puts("test MrsP obtain and release");
+
+ sc = rtems_semaphore_create(
+ rtems_build_name('M', 'R', 'S', 'P'),
+ 1,
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
+ | RTEMS_BINARY_SEMAPHORE,
+ 1,
+ &id
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ assert_prio(2);
+
+ sc = rtems_semaphore_obtain(id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ assert_prio(1);
+
+ sc = rtems_semaphore_delete(id);
+ rtems_test_assert(sc == RTEMS_RESOURCE_IN_USE);
+
+ sc = rtems_semaphore_release(id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ assert_prio(2);
+
+ sc = rtems_semaphore_delete(id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void test_mrsp_set_priority_errors(void)
+{
+ rtems_status_code sc;
+ rtems_id id;
+ rtems_id scheduler_id;
+ rtems_task_priority prio;
+
+ puts("test MrsP set priority errors");
+
+ sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_semaphore_create(
+ rtems_build_name('C', 'O', 'N', 'T'),
+ 0,
+ RTEMS_COUNTING_SEMAPHORE,
+ 0,
+ &id
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ prio = 1;
+ sc = rtems_semaphore_set_priority(RTEMS_ID_NONE, scheduler_id, prio, &prio);
+ rtems_test_assert(sc == RTEMS_INVALID_ID);
+
+ prio = 1;
+ sc = rtems_semaphore_set_priority(id, RTEMS_ID_NONE, prio, &prio);
+ rtems_test_assert(sc == RTEMS_INVALID_ID);
+
+ prio = 0xffffffff;
+ sc = rtems_semaphore_set_priority(id, scheduler_id, prio, &prio);
+ rtems_test_assert(sc == RTEMS_INVALID_PRIORITY);
+
+ prio = 1;
+ sc = rtems_semaphore_set_priority(id, scheduler_id, prio, NULL);
+ rtems_test_assert(sc == RTEMS_INVALID_ADDRESS);
+
+ prio = 1;
+ sc = rtems_semaphore_set_priority(id, scheduler_id, prio, &prio);
+ rtems_test_assert(sc == RTEMS_NOT_DEFINED);
+
+ sc = rtems_semaphore_delete(id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void test_mrsp_set_priority(void)
+{
+ rtems_status_code sc;
+ rtems_id id;
+ rtems_id scheduler_id;
+ rtems_task_priority prio;
+
+ puts("test MrsP set priority");
+
+ sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_semaphore_create(
+ rtems_build_name('M', 'R', 'S', 'P'),
+ 1,
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
+ | RTEMS_BINARY_SEMAPHORE,
+ 1,
+ &id
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ prio = RTEMS_CURRENT_PRIORITY;
+ sc = rtems_semaphore_set_priority(id, scheduler_id, prio, &prio);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(prio == 1);
+
+ prio = 1;
+ sc = rtems_semaphore_set_priority(id, scheduler_id, prio, &prio);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(prio == 1);
+
+ prio = 2;
+ sc = rtems_semaphore_set_priority(id, scheduler_id, prio, &prio);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(prio == 1);
+
+ prio = RTEMS_CURRENT_PRIORITY;
+ sc = rtems_semaphore_set_priority(id, scheduler_id, prio, &prio);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(prio == 2);
+
+ sc = rtems_semaphore_delete(id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void test_mrsp_task(rtems_task_argument arg)
+{
+ test_mrsp_context *ctx = (test_mrsp_context *) arg;
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_release(ctx->semaphore_id);
+ rtems_test_assert(sc == RTEMS_NOT_OWNER_OF_RESOURCE);
+
+ sc = rtems_semaphore_obtain(ctx->semaphore_id, RTEMS_NO_WAIT, 0);
+ rtems_test_assert(sc == RTEMS_UNSATISFIED);
+
+ sc = rtems_semaphore_obtain(ctx->semaphore_id, RTEMS_WAIT, 1);
+ rtems_test_assert(sc == RTEMS_TIMEOUT);
+
+ sc = rtems_event_transient_send(ctx->task_id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ rtems_task_delete(RTEMS_SELF);
+ rtems_test_assert(0);
+}
+
+static void test_mrsp_timeout_and_not_owner_of_resource(void)
+{
+ rtems_status_code sc;
+ rtems_id id;
+ rtems_id task_id;
+ test_mrsp_context ctx;
+
+ puts("test MrsP timeout and not owner of resource");
+
+ sc = rtems_semaphore_create(
+ rtems_build_name('M', 'R', 'S', 'P'),
+ 1,
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
+ | RTEMS_BINARY_SEMAPHORE,
+ 1,
+ &id
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_semaphore_obtain(id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_create(
+ rtems_build_name('M', 'R', 'S', 'P'),
+ 1,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &task_id
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ ctx.semaphore_id = id;
+ ctx.task_id = rtems_task_self();
+
+ sc = rtems_task_start(task_id, test_mrsp_task, (rtems_task_argument) &ctx);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_semaphore_release(id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_semaphore_delete(id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void Init(rtems_task_argument arg)
+{
+ rtems_resource_snapshot snapshot;
+
+ TEST_BEGIN();
+
+ rtems_resource_snapshot_take(&snapshot);
+
+ test_mrsp_create_errors();
+ test_mrsp_obtain_release();
+ test_mrsp_set_priority_errors();
+ test_mrsp_set_priority();
+ test_mrsp_timeout_and_not_owner_of_resource();
+
+ rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
+
+ TEST_END();
+ rtems_test_exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_TASKS 2
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+#define CONFIGURE_MAXIMUM_MRSP_SEMAPHORES 1
+
+#define CONFIGURE_INIT_TASK_PRIORITY 2
+
+#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/sptests/spmrsp01/spmrsp01.doc b/testsuites/sptests/spmrsp01/spmrsp01.doc
new file mode 100644
index 0000000000..e09cff11c7
--- /dev/null
+++ b/testsuites/sptests/spmrsp01/spmrsp01.doc
@@ -0,0 +1,13 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: spmrsp01
+
+directives:
+
+ - rtems_semaphore_create()
+ - rtems_semaphore_set_priority()
+
+concepts:
+
+ - Ensure that the RTEMS_MULTIPROCESSOR_RESOURCE_SHARING attribute and
+ semaphores work on uni-processor configurations.
diff --git a/testsuites/sptests/spmrsp01/spmrsp01.scn b/testsuites/sptests/spmrsp01/spmrsp01.scn
new file mode 100644
index 0000000000..29b616d217
--- /dev/null
+++ b/testsuites/sptests/spmrsp01/spmrsp01.scn
@@ -0,0 +1,7 @@
+*** BEGIN OF TEST SPMRSP 1 ***
+test MRSP create errors
+test MRSP obtain and release
+test MRSP set priority errors
+test MRSP set priority
+test MRSP timeout and not owner of resource
+*** END OF TEST SPMRSP 1 ***