source: rtems/cpukit/score/src/object.c @ 97e2729d

4.104.114.84.95
Last change on this file since 97e2729d was 97e2729d, checked in by Joel Sherrill <joel.sherrill@…>, on 11/23/98 at 17:38:09

Added --disable-multiprocessing flag and modified a lot of files to make
it work.

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