RTEMS
threadhandler.c
Go to the documentation of this file.
1 
8 /*
9  * COPYRIGHT (c) 1989-2012.
10  * On-Line Applications Research Corporation (OAR).
11  *
12  * The license and distribution terms for this file may be
13  * found in the file LICENSE in this distribution or at
14  * http://www.rtems.org/license/LICENSE.
15  */
16 
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20 
21 #include <rtems/score/threadimpl.h>
22 #include <rtems/score/assert.h>
23 #include <rtems/score/interr.h>
24 #include <rtems/score/isrlevel.h>
26 
27 /*
28  * Conditional magic to determine what style of C++ constructor
29  * initialization this target and compiler version uses.
30  */
32  CPU_USE_LIBC_INIT_FINI_ARRAY == TRUE
33  || CPU_USE_LIBC_INIT_FINI_ARRAY == FALSE,
34  CPU_USE_LIBC_INIT_FINI_ARRAY
35 );
36 #if defined(__USE_INIT_FINI__)
37  #if CPU_USE_LIBC_INIT_FINI_ARRAY == TRUE
38  #define INIT_NAME __libc_init_array
39  #else
40  #define INIT_NAME _init
41  #endif
42 
43  extern void INIT_NAME(void);
44  #define EXECUTE_GLOBAL_CONSTRUCTORS
45 #endif
46 
47 #if defined(__USE__MAIN__)
48  extern void __main(void);
49  #define INIT_NAME __main
50  #define EXECUTE_GLOBAL_CONSTRUCTORS
51 #endif
52 
54 
55 static void _Thread_Global_construction( Thread_Control *executing )
56 {
57 #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
58  if ( executing->Object.id == _Thread_Global_constructor ) {
59  /*
60  * Prevent double construction in case the initialization thread is deleted
61  * and then recycled. There is not need for extra synchronization since
62  * this variable is set during the sequential system boot procedure.
63  */
65 
66  /*
67  * _init could be a weak symbol and we SHOULD test it but it isn't
68  * in any configuration I know of and it generates a warning on every
69  * RTEMS target configuration. --joel (12 May 2007)
70  */
71  INIT_NAME();
72  }
73 #endif
74 }
75 
76 void _Thread_Handler( void )
77 {
78  Thread_Control *executing;
79  ISR_Level level;
80  Per_CPU_Control *cpu_self;
81 
82  /*
83  * Some CPUs need to tinker with the call frame or registers when the
84  * thread actually begins to execute for the first time. This is a
85  * hook point where the port gets a shot at doing whatever it requires.
86  */
88  executing = _Thread_Executing;
89 
90  /*
91  * have to put level into a register for those cpu's that use
92  * inline asm here
93  */
94  level = executing->Start.isr_level;
95  _ISR_Set_level( level );
96 
97  /*
98  * Initialize the floating point context because we do not come
99  * through _Thread_Dispatch on our first invocation. So the normal
100  * code path for performing the FP context switch is not hit.
101  */
102  _Thread_Restore_fp( executing );
103 
104 #if defined(RTEMS_SMP)
105  _User_extensions_Thread_switch( NULL, executing );
106 #endif
107 
108  /*
109  * Do not use the level of the thread control block, since it has a
110  * different format.
111  */
112  _ISR_Local_disable( level );
113 
114  /*
115  * At this point, the dispatch disable level BETTER be 1.
116  */
117  cpu_self = _Per_CPU_Get();
118  _Assert( cpu_self->thread_dispatch_disable_level == 1 );
119 
120  /*
121  * Make sure we lose no thread dispatch necessary update and execute the
122  * post-switch actions. As a side-effect change the thread dispatch level
123  * from one to zero. Do not use _Thread_Enable_dispatch() since there is no
124  * valid thread dispatch necessary indicator in this context.
125  */
126  _Thread_Do_dispatch( cpu_self, level );
127 
128  /*
129  * Invoke the thread begin extensions in the context of the thread entry
130  * function with thread dispatching enabled. This enables use of dynamic
131  * memory allocation, creation of POSIX keys and use of C++ thread local
132  * storage. Blocking synchronization primitives are allowed also.
133  */
134  _User_extensions_Thread_begin( executing );
135 
136  _Thread_Global_construction( executing );
137 
138  /*
139  * RTEMS supports multiple APIs and each API can define a different
140  * thread/task prototype. The following code supports invoking the
141  * user thread entry point using the prototype expected.
142  */
143  ( *executing->Start.Entry.adaptor )( executing );
144 
145  /*
146  * In the call above, the return code from the user thread body which return
147  * something was placed in return_argument. This assumed that if it
148  * returned anything (which is not supporting in all APIs), then it would be
149  * able to fit in a (void *).
150  */
151 
152  _User_extensions_Thread_exitted( executing );
153 
154  _Internal_error( INTERNAL_ERROR_THREAD_EXITTED );
155 }
Constants and Prototypes Related to the Internal Error Handler.
#define _ISR_Local_disable(_level)
Disables interrupts on this processor.
Definition: isrlevel.h:57
Thread_Start_information Start
Definition: thread.h:825
ISR Level Type.
Thread_Entry_information Entry
Definition: thread.h:180
void _Thread_Do_dispatch(Per_CPU_Control *cpu_self, ISR_Level level)
Performs a thread dispatch on the current processor.
User Extension Handler API.
static __inline__ void _Thread_Restore_fp(Thread_Control *executing)
Restores the executing thread&#39;s floating point area.
Definition: threadimpl.h:1029
static void _User_extensions_Thread_switch(Thread_Control *executing, Thread_Control *heir)
Switches the thread from the executing to the heir.
Definition: userextimpl.h:366
Information for the Assert Handler.
#define _ISR_Set_level(_new_level)
Set current interrupt level.
Definition: isrlevel.h:140
Per CPU Core Structure.
Definition: percpu.h:347
Objects_Id _Thread_Global_constructor
Object identifier of the global constructor thread.
Definition: threadhandler.c:53
uint32_t ISR_Level
Definition: isrlevel.h:41
Objects_Control Object
Definition: thread.h:727
#define RTEMS_STATIC_ASSERT(_cond, _msg)
Asserts at compile time that the specified condition is satisfied.
Definition: basedefs.h:838
static void _User_extensions_Thread_begin(Thread_Control *executing)
Begins a thread.
Definition: userextimpl.h:351
#define TRUE
If TRUE is undefined, then TRUE is defined to 1.
Definition: basedefs.h:851
void _Thread_Handler(void)
Wrapper function for all threads.
Definition: threadhandler.c:76
volatile uint32_t thread_dispatch_disable_level
The thread dispatch critical section nesting counter which is used to prevent context switches at ino...
Definition: percpu.h:385
void _Internal_error(Internal_errors_Core_list core_error) RTEMS_NO_RETURN
Terminates the system with an INTERNAL_ERROR_CORE fatal source and the specified core error code...
Definition: interr.c:51
Inlined Routines from the Thread Handler.
uint32_t Objects_Id
Definition: object.h:80
#define FALSE
If FALSE is undefined, then FALSE is defined to 0.
Definition: basedefs.h:645
void(* adaptor)(Thread_Control *executing)
Thread entry adaptor.
Definition: thread.h:138
static void _User_extensions_Thread_exitted(Thread_Control *executing)
A user extension thread exitted.
Definition: userextimpl.h:423
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG.
Definition: assert.h:100
#define _Context_Initialization_at_thread_begin()
Definition: context.h:94
Objects_Id id
Definition: objectdata.h:43