summaryrefslogtreecommitdiffstats
path: root/testsuites/sptests/sptls02/init.cc
diff options
context:
space:
mode:
Diffstat (limited to 'testsuites/sptests/sptls02/init.cc')
-rw-r--r--testsuites/sptests/sptls02/init.cc256
1 files changed, 256 insertions, 0 deletions
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>