source: rtems/cpukit/score/src/object.c @ 98e4ebf5

4.104.114.84.95
Last change on this file since 98e4ebf5 was 98e4ebf5, checked in by Joel Sherrill <joel.sherrill@…>, on 10/08/97 at 15:45:54

Fixed typo in the pointer to the license terms.

  • Property mode set to 100644
File size: 11.8 KB
Line 
1/*
2 *  Object Handler
3 *
4 *
5 *  COPYRIGHT (c) 1989-1997.
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#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 =
125    (Objects_Control **) _Workspace_Allocate_or_fatal_error(
126      (maximum + 1) * sizeof(Objects_Control *)
127    );
128
129  /*
130   *  Allocate name table
131   */
132
133  name_length = maximum_name_length;
134
135  if (name_length & (OBJECTS_NAME_ALIGNMENT-1))
136    name_length = (name_length + OBJECTS_NAME_ALIGNMENT) &
137                  ~(OBJECTS_NAME_ALIGNMENT-1);
138
139  information->name_length = name_length;
140
141  name_area = (Objects_Name *)
142    _Workspace_Allocate_or_fatal_error( (maximum + 1) * name_length );
143  information->name_table = name_area;
144
145  /*
146   *  Initialize local pointer table
147   */
148
149  for ( index=0 ; index <= maximum ; index++ ) {
150     information->local_table[ index ] = NULL;
151  }
152
153  /*
154   *  Initialize objects .. if there are any
155   */
156
157  if ( maximum == 0 ) {
158    _Chain_Initialize_empty( &information->Inactive );
159  } else {
160
161    _Chain_Initialize(
162      &information->Inactive,
163      _Workspace_Allocate_or_fatal_error( maximum * size ),
164      maximum,
165      size
166    );
167
168    the_object = (Objects_Control *) information->Inactive.first;
169    for ( index=1; index <= maximum ; index++ ) {
170      the_object->id =
171        _Objects_Build_id( the_class, _Objects_Local_node, index );
172     
173      the_object->name = (void *) name_area;
174
175      name_area = _Addresses_Add_offset( name_area, name_length );
176
177      the_object = (Objects_Control *) the_object->Node.next;
178    }
179
180  }
181
182  /*
183   *  Take care of multiprocessing
184   */
185
186  if ( supports_global == TRUE && _System_state_Is_multiprocessing ) {
187
188    information->global_table =
189      (Chain_Control *) _Workspace_Allocate_or_fatal_error(
190        (_Objects_Maximum_nodes + 1) * sizeof(Chain_Control)
191      );
192
193    for ( index=1; index <= _Objects_Maximum_nodes ; index++ )
194      _Chain_Initialize_empty( &information->global_table[ index ] );
195   }
196   else
197     information->global_table = NULL;
198}
199
200/*PAGE
201 *
202 *  _Objects_Clear_name
203 *
204 *  XXX
205 */
206
207void _Objects_Clear_name(
208  void       *name,
209  unsigned32  length
210)
211{
212  unsigned32  index;
213  unsigned32  maximum = length / OBJECTS_NAME_ALIGNMENT;
214  unsigned32 *name_ptr = (unsigned32 *) name;
215
216  for ( index=0 ; index < maximum ; index++ )
217    *name_ptr++ = 0;
218}
219 
220/*PAGE
221 *
222 *  _Objects_Copy_name_string
223 *
224 *  XXX
225 */
226 
227void _Objects_Copy_name_string(
228  void       *source,
229  void       *destination
230)
231{
232  unsigned8 *source_p = (unsigned8 *) source;
233  unsigned8 *destination_p = (unsigned8 *) destination;
234 
235  do {
236    *destination_p++ = *source_p;
237  } while ( *source_p++ );
238}
239
240/*PAGE
241 *
242 *  _Objects_Copy_name_raw
243 *
244 *  XXX
245 */
246 
247void _Objects_Copy_name_raw(
248  void       *source,
249  void       *destination,
250  unsigned32  length
251)
252{
253  unsigned32 *source_p = (unsigned32 *) source;
254  unsigned32 *destination_p = (unsigned32 *) destination;
255  unsigned32  tmp_length = length / OBJECTS_NAME_ALIGNMENT;
256 
257  while ( tmp_length-- )
258    *destination_p++ = *source_p++;
259}
260
261/*PAGE
262 *
263 *  _Objects_Compare_name_string
264 *
265 *  XXX
266 */
267 
268boolean _Objects_Compare_name_string(
269  void       *name_1,
270  void       *name_2,
271  unsigned32  length
272)
273{
274  unsigned8 *name_1_p = (unsigned8 *) name_1;
275  unsigned8 *name_2_p = (unsigned8 *) name_2;
276  unsigned32 tmp_length = length;
277 
278  do {
279    if ( *name_1_p++ != *name_2_p++ )
280      return FALSE;
281    if ( !tmp_length-- )
282      return FALSE;
283  } while ( *name_1_p );
284
285  return TRUE;
286}
287 
288/*PAGE
289 *
290 *  _Objects_Compare_name_raw
291 *
292 *  XXX
293 */
294 
295boolean _Objects_Compare_name_raw(
296  void       *name_1,
297  void       *name_2,
298  unsigned32  length
299)
300{
301  unsigned32 *name_1_p = (unsigned32 *) name_1;
302  unsigned32 *name_2_p = (unsigned32 *) name_2;
303  unsigned32  tmp_length = length / OBJECTS_NAME_ALIGNMENT;
304 
305  while ( tmp_length-- )
306    if ( *name_1_p++ != *name_2_p++ )
307      return FALSE;
308
309  return TRUE;
310}
311
312
313/*PAGE
314 *
315 *  _Objects_Name_to_id
316 *
317 *  These kernel routines search the object table(s) for the given
318 *  object name and returns the associated object id.
319 *
320 *  Input parameters:
321 *    information - object information
322 *    name        - user defined object name
323 *    node        - node indentifier (0 indicates any node)
324 *    id          - address of return ID
325 *
326 *  Output parameters:
327 *    id                 - object id
328 *    OBJECTS_SUCCESSFUL - if successful
329 *    error code         - if unsuccessful
330 */
331
332Objects_Name_to_id_errors _Objects_Name_to_id(
333  Objects_Information *information,
334  Objects_Name         name,
335  unsigned32           node,
336  Objects_Id          *id
337)
338{
339  boolean                    search_local_node;
340  Objects_Control          **objects;
341  Objects_Control           *the_object;
342  unsigned32                 index;
343  unsigned32                 name_length;
344  Objects_Name_comparators   compare_them;
345
346  if ( name == 0 )
347    return OBJECTS_INVALID_NAME;
348
349  search_local_node = FALSE;
350
351  if ( information->maximum != 0 &&
352      (node == OBJECTS_SEARCH_ALL_NODES || node == OBJECTS_SEARCH_LOCAL_NODE ||
353      _Objects_Is_local_node( node ) ) )
354   search_local_node = TRUE;
355
356  if ( search_local_node ) {
357    objects = information->local_table;
358
359    name_length = information->name_length;
360
361    if ( information->is_string ) compare_them = _Objects_Compare_name_string;
362    else                          compare_them = _Objects_Compare_name_raw;
363
364    for ( index = 1; index <= information->maximum; index++ ) {
365
366      the_object = objects[ index ];
367
368      if ( !the_object || !the_object->name )
369        continue;
370
371      if ( (*compare_them)( name, the_object->name, name_length ) ) {
372        *id = the_object->id;
373        return OBJECTS_SUCCESSFUL;
374      }
375    }
376  }
377
378  if ( _Objects_Is_local_node( node ) || node == OBJECTS_SEARCH_LOCAL_NODE )
379    return OBJECTS_INVALID_NAME;
380
381  return ( _Objects_MP_Global_name_search( information, name, node, id ) );
382}
383
384/*PAGE
385 *
386 * _Objects_Get
387 *
388 * This routine sets the object pointer for the given
389 * object id based on the given object information structure.
390 *
391 * Input parameters:
392 *   information - pointer to entry in table for this class
393 *   id          - object id to search for
394 *   location    - address of where to store the location
395 *
396 * Output parameters:
397 *   returns - address of object if local
398 *   location    - one of the following:
399 *                  OBJECTS_ERROR  - invalid object ID
400 *                  OBJECTS_REMOTE - remote object
401 *                  OBJECTS_LOCAL  - local object
402 */
403
404Objects_Control *_Objects_Get(
405  Objects_Information *information,
406  Objects_Id           id,
407  Objects_Locations   *location
408)
409{
410  Objects_Control *the_object;
411  unsigned32       index;
412
413  index = id - information->minimum_id;
414
415  if ( information->maximum >= index ) {
416    _Thread_Disable_dispatch();
417    if ( (the_object = information->local_table[index+1]) != NULL ) {
418      *location = OBJECTS_LOCAL;
419      return( the_object );
420    }
421    _Thread_Enable_dispatch();
422    *location = OBJECTS_ERROR;
423    return( NULL );
424  }
425  *location = OBJECTS_ERROR;
426  _Objects_MP_Is_remote( information, id, location, &the_object );
427  return the_object;
428}
429
430
431/*PAGE
432 *
433 * _Objects_Get_next
434 *
435 * Like _Objects_Get, but considers the 'id' as a "hint" and
436 * finds next valid one after that point.
437 * Mostly used for monitor and debug traversal of an object.
438 *
439 * Input parameters:
440 *   information - pointer to entry in table for this class
441 *   id          - object id to search for
442 *   location    - address of where to store the location
443 *   next_id     - address to store next id to try
444 *
445 * Output parameters:
446 *   returns     - address of object if local
447 *   location    - one of the following:
448 *                  OBJECTS_ERROR  - invalid object ID
449 *                  OBJECTS_REMOTE - remote object
450 *                  OBJECTS_LOCAL  - local object
451 *   next_id     - will contain a reasonable "next" id to continue traversal
452 *
453 * NOTE:
454 *      assumes can add '1' to an id to get to next index.
455 */
456
457Objects_Control *
458_Objects_Get_next(
459    Objects_Information *information,
460    Objects_Id           id,
461    Objects_Locations   *location_p,
462    Objects_Id          *next_id_p
463)
464{
465    Objects_Control *object;
466    Objects_Id       next_id;
467   
468    if (_Objects_Get_index(id) == OBJECTS_ID_INITIAL_INDEX)
469        next_id = information->minimum_id;
470    else
471        next_id = id;
472
473    do {
474        /* walked off end of list? */
475        if (_Objects_Get_index(next_id) > information->maximum)
476        {
477            *location_p = OBJECTS_ERROR;
478            goto final;
479        }
480       
481        /* try to grab one */
482        object = _Objects_Get(information, next_id, location_p);
483
484        next_id++;
485
486    } while (*location_p != OBJECTS_LOCAL);
487
488    *next_id_p = next_id;
489    return object;
490
491final:
492    *next_id_p = OBJECTS_ID_FINAL;
493    return 0;
494}
495
496/*PAGE
497 *
498 *  _Objects_Get_information
499 *
500 *  XXX
501 */
502 
503Objects_Information *_Objects_Get_information(
504  Objects_Id  id
505)
506{
507  Objects_Classes  the_class;
508
509  the_class = _Objects_Get_class( id );
510
511  if ( !_Objects_Is_class_valid( the_class ) )
512    return NULL;
513
514  return _Objects_Information_table[ the_class ];
515}
516
Note: See TracBrowser for help on using the repository browser.