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

4.11
Last change on this file since a936aa49 was a936aa49, checked in by Sebastian Huber <sebastian.huber@…>, on Jun 6, 2013 at 1:41:00 PM

scheduler: New simple SMP scheduler implementation

The new Simple SMP Scheduler allocates a processor for the processor
count highest priority ready threads. The thread priority and position
in the ready chain are the only information to determine the scheduling
decision. Threads with an allocated processor are in the scheduled
chain. After initialization the scheduled chain has exactly processor
count nodes. Each processor has exactly one allocated thread after
initialization. All enqueue and extract operations may exchange threads
with the scheduled chain. One thread will be added and another will be
removed. The scheduled and ready chain is ordered according to the
thread priority order. The chain insert operations are O(count of ready
threads), thus this scheduler is unsuitable for most real-time
applications.

The thread preempt mode will be ignored.

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