File indexing completed on 2025-05-11 08:24:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031
0032 #include "sptls02.h"
0033
0034 #include <stdio.h>
0035 #include <stdlib.h>
0036
0037 #include <rtems.h>
0038 #include <rtems/libcsupport.h>
0039 #include <rtems/stackchk.h>
0040
0041 #include <tmacros.h>
0042
0043 const char rtems_test_name[] = "SPTLS 2";
0044
0045 static thread_local long i123 = 123;
0046
0047 alignas(256) static thread_local long a256 = 256;
0048
0049 static thread_local long i0;
0050
0051 alignas(RTEMS_MINIMUM_STACK_SIZE) static thread_local long a;
0052
0053 int seven()
0054 {
0055 return 7;
0056 }
0057
0058 static void clobber()
0059 {
0060 extern_int = 0xdead0007;
0061 i123 = 0xdead0001;
0062 a256 = 0xdead0002;
0063 i0 = 0xdead0003;
0064 a = 0xdead0004;
0065 }
0066
0067 static long f456(bool clobber)
0068 {
0069 static thread_local long fi456 = 456;
0070
0071 if (clobber) {
0072 fi456 = 0xdead0003;
0073 }
0074
0075 return fi456;
0076 }
0077
0078 static long f0(bool clobber)
0079 {
0080 static thread_local long fi0;
0081
0082 if (clobber) {
0083 fi0 = 0xdead0004;
0084 }
0085
0086 return fi0;
0087 }
0088
0089 class C {
0090 public:
0091 static long c789()
0092 {
0093 return ci789;
0094 }
0095
0096 static long c0()
0097 {
0098 return ci0;
0099 }
0100
0101 static void clobber()
0102 {
0103 ci789 = 0xdead0005;
0104 ci0 = 0xdead0006;
0105 }
0106
0107 private:
0108 static thread_local long ci789;
0109
0110 static thread_local long ci0;
0111 };
0112
0113 thread_local long C::ci789 = 789;
0114
0115 thread_local long C::ci0;
0116
0117 class A {
0118 public:
0119 A(long i)
0120 : ii(i), c(gc)
0121 {
0122 ++gc;
0123 }
0124
0125 ~A()
0126 {
0127 --gc;
0128 }
0129
0130 long i() const
0131 {
0132 return ii;
0133 }
0134
0135 void clobber()
0136 {
0137 ii = ~ii;
0138 c = ~c;
0139 }
0140
0141 long counter() const
0142 {
0143 return c;
0144 }
0145
0146 static long globalCounter()
0147 {
0148 return gc;
0149 }
0150
0151 private:
0152 static long gc;
0153
0154 long ii;
0155
0156 long c;
0157 };
0158
0159 long A::gc;
0160
0161 static volatile long mc;
0162
0163 static thread_local A a1(mc + 1);
0164 static thread_local A a2(mc + 2);
0165 static thread_local A a3(mc + 3);
0166
0167 static void checkTLSValues()
0168 {
0169 rtems_test_assert(extern_int == 7);
0170 rtems_test_assert(i123 == 123);
0171 rtems_test_assert(a256 == 256);
0172 uintptr_t addr = reinterpret_cast<uintptr_t>(&a256);
0173 RTEMS_OBFUSCATE_VARIABLE(addr);
0174 rtems_test_assert((addr % 256) == 0);
0175 rtems_test_assert(i0 == 0);
0176 rtems_test_assert(a == 0);
0177 addr = reinterpret_cast<uintptr_t>(&a);
0178 RTEMS_OBFUSCATE_VARIABLE(addr);
0179 rtems_test_assert((addr % 512) == 0);
0180 rtems_test_assert(f456(false) == 456);
0181 rtems_test_assert(f0(false) == 0);
0182 rtems_test_assert(C::c789() == 789);
0183 rtems_test_assert(C::c0() == 0);
0184 rtems_test_assert(a1.i() == 1);
0185 rtems_test_assert(a2.i() == 2);
0186 rtems_test_assert(a3.i() == 3);
0187 }
0188
0189 static rtems_id masterTask;
0190
0191 static void wakeUpMaster()
0192 {
0193 rtems_status_code sc = rtems_event_transient_send(masterTask);
0194 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0195 }
0196
0197 static void waitForWorker()
0198 {
0199 rtems_status_code sc = rtems_event_transient_receive(
0200 RTEMS_WAIT,
0201 RTEMS_NO_TIMEOUT
0202 );
0203 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0204 }
0205
0206 static void worker(rtems_task_argument arg)
0207 {
0208 wakeUpMaster();
0209 checkTLSValues();
0210
0211 const long gc = static_cast<long>(arg);
0212
0213 rtems_test_assert(A::globalCounter() == gc + 3);
0214
0215 rtems_test_assert(a1.counter() == gc + 0);
0216 rtems_test_assert(a2.counter() == gc + 1);
0217 rtems_test_assert(a3.counter() == gc + 2);
0218
0219 clobber();
0220 f456(true);
0221 f0(true);
0222 C::clobber();
0223 a1.clobber();
0224 a2.clobber();
0225 a3.clobber();
0226
0227 wakeUpMaster();
0228
0229 (void) rtems_task_suspend(RTEMS_SELF);
0230 rtems_test_assert(false);
0231 }
0232
0233 static void testWorkerTask()
0234 {
0235 checkTLSValues();
0236
0237 rtems_id id;
0238 rtems_status_code sc = rtems_task_create(
0239 rtems_build_name('T', 'A', 'S', 'K'),
0240 2,
0241 RTEMS_MINIMUM_STACK_SIZE,
0242 RTEMS_DEFAULT_MODES,
0243 RTEMS_DEFAULT_ATTRIBUTES,
0244 &id
0245 );
0246 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0247
0248 const long gc = A::globalCounter();
0249
0250 sc = rtems_task_start(id, worker, gc);
0251 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0252
0253 waitForWorker();
0254 rtems_test_assert(A::globalCounter() == gc);
0255
0256 waitForWorker();
0257 rtems_test_assert(A::globalCounter() == gc + 3);
0258
0259 sc = rtems_task_restart(id, gc);
0260 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0261
0262 waitForWorker();
0263 rtems_test_assert(A::globalCounter() == gc);
0264
0265 waitForWorker();
0266 rtems_test_assert(A::globalCounter() == gc + 3);
0267
0268 sc = rtems_task_delete(id);
0269 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0270
0271 rtems_test_assert(A::globalCounter() == gc);
0272
0273 checkTLSValues();
0274 }
0275
0276 extern "C" void Init(rtems_task_argument arg)
0277 {
0278 TEST_BEGIN();
0279
0280 printf("A::globalCounter() = %li\n", A::globalCounter());
0281
0282 checkTLSValues();
0283
0284 printf("A::globalCounter() = %li\n", A::globalCounter());
0285
0286 masterTask = rtems_task_self();
0287
0288 testWorkerTask();
0289
0290 rtems_resource_snapshot snapshot;
0291 rtems_resource_snapshot_take(&snapshot);
0292
0293 testWorkerTask();
0294
0295 rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
0296 rtems_test_assert(!rtems_stack_checker_is_blown());
0297
0298 TEST_END();
0299
0300 exit(0);
0301 }
0302
0303 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0304 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0305
0306 #define CONFIGURE_STACK_CHECKER_ENABLED
0307
0308 #define CONFIGURE_MAXIMUM_TASKS 2
0309 #define CONFIGURE_MAXIMUM_SEMAPHORES 3
0310
0311 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0312
0313 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0314
0315 #define CONFIGURE_MAXIMUM_POSIX_KEYS 2
0316 #define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 2
0317
0318 #define CONFIGURE_INIT
0319
0320 #include <rtems/confdefs.h>