source: rtems/cpukit/rtems/src/taskcreate.c @ 66cb142

Last change on this file since 66cb142 was 2f5ac5b, checked in by Sebastian Huber <sebastian.huber@…>, on Nov 4, 2016 at 2:26:52 PM

rtems: Fix rtems_task_create() scheduler selection

Use the home scheduler of the executing thread for the created thread.
This is in line with pthread_create(). Using the current processor may
pick up an unexpected scheduler in case of a temporary migration, e.g.
due to locking protocols.

  • Property mode set to 100644
File size: 5.0 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  const Scheduler_Control *scheduler;
41  bool                     is_fp;
42#if defined(RTEMS_MULTIPROCESSING)
43  Objects_MP_Control      *the_global_object = NULL;
44  bool                     is_global;
45#endif
46  bool                     status;
47  rtems_attribute          the_attribute_set;
48  bool                     valid;
49  Priority_Control         priority;
50  RTEMS_API_Control       *api;
51  ASR_Information         *asr;
52
53
54  if ( !id )
55   return RTEMS_INVALID_ADDRESS;
56
57  if ( !rtems_is_name_valid( name ) )
58    return RTEMS_INVALID_NAME;
59
60  /*
61   *  Core Thread Initialize insures we get the minimum amount of
62   *  stack space.
63   */
64
65  /*
66   *  Fix the attribute set to match the attributes which
67   *  this processor (1) requires and (2) is able to support.
68   *  First add in the required flags for attribute_set
69   *  Typically this might include FP if the platform
70   *  or application required all tasks to be fp aware.
71   *  Then turn off the requested bits which are not supported.
72   */
73
74  the_attribute_set = _Attributes_Set( attribute_set, ATTRIBUTES_REQUIRED );
75  the_attribute_set =
76    _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED );
77
78  if ( _Attributes_Is_floating_point( the_attribute_set ) )
79    is_fp = true;
80  else
81    is_fp = false;
82
83  /*
84   *  Validate the RTEMS API priority and convert it to the core priority range.
85   */
86
87  if ( !_Attributes_Is_system_task( the_attribute_set ) ) {
88    if ( initial_priority == PRIORITY_MINIMUM ) {
89      return RTEMS_INVALID_PRIORITY;
90    }
91  }
92
93  scheduler = _Thread_Scheduler_get_home( _Thread_Get_executing() );
94
95  priority = _RTEMS_Priority_To_core( scheduler, initial_priority, &valid );
96  if ( !valid ) {
97    return RTEMS_INVALID_PRIORITY;
98  }
99
100#if defined(RTEMS_MULTIPROCESSING)
101  if ( _Attributes_Is_global( the_attribute_set ) ) {
102
103    is_global = true;
104
105    if ( !_System_state_Is_multiprocessing )
106      return RTEMS_MP_NOT_CONFIGURED;
107
108  } else
109    is_global = false;
110#endif
111
112  /*
113   *  Allocate the thread control block and -- if the task is global --
114   *  allocate a global object control block.
115   *
116   *  NOTE:  This routine does not use the combined allocate and open
117   *         global object routine (_Objects_MP_Allocate_and_open) because
118   *         this results in a lack of control over when memory is allocated
119   *         and can be freed in the event of an error.
120   */
121  the_thread = _RTEMS_tasks_Allocate();
122
123  if ( !the_thread ) {
124    _Objects_Allocator_unlock();
125    return RTEMS_TOO_MANY;
126  }
127
128#if defined(RTEMS_MULTIPROCESSING)
129  if ( is_global ) {
130    the_global_object = _Objects_MP_Allocate_global_object();
131
132    if ( _Objects_MP_Is_null_global_object( the_global_object ) ) {
133      _RTEMS_tasks_Free( the_thread );
134      _Objects_Allocator_unlock();
135      return RTEMS_TOO_MANY;
136    }
137  }
138#endif
139
140  /*
141   *  Initialize the core thread for this task.
142   */
143
144  status = _Thread_Initialize(
145    &_RTEMS_tasks_Information,
146    the_thread,
147    scheduler,
148    NULL,
149    stack_size,
150    is_fp,
151    priority,
152    _Modes_Is_preempt(initial_modes)   ? true : false,
153    _Modes_Is_timeslice(initial_modes) ?
154      THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE :
155      THREAD_CPU_BUDGET_ALGORITHM_NONE,
156    NULL,        /* no budget algorithm callout */
157    _Modes_Get_interrupt_level(initial_modes),
158    (Objects_Name) name
159  );
160
161  if ( !status ) {
162#if defined(RTEMS_MULTIPROCESSING)
163    if ( is_global )
164      _Objects_MP_Free_global_object( the_global_object );
165#endif
166    _RTEMS_tasks_Free( the_thread );
167    _Objects_Allocator_unlock();
168    return RTEMS_UNSATISFIED;
169  }
170
171  api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
172  asr = &api->Signal;
173
174  asr->is_enabled = _Modes_Is_asr_disabled(initial_modes) ? false : true;
175
176  *id = the_thread->Object.id;
177
178#if defined(RTEMS_MULTIPROCESSING)
179  the_thread->is_global = is_global;
180  if ( is_global ) {
181
182    _Objects_MP_Open(
183      &_RTEMS_tasks_Information.Objects,
184      the_global_object,
185      name,
186      the_thread->Object.id
187    );
188
189    _RTEMS_tasks_MP_Send_process_packet(
190      RTEMS_TASKS_MP_ANNOUNCE_CREATE,
191      the_thread->Object.id,
192      name
193    );
194
195   }
196#endif
197
198  _Objects_Allocator_unlock();
199  return RTEMS_SUCCESSFUL;
200}
Note: See TracBrowser for help on using the repository browser.