RTEMS
taskbuild.c
Go to the documentation of this file.
1 
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 #ifdef 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>
28 #include <rtems/score/stackimpl.h>
29 #include <rtems/score/sysstate.h>
30 #include <rtems/score/threadimpl.h>
32 #include <rtems/sysinit.h>
33 
34 #include <string.h>
35 
36 static void _RTEMS_tasks_Prepare_user_stack(
37  Thread_Configuration *thread_config,
38  const rtems_task_config *config
39 )
40 {
41  thread_config->stack_size = config->stack_size;
42  thread_config->stack_area = config->stack_area;
43 
44  if ( config->stack_free != NULL ) {
45  thread_config->stack_free = config->stack_free;
46  } else {
47  thread_config->stack_free = _Stack_Free_nothing;
48  }
49 }
50 
51 rtems_status_code rtems_task_build(
52  const rtems_task_config *config,
53  rtems_id *id
54 )
55 {
56  return _RTEMS_tasks_Build( config, id, _RTEMS_tasks_Prepare_user_stack );
57 }
58 
59 rtems_status_code _RTEMS_tasks_Build(
60  const rtems_task_config *config,
61  rtems_id *id,
62  void ( *prepare_stack )( Thread_Configuration *, const rtems_task_config * )
63 )
64 {
65  Thread_Control *the_thread;
66  Thread_Configuration thread_config;
67 #if defined(RTEMS_MULTIPROCESSING)
68  Objects_MP_Control *the_global_object = NULL;
69  bool is_global;
70 #endif
71  bool status;
72  rtems_attribute attributes;
73  bool valid;
74  RTEMS_API_Control *api;
75  ASR_Information *asr;
76 
77  if ( !id )
78  return RTEMS_INVALID_ADDRESS;
79 
80  if ( !rtems_is_name_valid( config->name ) )
81  return RTEMS_INVALID_NAME;
82 
83  /*
84  * Core Thread Initialize insures we get the minimum amount of
85  * stack space.
86  */
87 
88  /*
89  * Fix the attribute set to match the attributes which
90  * this processor (1) requires and (2) is able to support.
91  * First add in the required flags for attributes
92  * Typically this might include FP if the platform
93  * or application required all tasks to be fp aware.
94  * Then turn off the requested bits which are not supported.
95  */
96 
97  attributes = _Attributes_Set( config->attribute_set, ATTRIBUTES_REQUIRED );
98  attributes = _Attributes_Clear( attributes, ATTRIBUTES_NOT_SUPPORTED );
99 
100  memset( &thread_config, 0, sizeof( thread_config ) );
101  thread_config.budget_algorithm = _Modes_Is_timeslice( config->initial_modes ) ?
102  THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE
103  : THREAD_CPU_BUDGET_ALGORITHM_NONE,
104  thread_config.isr_level = _Modes_Get_interrupt_level( config->initial_modes );
105  thread_config.name.name_u32 = config->name;
106  thread_config.is_fp = _Attributes_Is_floating_point( attributes );
107  thread_config.is_preemptible = _Modes_Is_preempt( config->initial_modes );
108 
109  /*
110  * Validate the RTEMS API priority and convert it to the core priority range.
111  */
112 
113  if ( !_Attributes_Is_system_task( attributes ) ) {
114  if ( config->initial_priority == PRIORITY_MINIMUM ) {
115  return RTEMS_INVALID_PRIORITY;
116  }
117  }
118 
119  thread_config.scheduler =
121 
122  thread_config.priority = _RTEMS_Priority_To_core(
123  thread_config.scheduler,
124  config->initial_priority,
125  &valid
126  );
127  if ( !valid ) {
128  return RTEMS_INVALID_PRIORITY;
129  }
130 
131 #if defined(RTEMS_MULTIPROCESSING)
132  if ( !_System_state_Is_multiprocessing ) {
133  attributes = _Attributes_Clear( attributes, RTEMS_GLOBAL );
134  }
135 
136  is_global = _Attributes_Is_global( attributes );
137 #endif
138 
139  /*
140  * Allocate the thread control block and -- if the task is global --
141  * allocate a global object control block.
142  *
143  * NOTE: This routine does not use the combined allocate and open
144  * global object routine (_Objects_MP_Allocate_and_open) because
145  * this results in a lack of control over when memory is allocated
146  * and can be freed in the event of an error.
147  */
148  the_thread = _RTEMS_tasks_Allocate();
149 
150  if ( !the_thread ) {
152  return RTEMS_TOO_MANY;
153  }
154 
155 #if defined(RTEMS_MULTIPROCESSING)
156  if ( is_global ) {
157  the_global_object = _Objects_MP_Allocate_global_object();
158 
159  if ( _Objects_MP_Is_null_global_object( the_global_object ) ) {
160  _RTEMS_tasks_Free( the_thread );
162  return RTEMS_TOO_MANY;
163  }
164  }
165 #endif
166 
167  ( *prepare_stack )( &thread_config, config );
168  status = ( thread_config.stack_area != NULL );
169 
170  /*
171  * Initialize the core thread for this task.
172  */
173 
174  if ( status ) {
175  status = _Thread_Initialize(
177  the_thread,
178  &thread_config
179  );
180  }
181 
182  if ( !status ) {
183 #if defined(RTEMS_MULTIPROCESSING)
184  if ( is_global )
185  _Objects_MP_Free_global_object( the_global_object );
186 #endif
187  _RTEMS_tasks_Free( the_thread );
189  return RTEMS_UNSATISFIED;
190  }
191 
192  api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
193  asr = &api->Signal;
194 
196 
197  *id = the_thread->Object.id;
198 
199 #if defined(RTEMS_MULTIPROCESSING)
200  the_thread->is_global = is_global;
201  if ( is_global ) {
202 
203  _Objects_MP_Open(
205  the_global_object,
206  config->name,
207  the_thread->Object.id
208  );
209 
210  _RTEMS_tasks_MP_Send_process_packet(
211  RTEMS_TASKS_MP_ANNOUNCE_CREATE,
212  the_thread->Object.id,
213  config->name
214  );
215 
216  }
217 #endif
218 
220  return RTEMS_SUCCESSFUL;
221 }
222 
223 static void _RTEMS_tasks_Start_extension(
224  Thread_Control *executing,
225  Thread_Control *started
226 )
227 {
228  RTEMS_API_Control *api;
229 
230  api = started->API_Extensions[ THREAD_API_RTEMS ];
231 
232  _Event_Initialize( &api->Event );
233  _Event_Initialize( &api->System_event );
234 }
235 
236 #if defined(RTEMS_MULTIPROCESSING)
237 static void _RTEMS_tasks_Terminate_extension( Thread_Control *executing )
238 {
239  if ( executing->is_global ) {
240  _Objects_MP_Close(
242  executing->Object.id
243  );
244  _RTEMS_tasks_MP_Send_process_packet(
245  RTEMS_TASKS_MP_ANNOUNCE_DELETE,
246  executing->Object.id,
247  0 /* Not used */
248  );
249  }
250 }
251 #endif
252 
253 static User_extensions_Control _RTEMS_tasks_User_extensions = {
254  .Callouts = {
255 #if defined(RTEMS_MULTIPROCESSING)
256  .thread_terminate = _RTEMS_tasks_Terminate_extension,
257 #endif
258  .thread_start = _RTEMS_tasks_Start_extension,
259  .thread_restart = _RTEMS_tasks_Start_extension
260  }
261 };
262 
263 static void _RTEMS_tasks_Manager_initialization( void )
264 {
266  _User_extensions_Add_API_set( &_RTEMS_tasks_User_extensions );
267 }
268 
269 RTEMS_SYSINIT_ITEM(
270  _RTEMS_tasks_Manager_initialization,
271  RTEMS_SYSINIT_CLASSIC_TASKS,
272  RTEMS_SYSINIT_ORDER_MIDDLE
273 );
This status code indicates you have attempted to create too many instances of a particular object cla...
Definition: status.h:112
uint32_t name_u32
Definition: object.h:68
static __inline__ void _Objects_Allocator_unlock(void)
Unlocks the object allocator mutex.
Definition: objectimpl.h:846
This header file defines support services of the API.
Thread_CPU_budget_algorithms budget_algorithm
The thread&#39;s budget algorithm.
Definition: threadimpl.h:161
static __inline__ Priority_Control _RTEMS_Priority_To_core(const Scheduler_Control *scheduler, rtems_task_priority priority, bool *valid)
Converts the RTEMS API priority to the corresponding SuperCore priority and validates it...
Definition: tasksimpl.h:96
#define ATTRIBUTES_REQUIRED
Definition: attrimpl.h:49
rtems_mode initial_modes
This member defines the initial modes of the task.
Definition: tasks.h:207
This status code indicates that an invalid thread priority was provided.
Definition: status.h:189
RTEMS_INLINE_ROUTINE bool _Attributes_Is_floating_point(rtems_attribute attribute_set)
Checks if the floating point attribute is enabled in the attribute_set.
Definition: attrimpl.h:90
static __inline__ const Scheduler_Control * _Thread_Scheduler_get_home(const Thread_Control *the_thread)
Gets the home scheduler of the thread.
Definition: threadimpl.h:1419
static __inline__ bool _Modes_Is_asr_disabled(rtems_mode mode_set)
Checks if mode_set says that Asynchronous Signal Processing is disabled.
Definition: modesimpl.h:55
#define PRIORITY_MINIMUM
The highest (most important) thread priority value.
Definition: priority.h:75
Classic Modes Implementation.
static __inline__ void _RTEMS_tasks_Free(Thread_Control *the_task)
Frees a task control block.
Definition: tasksimpl.h:72
void _Stack_Free_nothing(void *stack_area)
This function does nothing.
Inlined Routines Associated with the Manipulation of the Scheduler.
This status code indicates that the request was not satisfied.
Definition: status.h:154
static bool rtems_is_name_valid(rtems_status_code name)
Returns true, if the specified object name is valid, otherwise returns false.
Definition: support.h:126
rtems_name name
This member defines the name of the task.
Definition: tasks.h:138
RTEMS_INLINE_ROUTINE bool _Attributes_Is_system_task(rtems_attribute attribute_set)
Checks if the system task attribute is enabled in the attribute_set.
Definition: attrimpl.h:249
Event_Control System_event
Definition: tasksdata.h:45
User Extension Handler API.
Objects_Information Objects
The object information.
Definition: thread.h:1004
This structure defines the configuration of a task constructed by rtems_task_construct().
Definition: tasks.h:134
RTEMS_INLINE_ROUTINE rtems_attribute _Attributes_Set(rtems_attribute new_attributes, rtems_attribute attribute_set)
Sets the requested new_attributes in the attribute_set passed in.
Definition: attrimpl.h:60
bool _Thread_Initialize(Thread_Information *information, Thread_Control *the_thread, const Thread_Configuration *config)
Initializes thread.
Thread_Information _RTEMS_tasks_Information
static __inline__ struct _Thread_Control * _Thread_Get_executing(void)
Returns the thread control block of the executing thread.
Definition: percpu.h:878
Event_Control Event
Definition: tasksdata.h:43
Classic Event Manager Implementation.
Inlined Routines from the Stack Handler.
Objects_Name name
Name of the object for the thread.
Definition: threadimpl.h:171
bool is_enabled
Definition: asrdata.h:38
This status code indicates successful completion.
Definition: status.h:86
ASR_Information Signal
Definition: tasksdata.h:47
Priority_Control priority
The new thread&#39;s priority.
Definition: threadimpl.h:156
static __inline__ bool _Modes_Is_timeslice(rtems_mode mode_set)
Checks if mode_set indicates that timeslicing is enabled.
Definition: modesimpl.h:81
rtems_status_code
This enumeration provides status codes for directives of the Classic API.
Definition: status.h:82
const struct _Scheduler_Control * scheduler
The scheduler control instance for the thread.
Definition: threadimpl.h:134
The configuration of a new thread to initialize.
Definition: threadimpl.h:130
Objects_Control Object
Definition: thread.h:727
API Mutex Handler API.
size_t stack_size
The size of the stack area in bytes.
Definition: threadimpl.h:144
static __inline__ ISR_Level _Modes_Get_interrupt_level(rtems_mode mode_set)
Gets the interrupt level portion of the mode_set.
Definition: modesimpl.h:93
#define ATTRIBUTES_NOT_SUPPORTED
Definition: attrimpl.h:42
rtems_task_priority initial_priority
This member defines the initial priority of the task.
Definition: tasks.h:143
This status code indicates that a specified address was invalid.
Definition: status.h:133
uint32_t rtems_attribute
This type is used to represent Classic API attributes.
Definition: attr.h:91
void * API_Extensions[THREAD_API_LAST+1]
Definition: thread.h:840
Classic Attributes Implementation.
Objects_Id rtems_id
Values of this type identify an RTEMS object.
Definition: types.h:99
bool is_fp
Indicates whether the thread needs a floating-point area.
Definition: threadimpl.h:181
System State Handler API.
void * stack_area
The starting address of the stack area.
Definition: threadimpl.h:139
RTEMS_INLINE_ROUTINE rtems_attribute _Attributes_Clear(rtems_attribute attribute_set, rtems_attribute mask)
Clears the requested new_attributes in the attribute_set passed in.
Definition: attrimpl.h:75
Inlined Routines from the Thread Handler.
bool is_preemptible
Indicates whether the new thread is preemptible.
Definition: threadimpl.h:186
Manages each user extension set.
Definition: userextdata.h:50
static __inline__ bool _Modes_Is_preempt(rtems_mode mode_set)
Checks if mode_set indicates that preemption is enabled.
Definition: modesimpl.h:68
static __inline__ void _User_extensions_Add_API_set(User_extensions_Control *extension)
Adds a user extension.
Definition: userextimpl.h:104
This status code indicates that an object name was invalid.
Definition: status.h:101
uint32_t isr_level
The thread&#39;s initial ISR level.
Definition: threadimpl.h:176
#define RTEMS_GLOBAL
This attribute constant indicates that the Classic API object shall be a global resource in a multipr...
Definition: attr.h:173
void(* stack_free)(void *)
This member contains the handler to free the stack.
Definition: threadimpl.h:151
void _Thread_Initialize_information(Thread_Information *information)
Initializes the thread information.
Definition: thread.c:46
Classic Tasks Manager Implementation.
Objects_Id id
Definition: objectdata.h:43