source: rtems/cpukit/rtems/src/taskcreate.c @ 2b9374e1

Last change on this file since 2b9374e1 was 2b9374e1, checked in by Joel Sherrill <joel@…>, on Jan 18, 2016 at 11:34:25 PM

taskcreate.c: Add method name to comment to be clearer

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief RTEMS Task Create
5 *  @ingroup ClassicTasks
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2014,2016.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/rtems/tasksimpl.h>
22#include <rtems/rtems/attrimpl.h>
23#include <rtems/rtems/modesimpl.h>
24#include <rtems/rtems/support.h>
25#include <rtems/score/apimutex.h>
26#include <rtems/score/schedulerimpl.h>
27#include <rtems/score/sysstate.h>
28#include <rtems/score/threadimpl.h>
29
30rtems_status_code rtems_task_create(
31  rtems_name           name,
32  rtems_task_priority  initial_priority,
33  size_t               stack_size,
34  rtems_mode           initial_modes,
35  rtems_attribute      attribute_set,
36  rtems_id            *id
37)
38{
39  Thread_Control          *the_thread;
40  bool                     is_fp;
41#if defined(RTEMS_MULTIPROCESSING)
42  Objects_MP_Control      *the_global_object = NULL;
43  bool                     is_global;
44#endif
45  bool                     status;
46  rtems_attribute          the_attribute_set;
47  Priority_Control         core_priority;
48  RTEMS_API_Control       *api;
49  ASR_Information         *asr;
50
51
52  if ( !id )
53   return RTEMS_INVALID_ADDRESS;
54
55  if ( !rtems_is_name_valid( name ) )
56    return RTEMS_INVALID_NAME;
57
58  /*
59   *  Core Thread Initialize insures we get the minimum amount of
60   *  stack space.
61   */
62
63  /*
64   *  Fix the attribute set to match the attributes which
65   *  this processor (1) requires and (2) is able to support.
66   *  First add in the required flags for attribute_set
67   *  Typically this might include FP if the platform
68   *  or application required all tasks to be fp aware.
69   *  Then turn off the requested bits which are not supported.
70   */
71
72  the_attribute_set = _Attributes_Set( attribute_set, ATTRIBUTES_REQUIRED );
73  the_attribute_set =
74    _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED );
75
76  if ( _Attributes_Is_floating_point( the_attribute_set ) )
77    is_fp = true;
78  else
79    is_fp = false;
80
81  /*
82   *  Validate the RTEMS API priority and convert it to the core priority range.
83   */
84
85  if ( !_Attributes_Is_system_task( the_attribute_set ) ) {
86    if ( !_RTEMS_tasks_Priority_is_valid( initial_priority ) )
87      return RTEMS_INVALID_PRIORITY;
88  }
89
90  core_priority = _RTEMS_tasks_Priority_to_Core( initial_priority );
91
92#if defined(RTEMS_MULTIPROCESSING)
93  if ( _Attributes_Is_global( the_attribute_set ) ) {
94
95    is_global = true;
96
97    if ( !_System_state_Is_multiprocessing )
98      return RTEMS_MP_NOT_CONFIGURED;
99
100  } else
101    is_global = false;
102#endif
103
104  /*
105   *  Allocate the thread control block and -- if the task is global --
106   *  allocate a global object control block.
107   *
108   *  NOTE:  This routine does not use the combined allocate and open
109   *         global object routine (_Objects_MP_Allocate_and_open) because
110   *         this results in a lack of control over when memory is allocated
111   *         and can be freed in the event of an error.
112   */
113  the_thread = _RTEMS_tasks_Allocate();
114
115  if ( !the_thread ) {
116    _Objects_Allocator_unlock();
117    return RTEMS_TOO_MANY;
118  }
119
120#if defined(RTEMS_MULTIPROCESSING)
121  if ( is_global ) {
122    the_global_object = _Objects_MP_Allocate_global_object();
123
124    if ( _Objects_MP_Is_null_global_object( the_global_object ) ) {
125      _RTEMS_tasks_Free( the_thread );
126      _Objects_Allocator_unlock();
127      return RTEMS_TOO_MANY;
128    }
129  }
130#endif
131
132  /*
133   *  Initialize the core thread for this task.
134   */
135
136  status = _Thread_Initialize(
137    &_RTEMS_tasks_Information,
138    the_thread,
139    _Scheduler_Get_by_CPU_index( _SMP_Get_current_processor() ),
140    NULL,
141    stack_size,
142    is_fp,
143    core_priority,
144    _Modes_Is_preempt(initial_modes)   ? true : false,
145    _Modes_Is_timeslice(initial_modes) ?
146      THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE :
147      THREAD_CPU_BUDGET_ALGORITHM_NONE,
148    NULL,        /* no budget algorithm callout */
149    _Modes_Get_interrupt_level(initial_modes),
150    (Objects_Name) name
151  );
152
153  if ( !status ) {
154#if defined(RTEMS_MULTIPROCESSING)
155    if ( is_global )
156      _Objects_MP_Free_global_object( the_global_object );
157#endif
158    _RTEMS_tasks_Free( the_thread );
159    _Objects_Allocator_unlock();
160    return RTEMS_UNSATISFIED;
161  }
162
163  api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
164  asr = &api->Signal;
165
166  asr->is_enabled = _Modes_Is_asr_disabled(initial_modes) ? false : true;
167
168  *id = the_thread->Object.id;
169
170#if defined(RTEMS_MULTIPROCESSING)
171  the_thread->is_global = is_global;
172  if ( is_global ) {
173
174    _Objects_MP_Open(
175      &_RTEMS_tasks_Information.Objects,
176      the_global_object,
177      name,
178      the_thread->Object.id
179    );
180
181    _RTEMS_tasks_MP_Send_process_packet(
182      RTEMS_TASKS_MP_ANNOUNCE_CREATE,
183      the_thread->Object.id,
184      name
185    );
186
187   }
188#endif
189
190  _Objects_Allocator_unlock();
191  return RTEMS_SUCCESSFUL;
192}
Note: See TracBrowser for help on using the repository browser.