source: rtems/cpukit/rtems/src/tasks.c @ 0960fee

4.115
Last change on this file since 0960fee was 0960fee, checked in by Sebastian Huber <sebastian.huber@…>, on 05/07/14 at 15:53:48

rtems: Fix ASR SMP support

Initialize the ISR lock only once and destroy it properly.

  • Property mode set to 100644
File size: 6.0 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief RTEMS Task API Extensions
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/system.h>
22#include <rtems/config.h>
23#include <rtems/rtems/asrimpl.h>
24#include <rtems/rtems/eventimpl.h>
25#include <rtems/rtems/signalimpl.h>
26#include <rtems/rtems/status.h>
27#include <rtems/rtems/support.h>
28#include <rtems/rtems/modes.h>
29#include <rtems/rtems/tasksimpl.h>
30#include <rtems/posix/keyimpl.h>
31#include <rtems/score/stack.h>
32#include <rtems/score/threadimpl.h>
33#include <rtems/score/userextimpl.h>
34#include <rtems/score/wkspace.h>
35#include <rtems/score/apiext.h>
36
37/*
38 *  _RTEMS_tasks_Create_extension
39 *
40 *  This routine is an extension routine that is invoked as part
41 *  of creating any type of task or thread in the system.  If the
42 *  task is created via another API, then this routine is invoked
43 *  and this API given the opportunity to initialize its extension
44 *  area.
45 */
46
47static bool _RTEMS_tasks_Create_extension(
48  Thread_Control *executing,
49  Thread_Control *created
50)
51{
52  RTEMS_API_Control *api;
53  size_t             i;
54
55  api = created->API_Extensions[ THREAD_API_RTEMS ];
56
57  _Event_Initialize( &api->Event );
58  _Event_Initialize( &api->System_event );
59  _ASR_Create( &api->Signal );
60  _Thread_Action_initialize( &api->Signal_action, _Signal_Action_handler );
61#if !defined(RTEMS_SMP)
62  created->task_variables = NULL;
63#endif
64
65  if ( rtems_configuration_get_notepads_enabled() ) {
66    for (i=0; i < RTEMS_NUMBER_NOTEPADS; i++)
67      api->Notepads[i] = 0;
68  }
69
70  return true;
71}
72
73/*
74 *  _RTEMS_tasks_Start_extension
75 *
76 *  This extension routine is invoked when a task is started for the
77 *  first time.
78 */
79
80static void _RTEMS_tasks_Start_extension(
81  Thread_Control *executing,
82  Thread_Control *started
83)
84{
85  RTEMS_API_Control *api;
86
87  api = started->API_Extensions[ THREAD_API_RTEMS ];
88
89  _Event_Initialize( &api->Event );
90  _Event_Initialize( &api->System_event );
91}
92
93static void _RTEMS_tasks_Delete_extension(
94  Thread_Control *executing,
95  Thread_Control *deleted
96)
97{
98  RTEMS_API_Control *api;
99
100  api = deleted->API_Extensions[ THREAD_API_RTEMS ];
101
102  _ASR_Destroy( &api->Signal );
103}
104
105static void _RTEMS_tasks_Terminate_extension(
106  Thread_Control *executing
107)
108{
109  /*
110   *  Free per task variable memory
111   *
112   *  Per Task Variables are only enabled in uniprocessor configurations
113   */
114  #if !defined(RTEMS_SMP)
115    do {
116      rtems_task_variable_t *tvp, *next;
117
118      tvp = executing->task_variables;
119      executing->task_variables = NULL;
120      while (tvp) {
121        next = (rtems_task_variable_t *)tvp->next;
122        _RTEMS_Tasks_Invoke_task_variable_dtor( executing, tvp );
123        tvp = next;
124      }
125    } while (0);
126  #endif
127
128  /*
129   *  Run all the key destructors
130   */
131  _POSIX_Keys_Run_destructors( executing );
132}
133
134#if !defined(RTEMS_SMP)
135/*
136 *  _RTEMS_tasks_Switch_extension
137 *
138 *  This extension routine is invoked at each context switch.
139 *
140 *  @note Since this only needs to address per-task variables, it is
141 *        disabled entirely for SMP configurations.
142 */
143static void _RTEMS_tasks_Switch_extension(
144  Thread_Control *executing,
145  Thread_Control *heir
146)
147{
148  rtems_task_variable_t *tvp;
149
150  /*
151   *  Per Task Variables are only enabled in uniprocessor configurations
152   */
153
154  tvp = executing->task_variables;
155  while (tvp) {
156    tvp->tval = *tvp->ptr;
157    *tvp->ptr = tvp->gval;
158    tvp = (rtems_task_variable_t *)tvp->next;
159  }
160
161  tvp = heir->task_variables;
162  while (tvp) {
163    tvp->gval = *tvp->ptr;
164    *tvp->ptr = tvp->tval;
165    tvp = (rtems_task_variable_t *)tvp->next;
166  }
167}
168#define RTEMS_TASKS_SWITCH_EXTENSION _RTEMS_tasks_Switch_extension
169#else
170#define RTEMS_TASKS_SWITCH_EXTENSION NULL
171#endif
172
173API_extensions_Control _RTEMS_tasks_API_extensions = {
174  #if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API)
175    .predriver_hook = NULL,
176  #endif
177  .postdriver_hook = _RTEMS_tasks_Initialize_user_tasks
178};
179
180User_extensions_Control _RTEMS_tasks_User_extensions = {
181  { NULL, NULL },
182  { { NULL, NULL }, RTEMS_TASKS_SWITCH_EXTENSION },
183  { _RTEMS_tasks_Create_extension,            /* create */
184    _RTEMS_tasks_Start_extension,             /* start */
185    _RTEMS_tasks_Start_extension,             /* restart */
186    _RTEMS_tasks_Delete_extension,            /* delete */
187    RTEMS_TASKS_SWITCH_EXTENSION,             /* switch */
188    NULL,                                     /* begin */
189    NULL,                                     /* exitted */
190    NULL,                                     /* fatal */
191    _RTEMS_tasks_Terminate_extension          /* terminate */
192  }
193};
194
195void _RTEMS_tasks_Manager_initialization(void)
196{
197  _Objects_Initialize_information(
198    &_RTEMS_tasks_Information, /* object information table */
199    OBJECTS_CLASSIC_API,       /* object API */
200    OBJECTS_RTEMS_TASKS,       /* object class */
201    Configuration_RTEMS_API.maximum_tasks,
202                               /* maximum objects of this class */
203    _Thread_Control_size,      /* size of this object's control block */
204    false,                     /* true if the name is a string */
205    RTEMS_MAXIMUM_NAME_LENGTH  /* maximum length of an object name */
206#if defined(RTEMS_MULTIPROCESSING)
207    ,
208    true,                      /* true if this is a global object class */
209    NULL                       /* Proxy extraction support callout */
210#endif
211  );
212
213  /*
214   *  Add all the extensions for this API
215   */
216
217  _User_extensions_Add_API_set( &_RTEMS_tasks_User_extensions );
218
219  _API_extensions_Add( &_RTEMS_tasks_API_extensions );
220
221  /*
222   *  Register the MP Process Packet routine.
223   */
224
225#if defined(RTEMS_MULTIPROCESSING)
226  _MPCI_Register_packet_processor(
227    MP_PACKET_TASKS,
228    _RTEMS_tasks_MP_Process_packet
229  );
230#endif
231
232}
233
234void _RTEMS_tasks_Initialize_user_tasks( void )
235{
236  if ( _RTEMS_tasks_Initialize_user_tasks_p )
237    (*_RTEMS_tasks_Initialize_user_tasks_p)();
238}
Note: See TracBrowser for help on using the repository browser.