source: rtems/c/src/exec/rtems/src/tasks.c @ 0ab65474

4.104.114.84.95
Last change on this file since 0ab65474 was c941a98, checked in by Joel Sherrill <joel.sherrill@…>, on 01/21/00 at 15:07:55

Patch from Eric Norum <eric@…> to implement this:

I'd like to propose a change to RTEMS task variables that I think would
make them more useful. I think that it is early enough in their
existence to still make changes to their API.

1) Change type from int' to void *'.
2) Add extra argument to task_variable_add -- if non-NULL, a pointer to
a `destructor' function to be called when the task exits. This function
would be called with that task's value of the task variable as its
argument. In many cases, the dtor' function could be free'.

rtems_status_code rtems_task_variable_add (

rtems_id tid, void ptr, void (*dtor)(void *));

rtems_status_code rtems_task_variable_delete (rtems_id tid, void ptr);

This would be all we'd need to cleanly and efficiently support C++
per-thread exception information without dragging in all that POSIX API
stuff.

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/*
2 *  RTEMS Task Manager
3 *
4 *
5 *  COPYRIGHT (c) 1989-1999.
6 *  On-Line Applications Research Corporation (OAR).
7 *
8 *  The license and distribution terms for this file may be
9 *  found in the file LICENSE in this distribution or at
10 *  http://www.OARcorp.com/rtems/license.html.
11 *
12 *  $Id$
13 */
14
15#include <rtems/system.h>
16#include <rtems/rtems/status.h>
17#include <rtems/rtems/support.h>
18#include <rtems/rtems/modes.h>
19#include <rtems/score/object.h>
20#include <rtems/score/stack.h>
21#include <rtems/score/states.h>
22#include <rtems/rtems/tasks.h>
23#include <rtems/score/thread.h>
24#include <rtems/score/threadq.h>
25#include <rtems/score/tod.h>
26#include <rtems/score/userext.h>
27#include <rtems/score/wkspace.h>
28#include <rtems/score/apiext.h>
29#include <rtems/score/sysstate.h>
30
31/*PAGE
32 *
33 *  _RTEMS_tasks_Create_extension
34 *
35 *  This routine is an extension routine that is invoked as part
36 *  of creating any type of task or thread in the system.  If the
37 *  task is created via another API, then this routine is invoked
38 *  and this API given the opportunity to initialize its extension
39 *  area.
40 */
41
42boolean _RTEMS_tasks_Create_extension(
43  Thread_Control *executing,
44  Thread_Control *created
45)
46{
47  RTEMS_API_Control *api;
48
49  api = _Workspace_Allocate( sizeof( RTEMS_API_Control ) );
50
51  if ( !api )
52    return FALSE;
53
54  created->API_Extensions[ THREAD_API_RTEMS ] = api;
55 
56  api->pending_events = EVENT_SETS_NONE_PENDING;
57  _ASR_Initialize( &api->Signal );
58  created->task_variables = NULL;
59  return TRUE;
60}
61
62/*PAGE
63 *
64 *  _RTEMS_tasks_Start_extension
65 *
66 *  This extension routine is invoked when a task is started for the
67 *  first time.
68 */
69 
70User_extensions_routine _RTEMS_tasks_Start_extension(
71  Thread_Control *executing,
72  Thread_Control *started
73)
74{
75  RTEMS_API_Control *api;
76
77  api = started->API_Extensions[ THREAD_API_RTEMS ];
78 
79  api->pending_events = EVENT_SETS_NONE_PENDING;
80
81  _ASR_Initialize( &api->Signal );
82}
83
84/*PAGE
85 *
86 *  _RTEMS_tasks_Delete_extension
87 *
88 *  This extension routine is invoked when a task is deleted.
89 */
90 
91User_extensions_routine _RTEMS_tasks_Delete_extension(
92  Thread_Control *executing,
93  Thread_Control *deleted
94)
95{
96  rtems_task_variable_t *tvp, *next;
97
98  /*
99   *  Free per task variable memory
100   */
101
102  tvp = deleted->task_variables;
103  deleted->task_variables = NULL;
104  while (tvp) {
105    next = tvp->next;
106    if  (tvp->dtor)
107        (*tvp->dtor)( tvp->ptr );
108    _Workspace_Free( tvp );
109    tvp = next;
110  }
111
112  /*
113   *  Free API specific memory
114   */
115
116  (void) _Workspace_Free( deleted->API_Extensions[ THREAD_API_RTEMS ] );
117  deleted->API_Extensions[ THREAD_API_RTEMS ] = NULL;
118}
119
120/*PAGE
121 *
122 *  _RTEMS_tasks_Switch_extension
123 *
124 *  This extension routine is invoked at each context switch.
125 */
126 
127void _RTEMS_tasks_Switch_extension(
128  Thread_Control *executing,
129  Thread_Control *heir
130)
131{
132  rtems_task_variable_t *tvp;
133
134  /*
135   *  Per Task Variables
136   */
137
138  tvp = executing->task_variables;
139  while (tvp) {
140    tvp->var = *tvp->ptr;
141    tvp = tvp->next;
142  }
143
144  tvp = heir->task_variables;
145  while (tvp) {
146    *tvp->ptr = tvp->var;
147    tvp = tvp->next;
148  }
149}
150
151/*PAGE
152 *
153 *  _RTEMS_tasks_Post_switch_extension
154 *
155 *  This extension routine is invoked at each context switch.
156 */
157 
158void _RTEMS_tasks_Post_switch_extension(
159  Thread_Control *executing
160)
161{
162  ISR_Level          level;
163  RTEMS_API_Control *api;
164  ASR_Information   *asr;
165  rtems_signal_set   signal_set;
166  Modes_Control      prev_mode;
167
168  api = executing->API_Extensions[ THREAD_API_RTEMS ];
169
170  /*
171   *  Signal Processing
172   */
173
174  asr = &api->Signal;
175 
176  _ISR_Disable( level );
177    signal_set = asr->signals_posted;
178    asr->signals_posted = 0;
179  _ISR_Enable( level );
180 
181 
182  if ( !signal_set ) /* similar to _ASR_Are_signals_pending( asr ) */
183    return;
184 
185  asr->nest_level += 1;
186  rtems_task_mode( asr->mode_set, RTEMS_ALL_MODE_MASKS, &prev_mode );
187 
188  (*asr->handler)( signal_set );
189
190  asr->nest_level -= 1;
191  rtems_task_mode( prev_mode, RTEMS_ALL_MODE_MASKS, &prev_mode );
192
193}
194
195API_extensions_Control _RTEMS_tasks_API_extensions = {
196  { NULL, NULL },
197  NULL,                                     /* predriver */
198  _RTEMS_tasks_Initialize_user_tasks,       /* postdriver */
199  _RTEMS_tasks_Post_switch_extension        /* post switch */
200};
201
202User_extensions_Control _RTEMS_tasks_User_extensions = {
203  { NULL, NULL },
204  { _RTEMS_tasks_Create_extension,            /* create */
205    _RTEMS_tasks_Start_extension,             /* start */
206    _RTEMS_tasks_Start_extension,             /* restart */
207    _RTEMS_tasks_Delete_extension,            /* delete */
208    _RTEMS_tasks_Switch_extension,            /* switch */
209    NULL,                                     /* begin */
210    NULL,                                     /* exitted */
211    NULL                                      /* fatal */
212  }
213};
214
215/*PAGE
216 *
217 *  _RTEMS_tasks_Manager_initialization
218 *
219 *  This routine initializes all Task Manager related data structures.
220 *
221 *  Input parameters:
222 *    maximum_tasks       - number of tasks to initialize
223 *
224 *  Output parameters:  NONE
225 */
226
227void _RTEMS_tasks_Manager_initialization(
228  unsigned32                        maximum_tasks,
229  unsigned32                        number_of_initialization_tasks,
230  rtems_initialization_tasks_table *user_tasks
231)
232{
233
234  _RTEMS_tasks_Number_of_initialization_tasks = number_of_initialization_tasks;
235  _RTEMS_tasks_User_initialization_tasks = user_tasks;
236
237  /*
238   *  There may not be any RTEMS initialization tasks configured.
239   */
240
241#if 0
242  if ( user_tasks == NULL || number_of_initialization_tasks == 0 )
243    _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, TRUE, RTEMS_TOO_MANY );
244#endif
245
246  _Objects_Initialize_information(
247    &_RTEMS_tasks_Information,
248    OBJECTS_RTEMS_TASKS,
249    TRUE,
250    maximum_tasks,
251    sizeof( Thread_Control ),
252    FALSE,
253    RTEMS_MAXIMUM_NAME_LENGTH,
254    TRUE
255  );
256
257  /*
258   *  Add all the extensions for this API
259   */
260
261  _User_extensions_Add_API_set( &_RTEMS_tasks_User_extensions );
262
263  _API_extensions_Add( &_RTEMS_tasks_API_extensions );
264
265  /*
266   *  Register the MP Process Packet routine.
267   */
268
269#if defined(RTEMS_MULTIPROCESSING)
270  _MPCI_Register_packet_processor(
271    MP_PACKET_TASKS,
272    _RTEMS_tasks_MP_Process_packet
273  );
274#endif
275
276}
277
Note: See TracBrowser for help on using the repository browser.