RTEMS
threadinitialize.c
Go to the documentation of this file.
1 
8 /*
9  * COPYRIGHT (c) 1989-2014.
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>
24 #include <rtems/score/stackimpl.h>
25 #include <rtems/score/tls.h>
28 #include <rtems/config.h>
29 
31  Thread_Information *information,
32  Thread_Control *the_thread,
33  const Thread_Configuration *config
34 )
35 {
36  uintptr_t tls_size;
37  bool extension_status;
38  size_t i;
39  char *stack_begin;
40  char *stack_end;
41  Scheduler_Node *scheduler_node;
42 #if defined(RTEMS_SMP)
43  Scheduler_Node *scheduler_node_for_index;
44  const Scheduler_Control *scheduler_for_index;
45 #endif
46  size_t scheduler_index;
47  Per_CPU_Control *cpu = _Per_CPU_Get_by_index( 0 );
48 
49  memset(
50  &the_thread->Join_queue,
51  0,
52  information->Objects.object_size - offsetof( Thread_Control, Join_queue )
53  );
54 
55  for ( i = 0 ; i < _Thread_Control_add_on_count ; ++i ) {
56  const Thread_Control_add_on *add_on = &_Thread_Control_add_ons[ i ];
57 
58  *(void **) ( (char *) the_thread + add_on->destination_offset ) =
59  (char *) the_thread + add_on->source_offset;
60  }
61 
62  /* Set everything to perform the error case clean up */
63  the_thread->Start.stack_free = config->stack_free;
64 
65 #if defined(RTEMS_SMP)
66  if (
67  !config->is_preemptible
69  ) {
70  goto failed;
71  }
72 #endif
73 
74 #if defined(RTEMS_SMP) || CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
75  if (
76  config->isr_level != 0
77 #if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE
79 #endif
80  ) {
81  goto failed;
82  }
83 #endif
84 
85  stack_begin = config->stack_area;
86  stack_end = stack_begin + config->stack_size;
87 
88  /* Allocate floating-point context in stack area */
89 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
90  if ( config->is_fp ) {
91  stack_end -= CONTEXT_FP_SIZE;
92  the_thread->fp_context = (Context_Control_fp *) stack_end;
93  the_thread->Start.fp_context = (Context_Control_fp *) stack_end;
94  }
95 #endif
96 
97  tls_size = _TLS_Get_allocation_size();
98 
99  /* Allocate thread-local storage (TLS) area in stack area */
100  if ( tls_size > 0 ) {
101  uintptr_t tls_align;
102 
103  stack_end -= tls_size;
104  tls_align = (uintptr_t) _TLS_Alignment;
105  the_thread->Start.tls_area = (void *)
106  ( ( (uintptr_t) stack_end + tls_align - 1 ) & ~( tls_align - 1 ) );
107  }
108 
110  &the_thread->Start.Initial_stack,
111  stack_begin,
112  stack_end - stack_begin
113  );
114 
115  /*
116  * Get thread queue heads
117  */
118  the_thread->Wait.spare_heads = _Freechain_Pop(
119  &information->Thread_queue_heads.Free
120  );
121  _Thread_queue_Heads_initialize( the_thread->Wait.spare_heads );
122 
123  /*
124  * General initialization
125  */
126 
127  the_thread->is_fp = config->is_fp;
128  the_thread->Start.isr_level = config->isr_level;
129  the_thread->Start.is_preemptible = config->is_preemptible;
130  the_thread->Start.budget_algorithm = config->budget_algorithm;
131  the_thread->Start.budget_callout = config->budget_callout;
132 
133  _Thread_Timer_initialize( &the_thread->Timer, cpu );
134 
135  switch ( config->budget_algorithm ) {
136  case THREAD_CPU_BUDGET_ALGORITHM_NONE:
137  case THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE:
138  break;
139  #if defined(RTEMS_SCORE_THREAD_ENABLE_EXHAUST_TIMESLICE)
140  case THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE:
141  the_thread->cpu_time_budget =
143  break;
144  #endif
145  #if defined(RTEMS_SCORE_THREAD_ENABLE_SCHEDULER_CALLOUT)
146  case THREAD_CPU_BUDGET_ALGORITHM_CALLOUT:
147  break;
148  #endif
149  }
150 
151 #if defined(RTEMS_SMP)
152  scheduler_node = NULL;
153  scheduler_node_for_index = the_thread->Scheduler.nodes;
154  scheduler_for_index = &_Scheduler_Table[ 0 ];
155  scheduler_index = 0;
156 
157  while ( scheduler_index < _Scheduler_Count ) {
158  Priority_Control priority_for_index;
159 
160  if ( scheduler_for_index == config->scheduler ) {
161  priority_for_index = config->priority;
162  scheduler_node = scheduler_node_for_index;
163  } else {
164  /*
165  * Use the idle thread priority for the non-home scheduler instances by
166  * default.
167  */
168  priority_for_index = _Scheduler_Map_priority(
169  scheduler_for_index,
170  scheduler_for_index->maximum_priority
171  );
172  }
173 
175  scheduler_for_index,
176  scheduler_node_for_index,
177  the_thread,
178  priority_for_index
179  );
180  scheduler_node_for_index = (Scheduler_Node *)
181  ( (uintptr_t) scheduler_node_for_index + _Scheduler_Node_size );
182  ++scheduler_for_index;
183  ++scheduler_index;
184  }
185 
186  _Assert( scheduler_node != NULL );
188  &the_thread->Scheduler.Wait_nodes,
189  &scheduler_node->Thread.Wait_node
190  );
192  &the_thread->Scheduler.Scheduler_nodes,
193  &scheduler_node->Thread.Scheduler_node.Chain
194  );
195 #else
196  scheduler_node = _Thread_Scheduler_get_home_node( the_thread );
198  config->scheduler,
199  scheduler_node,
200  the_thread,
201  config->priority
202  );
203  scheduler_index = 1;
204 #endif
205 
206  _Priority_Node_initialize( &the_thread->Real_priority, config->priority );
208  &scheduler_node->Wait.Priority,
209  &the_thread->Real_priority
210  );
211 
212 #if defined(RTEMS_SMP)
213  RTEMS_STATIC_ASSERT( THREAD_SCHEDULER_BLOCKED == 0, Scheduler_state );
214  the_thread->Scheduler.home_scheduler = config->scheduler;
215  _ISR_lock_Initialize( &the_thread->Scheduler.Lock, "Thread Scheduler" );
217  &the_thread->Scheduler.Affinity,
219  );
220  _ISR_lock_Initialize( &the_thread->Wait.Lock.Default, "Thread Wait Default" );
223  _SMP_lock_Stats_initialize( &the_thread->Potpourri_stats, "Thread Potpourri" );
224  _SMP_lock_Stats_initialize( &the_thread->Join_queue.Lock_stats, "Thread State" );
225 #endif
226 
227  /* Initialize the CPU for the non-SMP schedulers */
228  _Thread_Set_CPU( the_thread, cpu );
229 
230  the_thread->current_state = STATES_DORMANT;
231  the_thread->Wait.operations = &_Thread_queue_Operations_default;
232  the_thread->Start.initial_priority = config->priority;
233 
235 
236  /* POSIX Keys */
238  _ISR_lock_Initialize( &the_thread->Keys.Lock, "POSIX Key Value Pairs" );
239 
240  _Thread_Action_control_initialize( &the_thread->Post_switch_actions );
241 
242  /*
243  * Open the object
244  */
245  _Objects_Open( &information->Objects, &the_thread->Object, config->name );
246 
247  /*
248  * We assume the Allocator Mutex is locked and dispatching is
249  * enabled when we get here. We want to be able to run the
250  * user extensions with dispatching enabled. The Allocator
251  * Mutex provides sufficient protection to let the user extensions
252  * run safely.
253  */
254  extension_status = _User_extensions_Thread_create( the_thread );
255  if ( extension_status )
256  return true;
257 
258 #if defined(RTEMS_SMP)
259  while ( scheduler_index > 0 ) {
260  scheduler_node_for_index = (Scheduler_Node *)
261  ( (uintptr_t) scheduler_node_for_index - _Scheduler_Node_size );
262  --scheduler_for_index;
263  --scheduler_index;
264  _Scheduler_Node_destroy( scheduler_for_index, scheduler_node_for_index );
265  }
266 #else
267  if ( scheduler_index > 0 ) {
268  _Scheduler_Node_destroy( config->scheduler, scheduler_node );
269  }
270 #endif
271 
273  &information->Thread_queue_heads.Free,
274  the_thread->Wait.spare_heads
275  );
276 
277 #if defined(RTEMS_SMP) || CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
278 failed:
279 #endif
280 
281  ( *the_thread->Start.stack_free )( the_thread->Start.Initial_stack.area );
282  return false;
283 }
Thread-Local Storage (TLS)
Thread_queue_Gate Tranquilizer
Tranquilizer gate used by _Thread_Wait_tranquilize().
Definition: thread.h:464
const struct _Scheduler_Control * home_scheduler
The home scheduler of this thread.
Definition: thread.h:258
Thread_CPU_budget_algorithms budget_algorithm
The thread&#39;s budget algorithm.
Definition: threadimpl.h:161
static __inline__ void _Priority_Initialize_one(Priority_Aggregation *aggregation, Priority_Node *node)
Initializes the priority aggregation with the given information.
Definition: priorityimpl.h:232
static __inline__ void _Thread_Action_control_initialize(Thread_Action_control *action_control)
Initializes the control chain of the action control.
Definition: threadimpl.h:1208
const Thread_queue_Operations * operations
The current thread queue operations.
Definition: thread.h:491
uintptr_t _TLS_Get_allocation_size(void)
Return the TLS area allocation size.
Definition: tlsallocsize.c:38
#define rtems_configuration_get_ticks_per_timeslice()
Returns the clock ticks per timeslice configured for this application.
Definition: config.h:277
uint64_t Priority_Control
The thread priority control.
Definition: priority.h:70
static __inline__ void _Stack_Initialize(Stack_Control *the_stack, void *starting_address, size_t size)
Initializes stack with the given starting address and size.
Definition: stackimpl.h:49
#define CONTEXT_FP_SIZE
Size of floating point context area.
Definition: context.h:52
Thread_Wait_information Wait
Definition: thread.h:767
static __inline__ const bool _SMP_Need_inter_processor_interrupts(void)
Indicate if inter-processor interrupts are needed.
Definition: smpimpl.h:333
Inlined Routines in the Watchdog Handler.
static __inline__ Priority_Control _Scheduler_Map_priority(const Scheduler_Control *scheduler, Priority_Control priority)
Maps a thread priority from the user domain to the scheduler domain.
Freechain Handler API.
Thread_Start_information Start
Definition: thread.h:825
static __inline__ const Processor_mask * _SMP_Get_online_processors(void)
Gets all online processors.
Definition: smpimpl.h:318
Inlined Routines Associated with the Manipulation of the Scheduler.
This header file defines parts of the application configuration information API.
static __inline__ void _RBTree_Initialize_empty(RBTree_Control *the_rbtree)
Initializes this RBTree as empty.
Definition: rbtree.h:410
size_t destination_offset
Offset of the pointer field in Thread_Control referencing an application configuration dependent memo...
Definition: thread.h:899
struct Thread_Wait_information::@26 Lock
Thread wait lock control block.
union Thread_Information::@27 Thread_queue_heads
Thread queue heads maintenance.
Thread_Keys_information Keys
The POSIX Keys information.
Definition: thread.h:845
static __inline__ void _Scheduler_Node_initialize(const Scheduler_Control *scheduler, Scheduler_Node *node, Thread_Control *the_thread, Priority_Control priority)
Initializes a scheduler node.
Thread_Scheduler_control Scheduler
Scheduler related control.
Definition: thread.h:764
ISR_lock_Control Default
Thread wait default lock.
Definition: thread.h:447
User Extension Handler API.
Objects_Information Objects
The object information.
Definition: thread.h:1004
struct Scheduler_Node::@19 Thread
Block to register and manage this scheduler node in the thread control block of the owner of this sch...
static bool _User_extensions_Thread_create(Thread_Control *created)
Creates a thread.
Definition: userextimpl.h:291
static __inline__ void _Thread_Timer_initialize(Thread_Timer_information *timer, Per_CPU_Control *cpu)
Initializes the thread timer.
Definition: threadimpl.h:2388
bool _Thread_Initialize(Thread_Information *information, Thread_Control *the_thread, const Thread_Configuration *config)
Initializes thread.
Inlined Routines from the Stack Handler.
Objects_Name name
Name of the object for the thread.
Definition: threadimpl.h:171
static __inline__ void * _Freechain_Pop(Freechain_Control *freechain)
Pops a node from the freechain.
Definition: freechainimpl.h:84
const size_t _Thread_Control_add_on_count
Thread control add-on count.
const Thread_Control_add_on _Thread_Control_add_ons[]
Thread control add-ons.
Chain_Node Wait_node
Node to add this scheduler node to Thread_Control::Scheduler::Wait_nodes.
char _TLS_Alignment[]
The TLS section alignment.
Processor_mask Affinity
The thread processor affinity set.
Definition: thread.h:343
static __inline__ void _Thread_queue_Gate_open(Thread_queue_Gate *gate)
Opens the gate.
Definition: threadqimpl.h:494
size_t source_offset
Offset relative to the thread control block begin to an application configuration dependent memory ar...
Definition: thread.h:905
#define STATES_DORMANT
Definition: statesimpl.h:119
This thread is blocked with respect to the scheduler.
Definition: thread.h:220
static __inline__ void _Objects_Open(Objects_Information *information, Objects_Control *the_object, Objects_Name name)
Places the_object control pointer and object name in the Local Pointer and Local Name Tables...
Definition: objectimpl.h:750
Priority_Control priority
The new thread&#39;s priority.
Definition: threadimpl.h:156
const struct _Scheduler_Control * scheduler
The scheduler control instance for the thread.
Definition: threadimpl.h:134
Per CPU Core Structure.
Definition: percpu.h:347
static __inline__ Scheduler_Node * _Thread_Scheduler_get_home_node(const Thread_Control *the_thread)
Gets the scheduler&#39;s home node.
Definition: threadimpl.h:1438
Priority_Control maximum_priority
The maximum priority value of this scheduler.
Definition: scheduler.h:281
The configuration of a new thread to initialize.
Definition: threadimpl.h:130
Thread control add-on.
Definition: thread.h:893
The thread object information.
Definition: thread.h:1000
static __inline__ void _Thread_Set_CPU(Thread_Control *thread, Per_CPU_Control *cpu)
Sets the cpu of the thread&#39;s scheduler.
Definition: threadimpl.h:886
Objects_Control Object
Definition: thread.h:727
size_t stack_size
The size of the stack area in bytes.
Definition: threadimpl.h:144
Thread_CPU_budget_algorithm_callout budget_callout
The thread&#39;s initial budget callout.
Definition: threadimpl.h:166
States_Control current_state
Definition: thread.h:749
RBTree_Control Key_value_pairs
Key value pairs registered for this thread.
Definition: thread.h:645
#define RTEMS_STATIC_ASSERT(_cond, _msg)
Asserts at compile time that the specified condition is satisfied.
Definition: basedefs.h:838
const Scheduler_Control _Scheduler_Table[]
This table contains the configured schedulers.
static __inline__ void _Thread_queue_Heads_initialize(Thread_queue_Heads *heads)
Initializes the thread queue heads.
Definition: threadqimpl.h:523
SPARC basic context.
Definition: cpu.h:478
static __inline__ bool _Scheduler_Is_non_preempt_mode_supported(const Scheduler_Control *scheduler)
Indicate if the thread non-preempt mode is supported by the scheduler.
Priority_Control initial_priority
Definition: thread.h:195
Thread_CPU_budget_algorithm_callout budget_callout
Definition: thread.h:191
const size_t _Scheduler_Node_size
The size of a scheduler node.
Freechain_Control Free
The free thread queue heads.
Definition: thread.h:1022
Chain_Control Scheduler_nodes
Scheduler nodes immediately available to the schedulers for this thread.
Definition: thread.h:294
static __inline__ void _Chain_Initialize_one(Chain_Control *the_chain, Chain_Node *the_node)
Initializes this chain to contain exactly the specified node.
Definition: chainimpl.h:528
struct Scheduler_Node::@20 Wait
Thread wait support block.
Stack_Control Initial_stack
Definition: thread.h:201
Thread_queue_Link Link
Thread queue link provided for use by the thread wait lock owner to build a thread queue path...
Definition: thread.h:471
static void __inline__ _Freechain_Push(Freechain_Control *freechain, void *node)
Pushes a node back to the freechain.
Definition: freechainimpl.h:95
bool is_fp
Indicates whether the thread needs a floating-point area.
Definition: threadimpl.h:181
static __inline__ void _RBTree_Initialize_node(RBTree_Node *the_node)
Initializes a red-black tree node.
Definition: rbtree.h:129
void * stack_area
The starting address of the stack area.
Definition: threadimpl.h:139
Thread_queue_Control Join_queue
Thread queue for thread join operations and multi-purpose lock.
Definition: thread.h:746
const size_t _Scheduler_Count
This constant contains the count of configured schedulers.
Scheduler control.
Definition: scheduler.h:264
Scheduler node for per-thread data.
Definition: schedulernode.h:79
Inlined Routines from the Thread Handler.
#define _ISR_lock_Initialize(_lock, _name)
Initializes an ISR lock.
Definition: isrlock.h:182
bool is_preemptible
Indicates whether the new thread is preemptible.
Definition: threadimpl.h:186
#define THREAD_WAIT_FLAGS_INITIAL
The initial thread wait flags value set by _Thread_Initialize().
Definition: threadimpl.h:2137
#define FALSE
If FALSE is undefined, then FALSE is defined to 0.
Definition: basedefs.h:645
Thread_CPU_budget_algorithms budget_algorithm
Definition: thread.h:187
Chain_Control Wait_nodes
Scheduler nodes immediately available to the thread by its home scheduler and due to thread queue own...
Definition: thread.h:279
Scheduler_Node * nodes
The scheduler nodes of this thread.
Definition: thread.h:351
RTEMS_INLINE_ROUTINE void _Processor_mask_Assign(Processor_mask *dst, const Processor_mask *src)
Copies the mask to another mask, also considers CPU_MAXIMUM_PROCESSORS.
Definition: processormask.h:95
ISR_lock_Control Lock
Lock to protect the scheduler node change requests.
Definition: thread.h:248
uint32_t isr_level
The thread&#39;s initial ISR level.
Definition: threadimpl.h:176
void * area
Definition: stack.h:57
Priority_Node Real_priority
The base priority of this thread in its home scheduler instance.
Definition: thread.h:754
static __inline__ void _Scheduler_Node_destroy(const Scheduler_Control *scheduler, Scheduler_Node *node)
Destroys a scheduler node.
union Scheduler_Node::@19::@22 Scheduler_node
Node to add this scheduler node to Thread_Control::Scheduler::Scheduler_nodes or a temporary remove l...
void(* stack_free)(void *)
This member contains the handler to free the stack.
Definition: threadimpl.h:151
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG.
Definition: assert.h:100
static __inline__ void _Priority_Node_initialize(Priority_Node *node, Priority_Control priority)
Initializes the priority node to the given priority.
Definition: priorityimpl.h:156
uint32_t cpu_time_budget
Definition: thread.h:809
void(* stack_free)(void *)
This field points to the handler which should free the stack.
Definition: thread.h:199
Thread_Timer_information Timer
Definition: thread.h:769
uint16_t object_size
This is the size in bytes of each object control block.
Definition: objectdata.h:238