source: rtems/cpukit/rtems/src/taskcreate.c @ 6b0a729b

5
Last change on this file since 6b0a729b was 21275b58, checked in by Sebastian Huber <sebastian.huber@…>, on 11/22/18 at 18:14:51

score: Static Objects_Information initialization

Statically allocate the objects information together with the initial
set of objects either via <rtems/confdefs.h>. Provide default object
informations with zero objects via librtemscpu.a. This greatly
simplifies the workspace size estimate. RTEMS applications which do not
use the unlimited objects option are easier to debug since all objects
reside now in statically allocated objects of the right types.

Close #3621.

  • Property mode set to 100644
File size: 6.5 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/eventimpl.h>
24#include <rtems/rtems/modesimpl.h>
25#include <rtems/rtems/support.h>
26#include <rtems/score/apimutex.h>
27#include <rtems/score/schedulerimpl.h>
28#include <rtems/score/sysstate.h>
29#include <rtems/score/threadimpl.h>
30#include <rtems/score/userextimpl.h>
31#include <rtems/sysinit.h>
32
33rtems_status_code rtems_task_create(
34  rtems_name           name,
35  rtems_task_priority  initial_priority,
36  size_t               stack_size,
37  rtems_mode           initial_modes,
38  rtems_attribute      attribute_set,
39  rtems_id            *id
40)
41{
42  Thread_Control          *the_thread;
43  const Scheduler_Control *scheduler;
44  bool                     is_fp;
45#if defined(RTEMS_MULTIPROCESSING)
46  Objects_MP_Control      *the_global_object = NULL;
47  bool                     is_global;
48#endif
49  bool                     status;
50  rtems_attribute          the_attribute_set;
51  bool                     valid;
52  Priority_Control         priority;
53  RTEMS_API_Control       *api;
54  ASR_Information         *asr;
55
56
57  if ( !id )
58   return RTEMS_INVALID_ADDRESS;
59
60  if ( !rtems_is_name_valid( name ) )
61    return RTEMS_INVALID_NAME;
62
63  /*
64   *  Core Thread Initialize insures we get the minimum amount of
65   *  stack space.
66   */
67
68  /*
69   *  Fix the attribute set to match the attributes which
70   *  this processor (1) requires and (2) is able to support.
71   *  First add in the required flags for attribute_set
72   *  Typically this might include FP if the platform
73   *  or application required all tasks to be fp aware.
74   *  Then turn off the requested bits which are not supported.
75   */
76
77  the_attribute_set = _Attributes_Set( attribute_set, ATTRIBUTES_REQUIRED );
78  the_attribute_set =
79    _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED );
80
81  if ( _Attributes_Is_floating_point( the_attribute_set ) )
82    is_fp = true;
83  else
84    is_fp = false;
85
86  /*
87   *  Validate the RTEMS API priority and convert it to the core priority range.
88   */
89
90  if ( !_Attributes_Is_system_task( the_attribute_set ) ) {
91    if ( initial_priority == PRIORITY_MINIMUM ) {
92      return RTEMS_INVALID_PRIORITY;
93    }
94  }
95
96  scheduler = _Thread_Scheduler_get_home( _Thread_Get_executing() );
97
98  priority = _RTEMS_Priority_To_core( scheduler, initial_priority, &valid );
99  if ( !valid ) {
100    return RTEMS_INVALID_PRIORITY;
101  }
102
103#if defined(RTEMS_MULTIPROCESSING)
104  if ( _Attributes_Is_global( the_attribute_set ) ) {
105
106    is_global = true;
107
108    if ( !_System_state_Is_multiprocessing )
109      return RTEMS_MP_NOT_CONFIGURED;
110
111  } else
112    is_global = false;
113#endif
114
115  /*
116   *  Allocate the thread control block and -- if the task is global --
117   *  allocate a global object control block.
118   *
119   *  NOTE:  This routine does not use the combined allocate and open
120   *         global object routine (_Objects_MP_Allocate_and_open) because
121   *         this results in a lack of control over when memory is allocated
122   *         and can be freed in the event of an error.
123   */
124  the_thread = _RTEMS_tasks_Allocate();
125
126  if ( !the_thread ) {
127    _Objects_Allocator_unlock();
128    return RTEMS_TOO_MANY;
129  }
130
131#if defined(RTEMS_MULTIPROCESSING)
132  if ( is_global ) {
133    the_global_object = _Objects_MP_Allocate_global_object();
134
135    if ( _Objects_MP_Is_null_global_object( the_global_object ) ) {
136      _RTEMS_tasks_Free( the_thread );
137      _Objects_Allocator_unlock();
138      return RTEMS_TOO_MANY;
139    }
140  }
141#endif
142
143  /*
144   *  Initialize the core thread for this task.
145   */
146
147  status = _Thread_Initialize(
148    &_RTEMS_tasks_Information,
149    the_thread,
150    scheduler,
151    NULL,
152    stack_size,
153    is_fp,
154    priority,
155    _Modes_Is_preempt(initial_modes)   ? true : false,
156    _Modes_Is_timeslice(initial_modes) ?
157      THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE :
158      THREAD_CPU_BUDGET_ALGORITHM_NONE,
159    NULL,        /* no budget algorithm callout */
160    _Modes_Get_interrupt_level(initial_modes),
161    (Objects_Name) name
162  );
163
164  if ( !status ) {
165#if defined(RTEMS_MULTIPROCESSING)
166    if ( is_global )
167      _Objects_MP_Free_global_object( the_global_object );
168#endif
169    _RTEMS_tasks_Free( the_thread );
170    _Objects_Allocator_unlock();
171    return RTEMS_UNSATISFIED;
172  }
173
174  api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
175  asr = &api->Signal;
176
177  asr->is_enabled = _Modes_Is_asr_disabled(initial_modes) ? false : true;
178
179  *id = the_thread->Object.id;
180
181#if defined(RTEMS_MULTIPROCESSING)
182  the_thread->is_global = is_global;
183  if ( is_global ) {
184
185    _Objects_MP_Open(
186      &_RTEMS_tasks_Information.Objects,
187      the_global_object,
188      name,
189      the_thread->Object.id
190    );
191
192    _RTEMS_tasks_MP_Send_process_packet(
193      RTEMS_TASKS_MP_ANNOUNCE_CREATE,
194      the_thread->Object.id,
195      name
196    );
197
198   }
199#endif
200
201  _Objects_Allocator_unlock();
202  return RTEMS_SUCCESSFUL;
203}
204
205static void _RTEMS_tasks_Start_extension(
206  Thread_Control *executing,
207  Thread_Control *started
208)
209{
210  RTEMS_API_Control *api;
211
212  api = started->API_Extensions[ THREAD_API_RTEMS ];
213
214  _Event_Initialize( &api->Event );
215  _Event_Initialize( &api->System_event );
216}
217
218#if defined(RTEMS_MULTIPROCESSING)
219static void _RTEMS_tasks_Terminate_extension( Thread_Control *executing )
220{
221  if ( executing->is_global ) {
222    _Objects_MP_Close(
223      &_RTEMS_tasks_Information.Objects,
224      executing->Object.id
225    );
226    _RTEMS_tasks_MP_Send_process_packet(
227      RTEMS_TASKS_MP_ANNOUNCE_DELETE,
228      executing->Object.id,
229      0                                /* Not used */
230    );
231  }
232}
233#endif
234
235static User_extensions_Control _RTEMS_tasks_User_extensions = {
236  .Callouts = {
237#if defined(RTEMS_MULTIPROCESSING)
238    .thread_terminate = _RTEMS_tasks_Terminate_extension,
239#endif
240    .thread_start     = _RTEMS_tasks_Start_extension,
241    .thread_restart   = _RTEMS_tasks_Start_extension
242  }
243};
244
245static void _RTEMS_tasks_Manager_initialization(void)
246{
247  _Thread_Initialize_information( &_RTEMS_tasks_Information );
248  _User_extensions_Add_API_set( &_RTEMS_tasks_User_extensions );
249
250#if defined(RTEMS_MULTIPROCESSING)
251  _MPCI_Register_packet_processor(
252    MP_PACKET_TASKS,
253    _RTEMS_tasks_MP_Process_packet
254  );
255#endif
256}
257
258RTEMS_SYSINIT_ITEM(
259  _RTEMS_tasks_Manager_initialization,
260  RTEMS_SYSINIT_CLASSIC_TASKS,
261  RTEMS_SYSINIT_ORDER_MIDDLE
262);
Note: See TracBrowser for help on using the repository browser.