source: rtems/c/src/exec/score/src/object.c @ 5250ff39

4.104.114.84.9
Last change on this file since 5250ff39 was 5250ff39, checked in by Joel Sherrill <joel.sherrill@…>, on Aug 23, 1995 at 9:06:31 PM

Moved _Thread_Information -> _RTEMS_tasks_Information.

Added a table of object information control blocks.

Modified _Thread_Get so it looks up a thread regardless of which
thread management "entity" (manager, internal, etc) actually "owns" it.

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