source: rtems/testsuites/sptests/sptls02/init.cc @ 45ee958

Last change on this file since 45ee958 was 45ee958, checked in by Sebastian Huber <sebastian.huber@…>, on 09/30/22 at 06:06:18

config: Add CONFIGURE_IDLE_TASK_STORAGE_SIZE

By default, allocate the IDLE task storage areas from the RTEMS Workspace.
This avoids having to estimate the thread-local storage size in the default
configuration.

Add the application configuration option CONFIGURE_IDLE_TASK_STORAGE_SIZE to
request a static allocation of the task storage area for IDLE tasks.

Update #3835.
Update #4524.

  • Property mode set to 100644
File size: 6.3 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/*
4 * Copyright (C) 2014, 2020 embedded brains GmbH (http://www.embedded-brains.de)
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "sptls02.h"
33
34#include <stdio.h>
35#include <stdlib.h>
36
37#include <rtems.h>
38#include <rtems/libcsupport.h>
39#include <rtems/stackchk.h>
40
41#include <tmacros.h>
42
43const char rtems_test_name[] = "SPTLS 2";
44
45static thread_local long i123 = 123;
46
47alignas(256) static thread_local long a256 = 256;
48
49static thread_local long i0;
50
51alignas(RTEMS_MINIMUM_STACK_SIZE) static thread_local long a;
52
53int seven()
54{
55        return 7;
56}
57
58static void clobber()
59{
60        extern_int = 0xdead0007;
61        i123 = 0xdead0001;
62        a256 = 0xdead0002;
63        i0 = 0xdead0003;
64        a = 0xdead0004;
65}
66
67static long f456(bool clobber)
68{
69        static thread_local long fi456 = 456;
70
71        if (clobber) {
72                fi456 = 0xdead0003;
73        }
74
75        return fi456;
76}
77
78static long f0(bool clobber)
79{
80        static thread_local long fi0;
81
82        if (clobber) {
83                fi0 = 0xdead0004;
84        }
85
86        return fi0;
87}
88
89class C {
90        public:
91                static long c789()
92                {
93                        return ci789;
94                }
95
96                static long c0()
97                {
98                        return ci0;
99                }
100
101                static void clobber()
102                {
103                        ci789 = 0xdead0005;
104                        ci0 = 0xdead0006;
105                }
106
107        private:
108                static thread_local long ci789;
109
110                static thread_local long ci0;
111};
112
113thread_local long C::ci789 = 789;
114
115thread_local long C::ci0;
116
117class A {
118        public:
119                A(long i)
120                        : ii(i), c(gc)
121                {
122                        ++gc;
123                }
124
125                ~A()
126                {
127                        --gc;
128                }
129
130                long i() const
131                {
132                        return ii;
133                }
134
135                void clobber()
136                {
137                        ii = ~ii;
138                        c = ~c;
139                }
140
141                long counter() const
142                {
143                        return c;
144                }
145
146                static long globalCounter()
147                {
148                        return gc;
149                }
150
151        private:
152                static long gc;
153
154                long ii;
155
156                long c;
157};
158
159long A::gc;
160
161static volatile long mc;
162
163static thread_local A a1(mc + 1);
164static thread_local A a2(mc + 2);
165static thread_local A a3(mc + 3);
166
167static void checkTLSValues()
168{
169        rtems_test_assert(extern_int == 7);
170        rtems_test_assert(i123 == 123);
171        rtems_test_assert(a256 == 256);
172        uintptr_t addr = reinterpret_cast<uintptr_t>(&a256);
173        RTEMS_OBFUSCATE_VARIABLE(addr);
174        rtems_test_assert((addr % 256) == 0);
175        rtems_test_assert(i0 == 0);
176        rtems_test_assert(a == 0);
177        addr = reinterpret_cast<uintptr_t>(&a);
178        RTEMS_OBFUSCATE_VARIABLE(addr);
179        rtems_test_assert((addr % 512) == 0);
180        rtems_test_assert(f456(false) == 456);
181        rtems_test_assert(f0(false) == 0);
182        rtems_test_assert(C::c789() == 789);
183        rtems_test_assert(C::c0() == 0);
184        rtems_test_assert(a1.i() == 1);
185        rtems_test_assert(a2.i() == 2);
186        rtems_test_assert(a3.i() == 3);
187}
188
189static rtems_id masterTask;
190
191static void wakeUpMaster()
192{
193        rtems_status_code sc = rtems_event_transient_send(masterTask);
194        rtems_test_assert(sc == RTEMS_SUCCESSFUL);
195}
196
197static void waitForWorker()
198{
199        rtems_status_code sc = rtems_event_transient_receive(
200                RTEMS_WAIT,
201                RTEMS_NO_TIMEOUT
202        );
203        rtems_test_assert(sc == RTEMS_SUCCESSFUL);
204}
205
206static void worker(rtems_task_argument arg)
207{
208        wakeUpMaster();
209        checkTLSValues();
210
211        const long gc = static_cast<long>(arg);
212
213        rtems_test_assert(A::globalCounter() == gc + 3);
214
215        rtems_test_assert(a1.counter() == gc + 0);
216        rtems_test_assert(a2.counter() == gc + 1);
217        rtems_test_assert(a3.counter() == gc + 2);
218
219        clobber();
220        f456(true);
221        f0(true);
222        C::clobber();
223        a1.clobber();
224        a2.clobber();
225        a3.clobber();
226
227        wakeUpMaster();
228
229        (void) rtems_task_suspend(RTEMS_SELF);
230        rtems_test_assert(false);
231}
232
233static void testWorkerTask()
234{
235        checkTLSValues();
236
237        rtems_id id;
238        rtems_status_code sc = rtems_task_create(
239                rtems_build_name('T', 'A', 'S', 'K'),
240                2,
241                RTEMS_MINIMUM_STACK_SIZE,
242                RTEMS_DEFAULT_MODES,
243                RTEMS_DEFAULT_ATTRIBUTES,
244                &id
245        );
246        rtems_test_assert(sc == RTEMS_SUCCESSFUL);
247
248        const long gc = A::globalCounter();
249
250        sc = rtems_task_start(id, worker, gc);
251        rtems_test_assert(sc == RTEMS_SUCCESSFUL);
252
253        waitForWorker();
254        rtems_test_assert(A::globalCounter() == gc);
255
256        waitForWorker();
257        rtems_test_assert(A::globalCounter() == gc + 3);
258
259        sc = rtems_task_restart(id, gc);
260        rtems_test_assert(sc == RTEMS_SUCCESSFUL);
261
262        waitForWorker();
263        rtems_test_assert(A::globalCounter() == gc);
264
265        waitForWorker();
266        rtems_test_assert(A::globalCounter() == gc + 3);
267
268        sc = rtems_task_delete(id);
269        rtems_test_assert(sc == RTEMS_SUCCESSFUL);
270
271        rtems_test_assert(A::globalCounter() == gc);
272
273        checkTLSValues();
274}
275
276extern "C" void Init(rtems_task_argument arg)
277{
278        TEST_BEGIN();
279
280        printf("A::globalCounter() = %li\n", A::globalCounter());
281
282        checkTLSValues();
283
284        printf("A::globalCounter() = %li\n", A::globalCounter());
285
286        masterTask = rtems_task_self();
287
288        testWorkerTask();
289
290        rtems_resource_snapshot snapshot;
291        rtems_resource_snapshot_take(&snapshot);
292
293        testWorkerTask();
294
295        rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
296        rtems_test_assert(!rtems_stack_checker_is_blown());
297
298        TEST_END();
299
300        exit(0);
301}
302
303#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
304#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
305
306#define CONFIGURE_STACK_CHECKER_ENABLED
307
308#define CONFIGURE_MAXIMUM_TASKS 2
309#define CONFIGURE_MAXIMUM_SEMAPHORES 3
310
311#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
312
313#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
314
315#define CONFIGURE_MAXIMUM_POSIX_KEYS 2
316#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 2
317
318#define CONFIGURE_INIT
319
320#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.