![]() |
|
|||
File indexing completed on 2025-05-11 08:24:27
0001 /* SPDX-License-Identifier: BSD-2-Clause */ 0002 0003 /** 0004 * @file 0005 * 0006 * @ingroup RTEMSScoreThread 0007 * 0008 * @brief This source file contains the definition of 0009 * ::_Thread_Global_constructor and the implementation of _Thread_Handler(). 0010 */ 0011 0012 /* 0013 * COPYRIGHT (c) 1989-2012. 0014 * On-Line Applications Research Corporation (OAR). 0015 * 0016 * Redistribution and use in source and binary forms, with or without 0017 * modification, are permitted provided that the following conditions 0018 * are met: 0019 * 1. Redistributions of source code must retain the above copyright 0020 * notice, this list of conditions and the following disclaimer. 0021 * 2. Redistributions in binary form must reproduce the above copyright 0022 * notice, this list of conditions and the following disclaimer in the 0023 * documentation and/or other materials provided with the distribution. 0024 * 0025 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 0026 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0027 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 0028 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 0029 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 0030 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 0031 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 0032 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 0033 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 0034 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 0035 * POSSIBILITY OF SUCH DAMAGE. 0036 */ 0037 0038 #ifdef HAVE_CONFIG_H 0039 #include "config.h" 0040 #endif 0041 0042 #include <rtems/score/threadimpl.h> 0043 #include <rtems/score/assert.h> 0044 #include <rtems/score/interr.h> 0045 #include <rtems/score/isrlevel.h> 0046 #include <rtems/score/userextimpl.h> 0047 0048 /* 0049 * Conditional magic to determine what style of C++ constructor 0050 * initialization this target and compiler version uses. 0051 */ 0052 RTEMS_STATIC_ASSERT( 0053 CPU_USE_LIBC_INIT_FINI_ARRAY == TRUE 0054 || CPU_USE_LIBC_INIT_FINI_ARRAY == FALSE, 0055 CPU_USE_LIBC_INIT_FINI_ARRAY 0056 ); 0057 #if defined(__USE_INIT_FINI__) 0058 #if CPU_USE_LIBC_INIT_FINI_ARRAY == TRUE 0059 #define INIT_NAME __libc_init_array 0060 #else 0061 #define INIT_NAME _init 0062 #endif 0063 0064 extern void INIT_NAME(void); 0065 #define EXECUTE_GLOBAL_CONSTRUCTORS 0066 #endif 0067 0068 #if defined(__USE__MAIN__) 0069 extern void __main(void); 0070 #define INIT_NAME __main 0071 #define EXECUTE_GLOBAL_CONSTRUCTORS 0072 #endif 0073 0074 Objects_Id _Thread_Global_constructor; 0075 0076 static void _Thread_Global_construction( Thread_Control *executing ) 0077 { 0078 #if defined(EXECUTE_GLOBAL_CONSTRUCTORS) 0079 if ( executing->Object.id == _Thread_Global_constructor ) { 0080 /* 0081 * Prevent double construction in case the initialization thread is deleted 0082 * and then recycled. There is not need for extra synchronization since 0083 * this variable is set during the sequential system boot procedure. 0084 */ 0085 _Thread_Global_constructor = 0; 0086 0087 /* 0088 * _init could be a weak symbol and we SHOULD test it but it isn't 0089 * in any configuration I know of and it generates a warning on every 0090 * RTEMS target configuration. --joel (12 May 2007) 0091 */ 0092 INIT_NAME(); 0093 } 0094 #endif 0095 } 0096 0097 void _Thread_Handler( void ) 0098 { 0099 Thread_Control *executing; 0100 ISR_Level level; 0101 Per_CPU_Control *cpu_self; 0102 0103 /* 0104 * Some CPUs need to tinker with the call frame or registers when the 0105 * thread actually begins to execute for the first time. This is a 0106 * hook point where the port gets a shot at doing whatever it requires. 0107 */ 0108 _Context_Initialization_at_thread_begin(); 0109 executing = _Thread_Executing; 0110 0111 /* 0112 * have to put level into a register for those cpu's that use 0113 * inline asm here 0114 */ 0115 level = executing->Start.isr_level; 0116 _ISR_Set_level( level ); 0117 0118 /* 0119 * Initialize the floating point context because we do not come 0120 * through _Thread_Dispatch on our first invocation. So the normal 0121 * code path for performing the FP context switch is not hit. 0122 */ 0123 _Thread_Restore_fp( executing ); 0124 0125 #if defined(RTEMS_SMP) 0126 _User_extensions_Thread_switch( NULL, executing ); 0127 #endif 0128 0129 /* 0130 * Do not use the level of the thread control block, since it has a 0131 * different format. 0132 */ 0133 _ISR_Local_disable( level ); 0134 0135 /* 0136 * At this point, the dispatch disable level BETTER be 1. 0137 */ 0138 cpu_self = _Per_CPU_Get(); 0139 _Assert( cpu_self->thread_dispatch_disable_level == 1 ); 0140 0141 /* 0142 * Make sure we lose no thread dispatch necessary update and execute the 0143 * post-switch actions. As a side-effect change the thread dispatch level 0144 * from one to zero. Do not use _Thread_Enable_dispatch() since there is no 0145 * valid thread dispatch necessary indicator in this context. 0146 */ 0147 _Thread_Do_dispatch( cpu_self, level ); 0148 0149 /* 0150 * Invoke the thread begin extensions in the context of the thread entry 0151 * function with thread dispatching enabled. This enables use of dynamic 0152 * memory allocation, creation of POSIX keys and use of C++ thread local 0153 * storage. Blocking synchronization primitives are allowed also. 0154 */ 0155 _User_extensions_Thread_begin( executing ); 0156 0157 _Thread_Global_construction( executing ); 0158 0159 /* 0160 * RTEMS supports multiple APIs and each API can define a different 0161 * thread/task prototype. The following code supports invoking the 0162 * user thread entry point using the prototype expected. 0163 */ 0164 ( *executing->Start.Entry.adaptor )( executing ); 0165 0166 /* 0167 * In the call above, the return code from the user thread body which return 0168 * something was placed in return_argument. This assumed that if it 0169 * returned anything (which is not supporting in all APIs), then it would be 0170 * able to fit in a (void *). 0171 */ 0172 0173 _User_extensions_Thread_exitted( executing ); 0174 0175 _Internal_error( INTERNAL_ERROR_THREAD_EXITTED ); 0176 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |