source: rtems/cpukit/score/src/object.c @ 5e9b32b

4.104.114.84.95
Last change on this file since 5e9b32b was 5e9b32b, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 26, 1995 at 7:27:15 PM

posix support initially added

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