summaryrefslogtreecommitdiffstats
path: root/testsuites/sptests/sptls02
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/sptests/sptls02
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/sptests/sptls02')
-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
4 files changed, 292 insertions, 0 deletions
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 ***