source: rtems/cpukit/score/src/object.c @ 7f6a24ab

4.104.114.84.95
Last change on this file since 7f6a24ab was 7f6a24ab, checked in by Joel Sherrill <joel.sherrill@…>, on Aug 28, 1995 at 3:30:29 PM

Added unused priority ceiling parameter to rtems_semaphore_create.

Rearranged code to created thread handler routines to initialize,
start, restart, and "close/delete" a thread.

Made internal threads their own object class. This now uses the
thread support routines for starting and initializing a thread.

Insured deleted tasks are freed to the Inactive pool associated with the
correct Information block.

Added an RTEMS API specific data area to the thread control block.

Beginnings of removing the word "rtems" from the core.

  • Property mode set to 100644
File size: 11.3 KB
Line 
1/*
2 *  Object Handler
3 *
4 *
5 *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
6 *  On-Line Applications Research Corporation (OAR).
7 *  All rights assigned to U.S. Government, 1994.
8 *
9 *  This material may be reproduced by or for the U.S. Government pursuant
10 *  to the copyright license under the clause at DFARS 252.227-7013.  This
11 *  notice must appear in all copies of this file and its derivatives.
12 *
13 *  $Id$
14 */
15
16#include <rtems/system.h>
17#include <rtems/chain.h>
18#include <rtems/config.h>
19#include <rtems/object.h>
20#include <rtems/objectmp.h>
21#include <rtems/thread.h>
22#include <rtems/wkspace.h>
23
24/*PAGE
25 *
26 *  _Objects_Handler_initialization
27 *
28 *  This routine initializes the object handler.
29 *
30 *  Input parameters:
31 *    node                   - local node
32 *    maximum_global_objects - number of configured global objects
33 *
34 *  Output parameters:  NONE
35 */
36
37void _Objects_Handler_initialization(
38  unsigned32 node,
39  unsigned32 maximum_global_objects
40)
41{
42  _Objects_Local_node = node;
43
44  _Objects_MP_Handler_initialization( maximum_global_objects );
45}
46
47/*PAGE
48 *
49 *  _Objects_Initialize_information
50 *
51 *  This routine initializes all object information related data structures.
52 *
53 *  Input parameters:
54 *    information     - object information table
55 *    the_class       - object class
56 *    supports_global - TRUE if this is a global object class
57 *    maximum         - maximum objects of this class
58 *    is_string       - TRUE if names for this object are strings
59 *    size            - size of this object's control block
60 *
61 *  Output parameters:  NONE
62 */
63
64void _Objects_Initialize_information(
65  Objects_Information *information,
66  Objects_Classes      the_class,
67  boolean              supports_global,
68  unsigned32           maximum,
69  unsigned32           size,
70  boolean              is_string,
71  unsigned32           maximum_name_length,
72  boolean              is_thread
73)
74{
75  unsigned32       minimum_index;
76  unsigned32       index;
77  Objects_Control *the_object;
78  unsigned32       name_length;
79  void            *name_area;
80
81  information->maximum   = maximum;
82  information->the_class = the_class; 
83  information->is_string = is_string; 
84  information->is_thread = is_thread; 
85
86  /*
87   *  Set the entry in the object information table.
88   */
89
90  _Objects_Information_table[ the_class ] = information;
91
92  /*
93   *  Calculate minimum and maximum Id's
94   */
95
96  if ( maximum == 0 ) minimum_index = 0;
97  else                minimum_index = 1;
98
99  information->minimum_id =
100    _Objects_Build_id( the_class, _Objects_Local_node, minimum_index );
101
102  information->maximum_id =
103    _Objects_Build_id( the_class, _Objects_Local_node, maximum );
104
105  /*
106   *  Allocate local pointer table
107   */
108
109  information->local_table = _Workspace_Allocate_or_fatal_error(
110    (maximum + 1) * sizeof(Objects_Control *)
111  );
112
113  /*
114   *  Allocate name table
115   */
116
117  name_length = maximum_name_length;
118
119  if (name_length & (OBJECTS_NAME_ALIGNMENT-1))
120    name_length = (name_length + OBJECTS_NAME_ALIGNMENT) & 
121                  ~(OBJECTS_NAME_ALIGNMENT-1);
122
123  information->name_length = name_length;
124
125  name_area = _Workspace_Allocate_or_fatal_error( (maximum + 1) * name_length );
126  information->name_table = name_area;
127
128  /*
129   *  Initialize local pointer table
130   */
131
132  for ( index=0 ; index <= maximum ; index++ ) {
133     information->local_table[ index ] = NULL;
134  }
135
136  /*
137   *  Initialize objects .. if there are any
138   */
139
140  if ( maximum == 0 ) {
141    _Chain_Initialize_empty( &information->Inactive );
142  } else {
143
144    _Chain_Initialize(
145      &information->Inactive,
146      _Workspace_Allocate_or_fatal_error( maximum * size ),
147      maximum,
148      size
149    );
150
151    the_object = (Objects_Control *) information->Inactive.first;
152    for ( index=1; index <= maximum ; index++ ) {
153      the_object->id = 
154        _Objects_Build_id( the_class, _Objects_Local_node, index );
155     
156      the_object->name = (void *) name_area;
157
158      name_area = _Addresses_Add_offset( name_area, name_length );
159
160      the_object = (Objects_Control *) the_object->Node.next;
161    }
162
163  }
164
165  /*
166   *  Take care of multiprocessing
167   */
168
169  if ( supports_global == TRUE && _Configuration_Is_multiprocessing() ) {
170
171    information->global_table = _Workspace_Allocate_or_fatal_error(
172      (_Configuration_MP_table->maximum_nodes + 1) * sizeof(Chain_Control)
173    );
174
175    for ( index=1;
176          index <= _Configuration_MP_table->maximum_nodes ;
177          index++ )
178      _Chain_Initialize_empty( &information->global_table[ index ] );
179   }
180   else
181     information->global_table = NULL;
182}
183
184/*PAGE
185 *
186 *  _Objects_Clear_name
187 *
188 *  XXX
189 */
190
191void _Objects_Clear_name(
192  void       *name,
193  unsigned32  length
194)
195{
196  unsigned32  index;
197  unsigned32  maximum = length / OBJECTS_NAME_ALIGNMENT;
198  unsigned32 *name_ptr = name;
199
200  for ( index=0 ; index < maximum ; index++ ) 
201    *name_ptr++ = 0;
202}
203 
204/*PAGE
205 *
206 *  _Objects_Copy_name_string
207 *
208 *  XXX
209 */
210 
211void _Objects_Copy_name_string(
212  void       *source,
213  void       *destination
214)
215{
216  unsigned8 *source_p = source;
217  unsigned8 *destination_p = destination;
218 
219  do {
220    *destination_p++ = *source_p;
221  } while ( *source_p++ );
222}
223
224/*PAGE
225 *
226 *  _Objects_Copy_name_raw
227 *
228 *  XXX
229 */
230 
231void _Objects_Copy_name_raw(
232  void       *source,
233  void       *destination,
234  unsigned32  length
235)
236{
237  unsigned32 *source_p = source;
238  unsigned32 *destination_p = destination;
239  unsigned32  tmp_length = length / OBJECTS_NAME_ALIGNMENT;
240 
241  while ( tmp_length-- )
242    *destination_p++ = *source_p++;
243}
244
245/*PAGE
246 *
247 *  _Objects_Compare_name_string
248 *
249 *  XXX
250 */
251 
252boolean _Objects_Compare_name_string(
253  void       *name_1,
254  void       *name_2,
255  unsigned32  length
256)
257{
258  unsigned8 *name_1_p = name_1;
259  unsigned8 *name_2_p = name_2;
260  unsigned32 tmp_length = length;
261 
262  do {
263    if ( *name_1_p++ != *name_2_p++ )
264      return FALSE;
265    if ( !tmp_length-- )
266      return FALSE;
267  } while ( *name_1_p );
268
269  return TRUE;
270}
271 
272/*PAGE
273 *
274 *  _Objects_Compare_name_raw
275 *
276 *  XXX
277 */
278 
279boolean _Objects_Compare_name_raw(
280  void       *name_1,
281  void       *name_2,
282  unsigned32  length
283)
284{
285  unsigned32 *name_1_p = name_1;
286  unsigned32 *name_2_p = name_2;
287  unsigned32  tmp_length = length / OBJECTS_NAME_ALIGNMENT;
288 
289  while ( tmp_length-- )
290    if ( *name_1_p++ != *name_2_p++ )
291      return FALSE;
292
293  return TRUE;
294}
295
296
297/*PAGE
298 *
299 *  _Objects_Name_to_id
300 *
301 *  These kernel routines search the object table(s) for the given
302 *  object name and returns the associated object id.
303 *
304 *  Input parameters:
305 *    information - object information
306 *    name        - user defined object name
307 *    node        - node indentifier (0 indicates any node)
308 *    id          - address of return ID
309 *
310 *  Output parameters:
311 *    obj_id     - object id
312 *    RTEMS_SUCCESSFUL - if successful
313 *    error code - if unsuccessful
314 */
315
316rtems_status_code _Objects_Name_to_id(
317  Objects_Information *information,
318  Objects_Name         name,
319  unsigned32           node,
320  Objects_Id          *id
321)
322{
323  boolean                    search_local_node;
324  Objects_Control          **objects;
325  Objects_Control           *the_object;
326  unsigned32                 index;
327  unsigned32                 name_length;
328  Objects_Name_comparators   compare_them;
329
330  if ( name == 0 )
331    return( RTEMS_INVALID_NAME );
332
333  search_local_node = FALSE;
334
335  if ( information->maximum != 0 &&
336      (node == RTEMS_SEARCH_ALL_NODES || node == RTEMS_SEARCH_LOCAL_NODE ||
337      _Objects_Is_local_node( node ) ) )
338   search_local_node = TRUE;
339
340  if ( search_local_node ) {
341    objects = information->local_table;
342
343    name_length = information->name_length;
344
345    if ( information->is_string ) compare_them = _Objects_Compare_name_string;
346    else                          compare_them = _Objects_Compare_name_raw;
347
348    for ( index = 1; index <= information->maximum; index++ ) {
349
350      the_object = objects[ index ];
351
352      if ( !the_object || !the_object->name )
353        continue;
354
355      if ( (*compare_them)( name, the_object->name, name_length ) ) {
356        *id = the_object->id;
357        return( RTEMS_SUCCESSFUL );
358      }
359    }
360  }
361
362  if ( _Objects_Is_local_node( node ) || node == RTEMS_SEARCH_LOCAL_NODE )
363    return( RTEMS_INVALID_NAME );
364
365  return ( _Objects_MP_Global_name_search( information, name, node, id ) );
366}
367
368/*PAGE
369 *
370 * _Objects_Get
371 *
372 * This routine sets the object pointer for the given
373 * object id based on the given object information structure.
374 *
375 * Input parameters:
376 *   information - pointer to entry in table for this class
377 *   id          - object id to search for
378 *   location    - address of where to store the location
379 *
380 * Output parameters:
381 *   returns - address of object if local
382 *   location    - one of the following:
383 *                  OBJECTS_ERROR  - invalid object ID
384 *                  OBJECTS_REMOTE - remote object
385 *                  OBJECTS_LOCAL  - local object
386 */
387
388Objects_Control *_Objects_Get(
389  Objects_Information *information,
390  Objects_Id           id,
391  Objects_Locations   *location
392)
393{
394  Objects_Control *the_object;
395  unsigned32       index;
396
397  index = id - information->minimum_id;
398
399  if ( information->maximum >= index ) {
400    _Thread_Disable_dispatch();
401    if ( (the_object = information->local_table[index+1]) != NULL ) {
402      *location = OBJECTS_LOCAL;
403      return( the_object );
404    }
405    _Thread_Enable_dispatch();
406    *location = OBJECTS_ERROR;
407    return( NULL );
408  }
409  *location = OBJECTS_ERROR;
410  _Objects_MP_Is_remote( information, id, location, &the_object );
411  return the_object;
412}
413
414
415/*PAGE
416 *
417 * _Objects_Get_next
418 *
419 * Like _Objects_Get, but considers the 'id' as a "hint" and
420 * finds next valid one after that point.
421 * Mostly used for monitor and debug traversal of an object.
422 *
423 * Input parameters:
424 *   information - pointer to entry in table for this class
425 *   id          - object id to search for
426 *   location    - address of where to store the location
427 *   next_id     - address to store next id to try
428 *
429 * Output parameters:
430 *   returns     - address of object if local
431 *   location    - one of the following:
432 *                  OBJECTS_ERROR  - invalid object ID
433 *                  OBJECTS_REMOTE - remote object
434 *                  OBJECTS_LOCAL  - local object
435 *   next_id     - will contain a reasonable "next" id to continue traversal
436 *
437 * NOTE:
438 *      assumes can add '1' to an id to get to next index.
439 */
440
441Objects_Control *
442_Objects_Get_next(
443    Objects_Information *information,
444    Objects_Id           id,
445    unsigned32          *location_p,
446    Objects_Id          *next_id_p
447)
448{
449    Objects_Control *object;
450    Objects_Id       next_id;
451   
452    if (rtems_get_index(id) == RTEMS_OBJECT_ID_INITIAL_INDEX)
453        next_id = information->minimum_id;
454    else
455        next_id = id;
456
457    do {
458        /* walked off end of list? */
459        if (rtems_get_index(next_id) > information->maximum)
460        {
461            *location_p = OBJECTS_ERROR;
462            goto final;
463        }
464       
465        /* try to grab one */
466        object = _Objects_Get(information, next_id, location_p);
467
468        next_id++;
469
470    } while (*location_p != OBJECTS_LOCAL);
471
472    *next_id_p = next_id;
473    return object;
474
475final:
476    *next_id_p = RTEMS_OBJECT_ID_FINAL;
477    return 0;
478}
479
480/*PAGE
481 *
482 *  _Objects_Get_information
483 *
484 *  XXX
485 */
486 
487Objects_Information *_Objects_Get_information(
488  Objects_Id  id
489)
490{
491  Objects_Classes  the_class;
492
493  the_class = rtems_get_class( id );
494
495  if ( !_Objects_Is_class_valid( the_class ) )
496    return NULL;
497
498  return _Objects_Information_table[ the_class ];
499}
500
Note: See TracBrowser for help on using the repository browser.