source: rtems/cpukit/score/src/object.c @ 3235ad9

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

Support for variable length names added to Object Handler. This supports
both fixed length "raw" names and strings from the API's point of view.

Both inline and macro implementations were tested.

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