Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:49

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (C) 2014, 2022 embedded brains GmbH & Co. KG
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031 
0032 #include <rtems/bspIo.h>
0033 #include <rtems/stackchk.h>
0034 #include <rtems/sysinit.h>
0035 #include <rtems/score/cpuimpl.h>
0036 #include <rtems/score/threadimpl.h>
0037 #include <rtems/score/tls.h>
0038 
0039 #include "tmacros.h"
0040 
0041 const char rtems_test_name[] = "SPTLS 1";
0042 
0043 static rtems_id master_task;
0044 
0045 static __thread volatile char tls_item = 123;
0046 
0047 static volatile uint32_t read_write_small = 0xdeadbeefUL;
0048 
0049 static const volatile uint32_t read_only_small = 0x601dc0feUL;
0050 
0051 static void check_tls_item(uint32_t expected)
0052 {
0053   printk("TLS item = %i\n", tls_item);
0054   rtems_test_assert(tls_item == expected);
0055 }
0056 
0057 static void task(rtems_task_argument arg)
0058 {
0059   rtems_status_code sc;
0060 
0061   check_tls_item(123);
0062   tls_item = 42;
0063 
0064   sc = rtems_event_transient_send(master_task);
0065   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0066 
0067   sc = rtems_task_suspend(RTEMS_SELF);
0068   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0069 }
0070 
0071 static void check_tls_size(void)
0072 {
0073   const volatile TLS_Configuration *config;
0074   uintptr_t tls_size;
0075 
0076   config = &_TLS_Configuration;
0077   tls_size = (uintptr_t) config->size;
0078 
0079   if (tls_size != 1) {
0080     printk(
0081       "WARNING: The thread-local storage size is %" PRIuPTR ".  It should be\n"
0082       "exactly one for this test.  Check the BSP implementation.  The BSP\n"
0083       "should not pull in thread-local storage objects such as errno for\n"
0084       "this test.\n",
0085       tls_size
0086     );
0087     rtems_test_assert(tls_size == 1);
0088   }
0089 }
0090 
0091 static Thread_Control *get_thread(rtems_id id)
0092 {
0093   Thread_Control *the_thread;
0094   ISR_lock_Context lock_context;
0095 
0096   the_thread = _Thread_Get(id, &lock_context);
0097   _ISR_lock_ISR_enable(&lock_context);
0098   return the_thread;
0099 }
0100 
0101 static void test(void)
0102 {
0103   rtems_id id;
0104   rtems_status_code sc;
0105   Thread_Control *self;
0106   Thread_Control *other;
0107   char *self_tp;
0108   char *other_tp;
0109   uintptr_t tls_item_offset;
0110   char *self_tls_item;
0111   char *other_tls_item;
0112 
0113   master_task = rtems_task_self();
0114 
0115   rtems_test_assert(read_write_small == 0xdeadbeefUL);
0116   rtems_test_assert(read_only_small == 0x601dc0feUL);
0117 
0118   check_tls_item(123);
0119   tls_item = 5;
0120 
0121   sc = rtems_task_create(
0122     rtems_build_name('T', 'A', 'S', 'K'),
0123     RTEMS_MINIMUM_PRIORITY,
0124     RTEMS_MINIMUM_STACK_SIZE,
0125     RTEMS_DEFAULT_MODES,
0126     RTEMS_DEFAULT_ATTRIBUTES,
0127     &id
0128   );
0129   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0130 
0131   sc = rtems_task_start(id, task, 0);
0132   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0133 
0134   self = get_thread(master_task);
0135   other = get_thread(id);
0136   self_tp = _CPU_Get_TLS_thread_pointer(&self->Registers);
0137   other_tp = _CPU_Get_TLS_thread_pointer(&other->Registers);
0138   tls_item_offset = (uintptr_t) (&tls_item - self_tp);
0139   self_tls_item = self_tp + tls_item_offset;
0140   other_tls_item = other_tp + tls_item_offset;
0141   rtems_test_assert(*self_tls_item == 5);
0142   rtems_test_assert(*other_tls_item == 123);
0143 
0144   sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0145   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0146 
0147   rtems_test_assert(*self_tls_item == 5);
0148   rtems_test_assert(*other_tls_item == 42);
0149 
0150   sc = rtems_task_delete(id);
0151   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0152 
0153   check_tls_item(5);
0154 }
0155 
0156 static void test_idle_during_system_init(void)
0157 {
0158   rtems_print_printer_printk(&rtems_test_printer);
0159   TEST_BEGIN();
0160 
0161   check_tls_item(123);
0162 }
0163 
0164 static void Init(rtems_task_argument arg)
0165 {
0166   test();
0167 
0168   rtems_test_assert(!rtems_stack_checker_is_blown());
0169   check_tls_size();
0170   TEST_END();
0171 
0172   rtems_test_exit(0);
0173 }
0174 
0175 RTEMS_SYSINIT_ITEM(
0176   test_idle_during_system_init,
0177   RTEMS_SYSINIT_IDLE_THREADS,
0178   RTEMS_SYSINIT_ORDER_LAST
0179 );
0180 
0181 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0182 
0183 /*
0184  * Avoid a dependency on errno which might be a thread-local object.  This test
0185  * assumes that no thread-local storage object other than tls_item is present.
0186  */
0187 #define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
0188 
0189 /*
0190  * This test requires full control over the present thread-local objects.  In
0191  * certain Newlib configurations, the Newlib reentrancy support may add
0192  * thread-local objects.
0193  */
0194 #define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
0195 
0196 #define CONFIGURE_STACK_CHECKER_ENABLED
0197 
0198 #define CONFIGURE_MAXIMUM_TASKS 2
0199 
0200 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0201 
0202 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0203 
0204 #define CONFIGURE_INIT
0205 
0206 #include <rtems/confdefs.h>