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

4.115
Last change on this file since c6e21ee1 was c6e21ee1, checked in by Sebastian Huber <sebastian.huber@…>, on 07/24/13 at 11:12:38

score: Create scheduler implementation header

Move implementation specific parts of scheduler.h and scheduler.inl into
new header file schedulerimpl.h. The scheduler.h contains now only the
application visible API.

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