source: rtems/cpukit/rtems/src/taskcreate.c @ 5088d97

4.104.114.95
Last change on this file since 5088d97 was 5088d97, checked in by Joel Sherrill <joel.sherrill@…>, on 02/28/08 at 16:15:35

2008-02-28 Joel Sherrill <joel.sherrill@…>

  • itron/include/rtems/itron/task.h, itron/src/cre_tsk.c, posix/src/pthreadcreate.c, rtems/src/taskcreate.c, rtems/src/taskdelete.c, rtems/src/timerserver.c, score/src/threadclose.c, score/src/threadcreateidle.c, score/src/threadinitialize.c: Switch task create and delete operations to using API Allocator Mutex. This moves almost all uses of the RTEMS Workspace from dispatching disabled to mutex protected which should improve deterministic behavior. The implementation was carefully done to allow task create and delete extensions to invoke more services. In particular, a task delete extension should be able to do mutex and file operations.
  • Property mode set to 100644
File size: 5.7 KB
Line 
1/*
2 *  RTEMS Task Manager
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 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/rtems/status.h>
21#include <rtems/rtems/support.h>
22#include <rtems/rtems/modes.h>
23#include <rtems/score/object.h>
24#include <rtems/score/stack.h>
25#include <rtems/score/states.h>
26#include <rtems/rtems/tasks.h>
27#include <rtems/score/thread.h>
28#include <rtems/score/threadq.h>
29#include <rtems/score/tod.h>
30#include <rtems/score/userext.h>
31#include <rtems/score/wkspace.h>
32#include <rtems/score/apiext.h>
33#include <rtems/score/sysstate.h>
34#include <rtems/score/apimutex.h>
35
36/*PAGE
37 *
38 *  rtems_task_create
39 *
40 *  This directive creates a thread by allocating and initializing a
41 *  thread control block and a stack.  The newly created thread is
42 *  placed in the dormant state.
43 *
44 *  Input parameters:
45 *    name             - user defined thread name
46 *    initial_priority - thread priority
47 *    stack_size       - stack size in bytes
48 *    initial_modes    - initial thread mode
49 *    attribute_set    - thread attributes
50 *    id               - pointer to thread id
51 *
52 *  Output parameters:
53 *    id               - thread id
54 *    RTEMS_SUCCESSFUL - if successful
55 *    error code       - if unsuccessful
56 */
57
58rtems_status_code rtems_task_create(
59  rtems_name           name,
60  rtems_task_priority  initial_priority,
61  size_t               stack_size,
62  rtems_mode           initial_modes,
63  rtems_attribute      attribute_set,
64  Objects_Id          *id
65)
66{
67  register Thread_Control *the_thread;
68  boolean                  is_fp;
69#if defined(RTEMS_MULTIPROCESSING)
70  Objects_MP_Control      *the_global_object = NULL;
71  boolean                  is_global;
72#endif
73  boolean                  status;
74  rtems_attribute          the_attribute_set;
75  Priority_Control         core_priority;
76  RTEMS_API_Control       *api;
77  ASR_Information         *asr;
78
79
80  if ( !id )
81   return RTEMS_INVALID_ADDRESS;
82
83  if ( !rtems_is_name_valid( name ) )
84    return RTEMS_INVALID_NAME;
85
86  /*
87   *  Core Thread Initialize insures we get the minimum amount of
88   *  stack space.
89   */
90
91  /*
92   *  Fix the attribute set to match the attributes which
93   *  this processor (1) requires and (2) is able to support.
94   *  First add in the required flags for attribute_set
95   *  Typically this might include FP if the platform
96   *  or application required all tasks to be fp aware.
97   *  Then turn off the requested bits which are not supported.
98   */
99
100  the_attribute_set = _Attributes_Set( attribute_set, ATTRIBUTES_REQUIRED );
101  the_attribute_set =
102    _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED );
103
104  if ( _Attributes_Is_floating_point( the_attribute_set ) )
105    is_fp = TRUE;
106  else
107    is_fp = FALSE;
108
109  /*
110   *  Validate the RTEMS API priority and convert it to the core priority range.
111   */
112
113  if ( !_Attributes_Is_system_task( the_attribute_set ) ) {
114    if ( !_RTEMS_tasks_Priority_is_valid( initial_priority ) )
115      return RTEMS_INVALID_PRIORITY;
116  }
117
118  core_priority = _RTEMS_tasks_Priority_to_Core( initial_priority );
119
120#if defined(RTEMS_MULTIPROCESSING)
121  if ( _Attributes_Is_global( the_attribute_set ) ) {
122
123    is_global = TRUE;
124
125    if ( !_System_state_Is_multiprocessing )
126      return RTEMS_MP_NOT_CONFIGURED;
127
128  } else
129    is_global = FALSE;
130#endif
131
132  /*
133   *  Make sure system is MP if this task is global
134   */
135
136  /*
137   *  Lock the allocator mutex for protection
138   */
139  _RTEMS_Lock_allocator();
140
141  /*
142   *  Allocate the thread control block and -- if the task is global --
143   *  allocate a global object control block.
144   *
145   *  NOTE:  This routine does not use the combined allocate and open
146   *         global object routine because this results in a lack of
147   *         control over when memory is allocated and can be freed in
148   *         the event of an error.
149   */
150
151  the_thread = _RTEMS_tasks_Allocate();
152
153  if ( !the_thread ) {
154    _RTEMS_Unlock_allocator();
155    return RTEMS_TOO_MANY;
156  }
157
158#if defined(RTEMS_MULTIPROCESSING)
159  if ( is_global ) {
160    the_global_object = _Objects_MP_Allocate_global_object();
161
162    if ( _Objects_MP_Is_null_global_object( the_global_object ) ) {
163      _RTEMS_tasks_Free( the_thread );
164      _RTEMS_Unlock_allocator();
165      return RTEMS_TOO_MANY;
166    }
167  }
168#endif
169
170  /*
171   *  Initialize the core thread for this task.
172   */
173
174  status = _Thread_Initialize(
175    &_RTEMS_tasks_Information,
176    the_thread,
177    NULL,
178    stack_size,
179    is_fp,
180    core_priority,
181    _Modes_Is_preempt(initial_modes)   ? TRUE : FALSE,
182    _Modes_Is_timeslice(initial_modes) ?
183      THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE :
184      THREAD_CPU_BUDGET_ALGORITHM_NONE,
185    NULL,        /* no budget algorithm callout */
186    _Modes_Get_interrupt_level(initial_modes),
187    (Objects_Name) name
188  );
189
190  if ( !status ) {
191#if defined(RTEMS_MULTIPROCESSING)
192    if ( is_global )
193      _Objects_MP_Free_global_object( the_global_object );
194#endif
195    _RTEMS_tasks_Free( the_thread );
196    _RTEMS_Unlock_allocator();
197    return RTEMS_UNSATISFIED;
198  }
199
200  api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
201  asr = &api->Signal;
202
203  asr->is_enabled = _Modes_Is_asr_disabled(initial_modes) ? FALSE : TRUE;
204
205  *id = the_thread->Object.id;
206
207#if defined(RTEMS_MULTIPROCESSING)
208  the_thread->is_global = is_global;
209  if ( is_global ) {
210
211    _Objects_MP_Open(
212      &_RTEMS_tasks_Information,
213      the_global_object,
214      name,
215      the_thread->Object.id
216    );
217
218    _RTEMS_tasks_MP_Send_process_packet(
219      RTEMS_TASKS_MP_ANNOUNCE_CREATE,
220      the_thread->Object.id,
221      name
222    );
223
224   }
225#endif
226
227  _RTEMS_Unlock_allocator();
228  return RTEMS_SUCCESSFUL;
229}
Note: See TracBrowser for help on using the repository browser.