source: rtems/cpukit/score/src/threadinitialize.c @ aa4a3f1

4.104.114.9
Last change on this file since aa4a3f1 was aa4a3f1, checked in by Joel Sherrill <joel.sherrill@…>, on Aug 20, 2008 at 10:24:09 PM

2008-08-20 Joel Sherrill <joel.sherrill@…>

  • libmisc/dummy/dummy.c: Add missing initializers.
  • score/src/threadinitialize.c: Change type of loop counter.
  • Property mode set to 100644
File size: 6.3 KB
Line 
1/*
2 *  Thread Handler
3 *
4 *
5 *  COPYRIGHT (c) 1989-2008.
6 *  On-Line Applications Research Corporation (OAR).
7 *
8 *  The license and distribution terms for this file may be
9 *  found in found in the file LICENSE in this distribution or at
10 *  http://www.rtems.com/license/LICENSE.
11 *
12 *  $Id$
13 */
14
15#if HAVE_CONFIG_H
16#include "config.h"
17#endif
18
19#include <rtems/system.h>
20#include <rtems/score/apiext.h>
21#include <rtems/score/context.h>
22#include <rtems/score/interr.h>
23#include <rtems/score/isr.h>
24#include <rtems/score/object.h>
25#include <rtems/score/priority.h>
26#include <rtems/score/states.h>
27#include <rtems/score/sysstate.h>
28#include <rtems/score/thread.h>
29#include <rtems/score/threadq.h>
30#include <rtems/score/userext.h>
31#include <rtems/score/watchdog.h>
32#include <rtems/score/wkspace.h>
33
34/*PAGE
35 *
36 *  _Thread_Initialize
37 *
38 *  This routine initializes the specified the thread.  It allocates
39 *  all memory associated with this thread.  It completes by adding
40 *  the thread to the local object table so operations on this
41 *  thread id are allowed.
42 */
43
44boolean _Thread_Initialize(
45  Objects_Information                  *information,
46  Thread_Control                       *the_thread,
47  void                                 *stack_area,
48  size_t                                stack_size,
49  boolean                               is_fp,
50  Priority_Control                      priority,
51  boolean                               is_preemptible,
52  Thread_CPU_budget_algorithms          budget_algorithm,
53  Thread_CPU_budget_algorithm_callout   budget_callout,
54  uint32_t                              isr_level,
55  Objects_Name                          name
56)
57{
58  size_t               actual_stack_size = 0;
59  void                *stack = NULL;
60#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
61  void                *fp_area;
62#endif
63  void                *extensions_area;
64  boolean              extension_status;
65
66#if __RTEMS_ADA__
67  /*
68   *  Initialize the Ada self pointer
69   */
70
71  the_thread->rtems_ada_self = NULL;
72#endif
73
74  /*
75   *  Allocate and Initialize the stack for this thread.
76   */
77
78
79  if ( !stack_area ) {
80
81    actual_stack_size = _Stack_Ensure_minimum( stack_size );
82
83    actual_stack_size = _Thread_Stack_Allocate( the_thread, actual_stack_size );
84
85    if ( !actual_stack_size || actual_stack_size < stack_size )
86      return FALSE;                     /* stack allocation failed */
87
88    stack = the_thread->Start.stack;
89    the_thread->Start.core_allocated_stack = TRUE;
90  } else {
91    stack = stack_area;
92    actual_stack_size = stack_size;
93    the_thread->Start.core_allocated_stack = FALSE;
94  }
95
96  _Stack_Initialize(
97     &the_thread->Start.Initial_stack,
98     stack,
99     actual_stack_size
100  );
101
102  /*
103   *  Allocate the floating point area for this thread
104   */
105
106#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
107  if ( is_fp ) {
108
109    fp_area = _Workspace_Allocate( CONTEXT_FP_SIZE );
110    if ( !fp_area ) {
111      _Thread_Stack_Free( the_thread );
112      return FALSE;
113    }
114    fp_area = _Context_Fp_start( fp_area, 0 );
115
116  } else
117    fp_area = NULL;
118
119  the_thread->fp_context       = fp_area;
120  the_thread->Start.fp_context = fp_area;
121#endif
122
123  /*
124   *  Initialize the thread timer
125   */
126  _Watchdog_Initialize( &the_thread->Timer, NULL, 0, NULL );
127
128#ifdef __RTEMS_STRICT_ORDER_MUTEX__
129  /*Initialize the head of chain of mutex */
130  _Chain_Initialize_empty(&the_thread->lock_mutex);
131#endif
132
133  /*
134   * Clear the libc reent hook.
135   */
136
137  the_thread->libc_reent = NULL;
138
139  /*
140   *  Allocate the extensions area for this thread
141   */
142
143  if ( _Thread_Maximum_extensions ) {
144    extensions_area = _Workspace_Allocate(
145      (_Thread_Maximum_extensions + 1) * sizeof( void * )
146    );
147
148    if ( !extensions_area ) {
149#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
150      if ( fp_area )
151        (void) _Workspace_Free( fp_area );
152#endif
153
154      _Thread_Stack_Free( the_thread );
155
156      return FALSE;
157    }
158  } else
159    extensions_area = NULL;
160
161  the_thread->extensions = (void **) extensions_area;
162
163  /*
164   * Clear the extensions area so extension users can determine
165   * if they are linked to the thread. An extension user may
166   * create the extension long after tasks have been created
167   * so they cannot rely on the thread create user extension
168   * call.
169   */
170
171  if ( the_thread->extensions ) {
172    uint32_t i;
173    for ( i = 0; i < (_Thread_Maximum_extensions + 1); i++ )
174      the_thread->extensions[i] = NULL;
175  }
176
177  /*
178   *  General initialization
179   */
180
181  the_thread->Start.is_preemptible   = is_preemptible;
182  the_thread->Start.budget_algorithm = budget_algorithm;
183  the_thread->Start.budget_callout   = budget_callout;
184
185  switch ( budget_algorithm ) {
186    case THREAD_CPU_BUDGET_ALGORITHM_NONE:
187    case THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE:
188      break;
189    case THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE:
190      the_thread->cpu_time_budget = _Thread_Ticks_per_timeslice;
191      break;
192    case THREAD_CPU_BUDGET_ALGORITHM_CALLOUT:
193      break;
194  }
195
196  the_thread->Start.isr_level         = isr_level;
197
198  the_thread->current_state           = STATES_DORMANT;
199  the_thread->Wait.queue              = NULL;
200  the_thread->resource_count          = 0;
201  the_thread->suspend_count           = 0;
202  the_thread->real_priority           = priority;
203  the_thread->Start.initial_priority  = priority;
204  _Thread_Set_priority( the_thread, priority );
205
206  /*
207   *  Initialize the CPU usage statistics
208   */
209
210  #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
211    the_thread->cpu_time_used.tv_sec  = 0;
212    the_thread->cpu_time_used.tv_nsec = 0;
213  #else
214    the_thread->cpu_time_used         = 0;
215  #endif
216
217  /*
218   *  Open the object
219   */
220
221  _Objects_Open( information, &the_thread->Object, name );
222
223  /*
224   *  We assume the Allocator Mutex is locked and dispatching is
225   *  enabled when we get here.  We want to be able to run the
226   *  user extensions with dispatching enabled.  The Allocator
227   *  Mutex provides sufficient protection to let the user extensions
228   *  run safely.
229   */
230  extension_status = _User_extensions_Thread_create( the_thread );
231
232  if ( !extension_status ) {
233
234    if ( extensions_area )
235      (void) _Workspace_Free( extensions_area );
236
237#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
238    if ( fp_area )
239      (void) _Workspace_Free( fp_area );
240#endif
241
242    _Thread_Stack_Free( the_thread );
243
244    return FALSE;
245  }
246
247  return TRUE;
248
249}
Note: See TracBrowser for help on using the repository browser.