source: rtems/cpukit/rtems/src/taskcreate.c @ a29d2e7

4.104.114.84.95
Last change on this file since a29d2e7 was 1095ec1, checked in by Ralf Corsepius <ralf.corsepius@…>, on 01/18/05 at 09:03:45

Include config.h.

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