source: rtems/cpukit/score/src/object.c @ 56e0b88

4.104.114.84.95
Last change on this file since 56e0b88 was 56e0b88, checked in by Joel Sherrill <joel.sherrill@…>, on 09/18/96 at 20:50:58

corrected prototype of _Objects_Get_next

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