summaryrefslogtreecommitdiffstats
path: root/testsuites
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-01-28 12:10:08 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-02-04 10:06:35 +0100
commit022851aba54d32831feaff13deb3d9943e130eee (patch)
treec1d6a8404dae393bd147790f6a9cf09c2f327b5a /testsuites
parentbsps: Thread-local storage (TLS) for linkcmds (diff)
downloadrtems-022851aba54d32831feaff13deb3d9943e130eee.tar.bz2
Add thread-local storage (TLS) support
Tested and implemented on ARM, m68k, PowerPC and SPARC. Other architectures need more work.
Diffstat (limited to 'testsuites')
-rw-r--r--testsuites/sptests/Makefile.am4
-rw-r--r--testsuites/sptests/configure.ac7
-rw-r--r--testsuites/sptests/sptls01/Makefile.am19
-rw-r--r--testsuites/sptests/sptls01/init.c98
-rw-r--r--testsuites/sptests/sptls01/sptls01.doc11
-rw-r--r--testsuites/sptests/sptls01/sptls01.scn5
-rw-r--r--testsuites/sptests/sptls02/Makefile.am20
-rw-r--r--testsuites/sptests/sptls02/init.cc256
-rw-r--r--testsuites/sptests/sptls02/sptls02.doc12
-rw-r--r--testsuites/sptests/sptls02/sptls02.scn4
10 files changed, 436 insertions, 0 deletions
diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am
index 7eab621dc5..1eacf5ceb3 100644
--- a/testsuites/sptests/Makefile.am
+++ b/testsuites/sptests/Makefile.am
@@ -30,6 +30,10 @@ SUBDIRS = \
spsimplesched03 spnsext01 spedfsched01 spedfsched02 spedfsched03 \
spcbssched01 spcbssched02 spcbssched03 spqreslib sptimespec01 \
spregion_err01 sppartition_err01
+if HAS_CPLUSPLUS
+SUBDIRS += sptls02
+endif
+SUBDIRS += sptls01
SUBDIRS += spintrcritical20
SUBDIRS += spintrcritical19
SUBDIRS += spcontext01
diff --git a/testsuites/sptests/configure.ac b/testsuites/sptests/configure.ac
index 6b14543e9e..623e784fd5 100644
--- a/testsuites/sptests/configure.ac
+++ b/testsuites/sptests/configure.ac
@@ -11,16 +11,21 @@ RTEMS_CANONICAL_TARGET_CPU
AM_INIT_AUTOMAKE([no-define foreign 1.12.2])
AM_MAINTAINER_MODE
+RTEMS_ENABLE_CXX
RTEMS_ENV_RTEMSBSP
RTEMS_CHECK_RTEMS_TEST_NO_PAUSE
RTEMS_PROJECT_ROOT
RTEMS_PROG_CC_FOR_TARGET
+RTEMS_PROG_CXX_FOR_TARGET
RTEMS_CANONICALIZE_TOOLS
RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP)
+RTEMS_CHECK_CXX(RTEMS_BSP)
+
+AM_CONDITIONAL([HAS_CPLUSPLUS],[test $HAS_CPLUSPLUS = "yes"])
# FIXME: We should get rid of this. It's a cludge.
AC_CHECK_SIZEOF([time_t])
@@ -31,6 +36,8 @@ AM_CONDITIONAL(HAS_CPUSET,test x"${ac_cv_header_sys_cpuset_h}" = x"yes")
# Explicitly list all Makefiles here
AC_CONFIG_FILES([Makefile
+sptls02/Makefile
+sptls01/Makefile
spintrcritical20/Makefile
spintrcritical19/Makefile
spcontext01/Makefile
diff --git a/testsuites/sptests/sptls01/Makefile.am b/testsuites/sptests/sptls01/Makefile.am
new file mode 100644
index 0000000000..5512b8aa3d
--- /dev/null
+++ b/testsuites/sptests/sptls01/Makefile.am
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = sptls01
+sptls01_SOURCES = init.c
+
+dist_rtems_tests_DATA = sptls01.scn sptls01.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 = $(sptls01_OBJECTS)
+LINK_LIBS = $(sptls01_LDLIBS)
+
+sptls01$(EXEEXT): $(sptls01_OBJECTS) $(sptls01_DEPENDENCIES)
+ @rm -f sptls01$(EXEEXT)
+ $(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/sptests/sptls01/init.c b/testsuites/sptests/sptls01/init.c
new file mode 100644
index 0000000000..76bd671dff
--- /dev/null
+++ b/testsuites/sptests/sptls01/init.c
@@ -0,0 +1,98 @@
+/*
+ * 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.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include "tmacros.h"
+
+static rtems_id master_task;
+
+static __thread volatile char tls_item = 123;
+
+static void check_tls_item(int expected)
+{
+ printf("TLS item = %i\n", tls_item);
+ rtems_test_assert(tls_item == expected);
+}
+
+static void task(rtems_task_argument arg)
+{
+ rtems_status_code sc;
+
+ check_tls_item(123);
+
+ sc = rtems_event_transient_send(master_task);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_suspend(RTEMS_SELF);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void test(void)
+{
+ rtems_id id;
+ rtems_status_code sc;
+
+ master_task = rtems_task_self();
+
+ check_tls_item(123);
+ tls_item = 5;
+
+ sc = rtems_task_create(
+ rtems_build_name('T', 'A', 'S', 'K'),
+ RTEMS_MINIMUM_PRIORITY,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &id
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_start(id, task, 0);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_delete(id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ check_tls_item(5);
+}
+
+static void Init(rtems_task_argument arg)
+{
+ puts("\n\n*** TEST SPTLS 1 ***");
+
+ test();
+
+ puts("*** END OF TEST SPTLS 1 ***");
+
+ rtems_test_exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_MAXIMUM_TASKS 2
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/sptests/sptls01/sptls01.doc b/testsuites/sptests/sptls01/sptls01.doc
new file mode 100644
index 0000000000..a6cc38b81c
--- /dev/null
+++ b/testsuites/sptests/sptls01/sptls01.doc
@@ -0,0 +1,11 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: sptls01
+
+directives:
+
+ - None
+
+concepts:
+
+ - Ensure that thread-local storage (TLS) works minimum alignment requirements.
diff --git a/testsuites/sptests/sptls01/sptls01.scn b/testsuites/sptests/sptls01/sptls01.scn
new file mode 100644
index 0000000000..eaeb11e21f
--- /dev/null
+++ b/testsuites/sptests/sptls01/sptls01.scn
@@ -0,0 +1,5 @@
+*** TEST SPTLS 1 ***
+TLS item = 123
+TLS item = 123
+TLS item = 5
+*** END OF TEST SPTLS 1 ***
diff --git a/testsuites/sptests/sptls02/Makefile.am b/testsuites/sptests/sptls02/Makefile.am
new file mode 100644
index 0000000000..d577b5b2c8
--- /dev/null
+++ b/testsuites/sptests/sptls02/Makefile.am
@@ -0,0 +1,20 @@
+rtems_tests_PROGRAMS = sptls02
+sptls02_SOURCES = init.cc
+
+dist_rtems_tests_DATA = sptls02.scn sptls02.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
+AM_CXXFLAGS += -std=c++11 -ftls-model=local-exec
+
+LINK_OBJS = $(sptls02_OBJECTS)
+LINK_LIBS = $(sptls02_LDLIBS)
+
+sptls02$(EXEEXT): $(sptls02_OBJECTS) $(sptls02_DEPENDENCIES)
+ @rm -f sptls02$(EXEEXT)
+ $(make-cxx-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/sptests/sptls02/init.cc b/testsuites/sptests/sptls02/init.cc
new file mode 100644
index 0000000000..d70419009a
--- /dev/null
+++ b/testsuites/sptests/sptls02/init.cc
@@ -0,0 +1,256 @@
+/*
+ * 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.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <rtems.h>
+#include <rtems/libcsupport.h>
+
+#include "tmacros.h"
+
+static thread_local long i123 = 123;
+
+alignas(256) static thread_local long a256 = 256;
+
+static thread_local long i0;
+
+alignas(512) static thread_local long a512;
+
+static void clobber()
+{
+ i123 = 0xdead0001;
+ a256 = 0xdead0002;
+ i0 = 0xdead0003;
+ a512 = 0xdead0004;
+}
+
+static long f456(bool clobber)
+{
+ static thread_local long fi456 = 456;
+
+ if (clobber) {
+ fi456 = 0xdead0003;
+ }
+
+ return fi456;
+}
+
+static long f0(bool clobber)
+{
+ static thread_local long fi0;
+
+ if (clobber) {
+ fi0 = 0xdead0004;
+ }
+
+ return fi0;
+}
+
+class C {
+ public:
+ static long c789()
+ {
+ return ci789;
+ }
+
+ static long c0()
+ {
+ return ci0;
+ }
+
+ static void clobber()
+ {
+ ci789 = 0xdead0005;
+ ci0 = 0xdead0006;
+ }
+
+ private:
+ static thread_local long ci789;
+
+ static thread_local long ci0;
+};
+
+thread_local long C::ci789 = 789;
+
+thread_local long C::ci0;
+
+class A {
+ public:
+ A(long i)
+ : ii(i), c(gc)
+ {
+ ++gc;
+ }
+
+ ~A()
+ {
+ --gc;
+ }
+
+ long i() const
+ {
+ return ii;
+ }
+
+ void clobber()
+ {
+ ii = ~ii;
+ c = ~c;
+ }
+
+ long counter() const
+ {
+ return c;
+ }
+
+ static long globalCounter()
+ {
+ return gc;
+ }
+
+ private:
+ static long gc;
+
+ long ii;
+
+ long c;
+};
+
+long A::gc;
+
+static volatile long mc;
+
+static thread_local A a1(mc + 1);
+static thread_local A a2(mc + 2);
+static thread_local A a3(mc + 3);
+
+static void checkTLSValues()
+{
+ rtems_test_assert(i123 == 123);
+ rtems_test_assert(a256 == 256);
+ rtems_test_assert((a256 & 255) == 0);
+ rtems_test_assert(i0 == 0);
+ rtems_test_assert(a512 == 0);
+ rtems_test_assert((a512 & 511) == 0);
+ rtems_test_assert(f456(false) == 456);
+ rtems_test_assert(f0(false) == 0);
+ rtems_test_assert(C::c789() == 789);
+ rtems_test_assert(C::c0() == 0);
+ rtems_test_assert(a1.i() == 1);
+ rtems_test_assert(a2.i() == 2);
+ rtems_test_assert(a3.i() == 3);
+}
+
+static rtems_id masterTask;
+
+static void task(rtems_task_argument arg)
+{
+ checkTLSValues();
+
+ const long gc = static_cast<long>(arg);
+
+ rtems_test_assert(A::globalCounter() == gc + 3);
+
+ rtems_test_assert(a1.counter() == gc + 0);
+ rtems_test_assert(a2.counter() == gc + 1);
+ rtems_test_assert(a3.counter() == gc + 2);
+
+ clobber();
+ f456(true);
+ f0(true);
+ C::clobber();
+ a1.clobber();
+ a2.clobber();
+ a3.clobber();
+
+ rtems_status_code sc = rtems_event_transient_send(masterTask);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_suspend(RTEMS_SELF);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void testTask()
+{
+ checkTLSValues();
+
+ rtems_id id;
+ rtems_status_code sc = rtems_task_create(
+ rtems_build_name('T', 'A', 'S', 'K'),
+ RTEMS_MINIMUM_PRIORITY,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &id
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ const long gc = A::globalCounter();
+
+ sc = rtems_task_start(id, task, gc);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_delete(id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ rtems_test_assert(A::globalCounter() == gc);
+
+ checkTLSValues();
+}
+
+extern "C" void Init(rtems_task_argument arg)
+{
+ puts("\n\n*** TEST SPTLS 2 ***");
+
+ printf("A::globalCounter() = %li\n", A::globalCounter());
+
+ checkTLSValues();
+
+ printf("A::globalCounter() = %li\n", A::globalCounter());
+
+ masterTask = rtems_task_self();
+
+ testTask();
+
+ rtems_resource_snapshot snapshot;
+ rtems_resource_snapshot_take(&snapshot);
+
+ testTask();
+
+ rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
+
+ puts("*** END OF TEST SPTLS 2 ***");
+
+ exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_MAXIMUM_TASKS 2
+#define CONFIGURE_MAXIMUM_SEMAPHORES 3
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/sptests/sptls02/sptls02.doc b/testsuites/sptests/sptls02/sptls02.doc
new file mode 100644
index 0000000000..7c19462166
--- /dev/null
+++ b/testsuites/sptests/sptls02/sptls02.doc
@@ -0,0 +1,12 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: sptls02
+
+directives:
+
+ - None
+
+concepts:
+
+ - Ensure thread-local storage (TLS) alignment requirements.
+ - Ensure thread-local storage (TLS) object construction and destruction.
diff --git a/testsuites/sptests/sptls02/sptls02.scn b/testsuites/sptests/sptls02/sptls02.scn
new file mode 100644
index 0000000000..e4c92f5f36
--- /dev/null
+++ b/testsuites/sptests/sptls02/sptls02.scn
@@ -0,0 +1,4 @@
+*** TEST SPTLS 2 ***
+A::globalCounter() = 0
+A::globalCounter() = 3
+*** END OF TEST SPTLS 2 ***