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

Last change on this file since d7665823 was d7665823, checked in by Sebastian Huber <sebastian.huber@…>, on Jun 24, 2015 at 1:43:19 PM

score: Introduce Thread_queue_Heads

Move the storage for the thread queue heads to the threads. Each thread
provides a set of thread queue heads allocated from a dedicated memory
pool. In case a thread blocks on a queue, then it lends its heads to
the queue. In case the thread unblocks, then it takes a free set of
threads from the queue. Since a thread can block on at most one queue
this works. This mechanism is used in FreeBSD. The motivation for this
change is to reduce the memory demands of the synchronization objects.
On a 32-bit uni-processor configuration the Thread_queue_Control size is
now 8 bytes, compared to 64 bytes in RTEMS 4.10 (other changes reduced
the size as well).

  • 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.
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   *  Make sure system is MP if this task is global
106   */
107
108  /*
109   *  Allocate the thread control block and -- if the task is global --
110   *  allocate a global object control block.
111   *
112   *  NOTE:  This routine does not use the combined allocate and open
113   *         global object routine because this results in a lack of
114   *         control over when memory is allocated and can be freed in
115   *         the event of an error.
116   */
117
118  the_thread = _RTEMS_tasks_Allocate();
119
120  if ( !the_thread ) {
121    _Objects_Allocator_unlock();
122    return RTEMS_TOO_MANY;
123  }
124
125#if defined(RTEMS_MULTIPROCESSING)
126  if ( is_global ) {
127    the_global_object = _Objects_MP_Allocate_global_object();
128
129    if ( _Objects_MP_Is_null_global_object( the_global_object ) ) {
130      _RTEMS_tasks_Free( the_thread );
131      _Objects_Allocator_unlock();
132      return RTEMS_TOO_MANY;
133    }
134  }
135#endif
136
137  /*
138   *  Initialize the core thread for this task.
139   */
140
141  status = _Thread_Initialize(
142    &_RTEMS_tasks_Information,
143    the_thread,
144    _Scheduler_Get_by_CPU_index( _SMP_Get_current_processor() ),
145    NULL,
146    stack_size,
147    is_fp,
148    core_priority,
149    _Modes_Is_preempt(initial_modes)   ? true : false,
150    _Modes_Is_timeslice(initial_modes) ?
151      THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE :
152      THREAD_CPU_BUDGET_ALGORITHM_NONE,
153    NULL,        /* no budget algorithm callout */
154    _Modes_Get_interrupt_level(initial_modes),
155    (Objects_Name) name
156  );
157
158  if ( !status ) {
159#if defined(RTEMS_MULTIPROCESSING)
160    if ( is_global )
161      _Objects_MP_Free_global_object( the_global_object );
162#endif
163    _RTEMS_tasks_Free( the_thread );
164    _Objects_Allocator_unlock();
165    return RTEMS_UNSATISFIED;
166  }
167
168  api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
169  asr = &api->Signal;
170
171  asr->is_enabled = _Modes_Is_asr_disabled(initial_modes) ? false : true;
172
173  *id = the_thread->Object.id;
174
175#if defined(RTEMS_MULTIPROCESSING)
176  the_thread->is_global = is_global;
177  if ( is_global ) {
178
179    _Objects_MP_Open(
180      &_RTEMS_tasks_Information.Objects,
181      the_global_object,
182      name,
183      the_thread->Object.id
184    );
185
186    _RTEMS_tasks_MP_Send_process_packet(
187      RTEMS_TASKS_MP_ANNOUNCE_CREATE,
188      the_thread->Object.id,
189      name
190    );
191
192   }
193#endif
194
195  _Objects_Allocator_unlock();
196  return RTEMS_SUCCESSFUL;
197}
Note: See TracBrowser for help on using the repository browser.