source: rtems/cpukit/score/src/object.c @ 3652ad35

4.104.114.84.95
Last change on this file since 3652ad35 was 3a4ae6c, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 11, 1995 at 7:35:39 PM

The word "RTEMS" almost completely removed from the core.

Configuration Table Template file added and all tests
modified to use this. All gvar.h and conftbl.h files
removed from test directories.

Configuration parameter maximum_devices added.

Core semaphore and mutex handlers added and RTEMS API Semaphore
Manager updated to reflect this.

Initialization sequence changed to invoke API specific initialization
routines. Initialization tasks table now owned by RTEMS Tasks Manager.

Added user extension for post-switch.

Utilized user extensions to implement API specific functionality
like signal dispatching.

Added extensions to the System Initialization Thread so that an
API can register a function to be invoked while the system
is being initialized. These are largely equivalent to the
pre-driver and post-driver hooks.

Added the Modules file oar-go32_p5, modified oar-go32, and modified
the file make/custom/go32.cfg to look at an environment varable which
determines what CPU model is being used.

All BSPs updated to reflect named devices and clock driver's IOCTL
used by the Shared Memory Driver. Also merged clock isr into
main file and removed ckisr.c where possible.

Updated spsize to reflect new and moved variables.

Makefiles for the executive source and include files updated to show
break down of files into Core, RTEMS API, and Neither.

Header and inline files installed into subdirectory based on whether
logically in the Core or a part of the RTEMS API.

  • 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/core/chain.h>
18#include <rtems/core/object.h>
19#include <rtems/objectmp.h>
20#include <rtems/core/thread.h>
21#include <rtems/core/wkspace.h>
22#include <rtems/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.