Changeset 317a5b5 in rtems


Ignore:
Timestamp:
Nov 2, 1999, 7:43:52 PM (20 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
b568ccb
Parents:
811fae1
Message:

Split object.c into multiple files.

Files:
30 added
3 edited

Legend:

Unmodified
Added
Removed
  • c/src/exec/score/src/Makefile.in

    r811fae1 r317a5b5  
    2323MP_C_PIECES = $(MP_C_PIECES_$(HAS_MP)_V)
    2424
     25OBJECT_C_PIECES = object objectallocate objectallocatebyindex \
     26    objectclearname objectcomparenameraw objectcomparenamestring \
     27    objectcopynameraw objectcopynamestring objectextendinformation \
     28    objectfree objectget objectgetbyindex objectgetnext \
     29    objectinitializeinformation objectnametoid objectshrinkinformation
     30
    2531THREAD_C_PIECES = thread threadchangepriority threadclearstate threadclose \
    2632    threadcreateidle threaddelayended threaddispatch threadevaluatemode \
     
    3339# C and C++ source names, if any, go here -- minus the .c or .cc
    3440C_PIECES = apiext chain coremsg coremutex coresem coretod heap interr isr \
    35     object $(THREAD_C_PIECES) threadq userext watchdog wkspace \
     41    $(OBJECT_C_PIECES) $(THREAD_C_PIECES) threadq userext watchdog wkspace \
    3642    $(MP_C_PIECES)
    3743C_FILES = $(C_PIECES:%=%.c)
  • c/src/exec/score/src/object.c

    r811fae1 r317a5b5  
    6464#endif
    6565}
    66 
    67 /*PAGE
    68  *
    69  *  _Objects_Extend_information
    70  *
    71  *  This routine extends all object information related data structures.
    72  *
    73  *  Input parameters:
    74  *    information     - object information table
    75  *
    76  *  Output parameters:  NONE
    77  */
    78 
    79 void _Objects_Extend_information(
    80   Objects_Information *information
    81 )
    82 {
    83   Objects_Control  *the_object;
    84   void             *name_area;
    85   Chain_Control     Inactive;
    86   unsigned32        block_count;
    87   unsigned32        block;
    88   unsigned32        index_base;
    89   unsigned32        minimum_index;
    90   unsigned32        index;
    91 
    92   /*
    93    *  Search for a free block of indexes. The block variable ends up set
    94    *  to block_count + 1 if the table needs to be extended.
    95    */
    96 
    97   minimum_index = _Objects_Get_index( information->minimum_id );
    98   index_base    = minimum_index;
    99   block         = 0;
    100  
    101   if ( information->maximum < minimum_index )
    102     block_count = 0;
    103   else {
    104     block_count = information->maximum / information->allocation_size;
    105  
    106     for ( ; block < block_count; block++ ) {
    107       if ( information->object_blocks[ block ] == NULL )
    108         break;
    109       else
    110         index_base += information->allocation_size;
    111     }
    112   }
    113 
    114   /*
    115    *  If the index_base is the maximum we need to grow the tables.
    116    */
    117 
    118   if (index_base >= information->maximum ) {
    119     ISR_Level         level;
    120     void            **object_blocks;
    121     Objects_Name     *name_table;
    122     unsigned32       *inactive_per_block;
    123     Objects_Control **local_table;
    124     unsigned32        maximum;
    125     void             *old_tables;   
    126    
    127     /*
    128      *  Growing the tables means allocating a new area, doing a copy and
    129      *  updating the information table.
    130      *
    131      *  If the maximum is minimum we do not have a table to copy. First
    132      *  time through.
    133      *
    134      *  The allocation has :
    135      *
    136      *      void            *objects[block_count];
    137      *      unsigned32       inactive_count[block_count];
    138      *      Objects_Name    *name_table[block_count];
    139      *      Objects_Control *local_table[maximum];
    140      *
    141      *  This is the order in memory. Watch changing the order. See the memcpy
    142      *  below.
    143      */
    144 
    145     /*
    146      *  Up the block count and maximum
    147      */
    148 
    149     block_count++;
    150    
    151     maximum = information->maximum + information->allocation_size;
    152 
    153     /*
    154      *  Allocate the tables and break it up.
    155      */
    156    
    157     if ( information->auto_extend ) {
    158       object_blocks = (void**)
    159         _Workspace_Allocate(
    160           block_count *
    161              (sizeof(void *) + sizeof(unsigned32) + sizeof(Objects_Name *)) +
    162           ((maximum + minimum_index) * sizeof(Objects_Control *))
    163           );
    164 
    165       if ( !object_blocks )
    166         return;
    167     }
    168     else {
    169       object_blocks = (void**)
    170         _Workspace_Allocate_or_fatal_error(
    171           block_count *
    172              (sizeof(void *) + sizeof(unsigned32) + sizeof(Objects_Name *)) +
    173           ((maximum + minimum_index) * sizeof(Objects_Control *))
    174         );
    175     }
    176 
    177     /*
    178      *  Break the block into the various sections.
    179      *
    180      */
    181      
    182     inactive_per_block = (unsigned32 *) _Addresses_Add_offset(
    183         object_blocks, block_count * sizeof(void*) );
    184     name_table = (Objects_Name *) _Addresses_Add_offset(
    185         inactive_per_block, block_count * sizeof(unsigned32) );
    186     local_table = (Objects_Control **) _Addresses_Add_offset(
    187         name_table, block_count * sizeof(Objects_Name *) );
    188    
    189     /*
    190      *  Take the block count down. Saves all the (block_count - 1)
    191      *  in the copies.
    192      */
    193 
    194     block_count--;
    195    
    196     if ( information->maximum > minimum_index ) {
    197      
    198       /*
    199        *  Copy each section of the table over. This has to be performed as
    200        *  separate parts as size of each block has changed.
    201        */
    202    
    203       memcpy( object_blocks,
    204               information->object_blocks,
    205               block_count * sizeof(void*) );
    206       memcpy( inactive_per_block,
    207               information->inactive_per_block,
    208               block_count * sizeof(unsigned32) );
    209       memcpy( name_table,
    210               information->name_table,
    211               block_count * sizeof(Objects_Name *) );
    212       memcpy( local_table,
    213               information->local_table,
    214               (information->maximum + minimum_index) * sizeof(Objects_Control *) );
    215     }
    216     else {
    217 
    218       /*
    219        *  Deal with the special case of the 0 to minimum_index
    220        */
    221       for ( index = 0; index < minimum_index; index++ ) {
    222         local_table[ index ] = NULL;
    223       }
    224     }
    225    
    226     /*
    227      *  Initialise the new entries in the table.
    228      */
    229    
    230     object_blocks[block_count] = NULL;
    231     inactive_per_block[block_count] = 0;
    232     name_table[block_count] = NULL;
    233 
    234     for ( index=index_base ;
    235           index < ( information->allocation_size + index_base );
    236           index++ ) {
    237       local_table[ index ] = NULL;
    238     }
    239    
    240     _ISR_Disable( level );
    241 
    242     old_tables = information->object_blocks;
    243    
    244     information->object_blocks = object_blocks;
    245     information->inactive_per_block = inactive_per_block;
    246     information->name_table = name_table;
    247     information->local_table = local_table;
    248     information->maximum = maximum;
    249     information->maximum_id =
    250       _Objects_Build_id(
    251         information->the_class, _Objects_Local_node, information->maximum
    252       );
    253 
    254     _ISR_Enable( level );
    255 
    256     if ( old_tables )
    257       _Workspace_Free( old_tables );
    258    
    259     block_count++;
    260   }
    261            
    262   /*
    263    *  Allocate the name table, and the objects
    264    */
    265 
    266   if ( information->auto_extend ) {
    267     information->object_blocks[ block ] =
    268       _Workspace_Allocate(
    269         (information->allocation_size * information->name_length) +
    270         (information->allocation_size * information->size)
    271       );
    272 
    273     if ( !information->object_blocks[ block ] )
    274       return;
    275   }
    276   else {
    277     information->object_blocks[ block ] =
    278       _Workspace_Allocate_or_fatal_error(
    279         (information->allocation_size * information->name_length) +
    280         (information->allocation_size * information->size)
    281       );
    282   }
    283  
    284   name_area = (Objects_Name *) _Addresses_Add_offset(
    285     information->object_blocks[ block ],
    286     (information->allocation_size * information->size)
    287   );
    288   information->name_table[ block ] = name_area;
    289 
    290   /*
    291    *  Initialize objects .. add to a local chain first.
    292    */
    293 
    294   _Chain_Initialize(
    295     &Inactive,
    296     information->object_blocks[ block ],
    297     information->allocation_size,
    298     information->size
    299   );
    300 
    301   /*
    302    *  Move from the local chain, initialise, then append to the inactive chain
    303    */
    304 
    305   index = index_base;
    306  
    307   while ( (the_object = (Objects_Control *) _Chain_Get( &Inactive ) ) != NULL ) {
    308    
    309     the_object->id =
    310       _Objects_Build_id(
    311         information->the_class, _Objects_Local_node, index
    312       );
    313      
    314     the_object->name = (void *) name_area;
    315 
    316     name_area = _Addresses_Add_offset( name_area, information->name_length );
    317 
    318     _Chain_Append( &information->Inactive, &the_object->Node );
    319 
    320     index++;
    321   }
    322  
    323   information->inactive_per_block[ block ] = information->allocation_size;
    324   information->inactive += information->allocation_size;
    325 }
    326 
    327 /*PAGE
    328  *
    329  *  _Objects_Shrink_information
    330  *
    331  *  This routine shrinks object information related data structures.
    332  *  The object's name and object space are released. The local_table
    333  *  etc block does not shrink. The InActive list needs to be scanned
    334  *  to find the objects are remove them.
    335  *  Input parameters:
    336  *    information     - object information table
    337  *    the_block       - the block to remove
    338  *
    339  *  Output parameters:  NONE
    340  */
    341 
    342 void _Objects_Shrink_information(
    343   Objects_Information *information
    344 )
    345 {
    346   Objects_Control  *the_object;
    347   Objects_Control  *extract_me;
    348   unsigned32        block_count;
    349   unsigned32        block;
    350   unsigned32        index_base;
    351   unsigned32        index;
    352 
    353   /*
    354    * Search the list to find block or chunnk with all objects inactive.
    355    */
    356 
    357   index_base = _Objects_Get_index( information->minimum_id );
    358   block_count = ( information->maximum - index_base ) / information->allocation_size;
    359  
    360   for ( block = 0; block < block_count; block++ ) {
    361     if ( information->inactive_per_block[ block ] == information->allocation_size ) {
    362 
    363       /*
    364        * XXX - Not to sure how to use a chain where you need to iterate and
    365        *       and remove elements.
    366        */
    367      
    368       the_object = (Objects_Control *) information->Inactive.first;
    369 
    370       /*
    371        *  Assume the Inactive chain is never empty at this point
    372        */
    373 
    374       do {
    375         index = _Objects_Get_index( the_object->id );
    376 
    377         if ((index >= index_base) &&
    378             (index < (index_base + information->allocation_size))) {
    379          
    380           /*
    381            *  Get the next node before the node is extracted
    382            */
    383          
    384           extract_me = the_object;
    385 
    386           if ( !_Chain_Is_last( &the_object->Node ) )
    387             the_object = (Objects_Control *) the_object->Node.next;
    388           else
    389             the_object = NULL;
    390          
    391           _Chain_Extract( &extract_me->Node );
    392         }
    393         else {
    394           the_object = (Objects_Control *) the_object->Node.next;
    395         }
    396       }
    397       while ( the_object && !_Chain_Is_last( &the_object->Node ) );
    398 
    399       /*
    400        *  Free the memory and reset the structures in the object' information
    401        */
    402 
    403       _Workspace_Free( information->object_blocks[ block ] );
    404       information->name_table[ block ] = NULL;
    405       information->object_blocks[ block ] = NULL;
    406       information->inactive_per_block[ block ] = 0;
    407 
    408       information->inactive -= information->allocation_size;
    409      
    410       return;
    411     }
    412    
    413     index_base += information->allocation_size;
    414   }
    415 }
    416 
    417 /*PAGE
    418  *
    419  *  _Objects_Initialize_information
    420  *
    421  *  This routine initializes all object information related data structures.
    422  *
    423  *  Input parameters:
    424  *    information         - object information table
    425  *    the_class           - object class
    426  *    supports_global     - TRUE if this is a global object class
    427  *    maximum             - maximum objects of this class
    428  *    size                - size of this object's control block
    429  *    is_string           - TRUE if names for this object are strings
    430  *    maximum_name_length - maximum length of each object's name
    431  *    is_thread           - TRUE if this class is threads
    432  *
    433  *  Output parameters:  NONE
    434  */
    435 
    436 void _Objects_Initialize_information(
    437   Objects_Information *information,
    438   Objects_Classes      the_class,
    439   boolean              supports_global,
    440   unsigned32           maximum,
    441   unsigned32           size,
    442   boolean              is_string,
    443   unsigned32           maximum_name_length,
    444   boolean              is_thread
    445 )
    446 {
    447   static Objects_Control *null_local_table = NULL;
    448  
    449   unsigned32       minimum_index;
    450   unsigned32       index;
    451   unsigned32       name_length;
    452 
    453   information->the_class          = the_class;
    454   information->is_string          = is_string;
    455   information->is_thread          = is_thread;
    456  
    457   information->local_table        = 0;
    458   information->name_table         = 0;
    459   information->inactive_per_block = 0;
    460   information->object_blocks      = 0;
    461  
    462   information->inactive           = 0;
    463  
    464   /*
    465    *  Set the entry in the object information table.
    466    */
    467 
    468   _Objects_Information_table[ the_class ] = information;
    469 
    470   /*
    471    *  Set the size of the object
    472    */
    473 
    474   information->size = size;
    475  
    476   /*
    477    *  Are we operating in unlimited, or auto-extend mode
    478    */
    479 
    480   information->auto_extend = (maximum & OBJECTS_UNLIMITED_OBJECTS) ? TRUE : FALSE;
    481   maximum                 &= ~OBJECTS_UNLIMITED_OBJECTS;
    482  
    483   /*
    484    *  The allocation unit is the maximum value
    485    */
    486 
    487   information->allocation_size = maximum;
    488 
    489   /*
    490    *  Provide a null local table entry for the case of any empty table.
    491    */
    492 
    493   information->local_table = &null_local_table;
    494 
    495   /*
    496    *  Calculate minimum and maximum Id's
    497    */
    498 
    499   if ( maximum == 0 ) minimum_index = 0;
    500   else                minimum_index = 1;
    501 
    502   information->minimum_id =
    503     _Objects_Build_id( the_class, _Objects_Local_node, minimum_index );
    504 
    505   /*
    506    *  Calculate the maximum name length
    507    */
    508 
    509   name_length = maximum_name_length;
    510 
    511   if ( name_length & (OBJECTS_NAME_ALIGNMENT-1) )
    512     name_length = (name_length + OBJECTS_NAME_ALIGNMENT) &
    513                   ~(OBJECTS_NAME_ALIGNMENT-1);
    514 
    515   information->name_length = name_length;
    516 
    517   _Chain_Initialize_empty( &information->Inactive );
    518    
    519   /*
    520    *  Initialize objects .. if there are any
    521    */
    522 
    523   if ( maximum ) {
    524 
    525     /*
    526      *  Reset the maximum value. It will be updated when the information is
    527      *  extended.
    528      */
    529    
    530     information->maximum = 0;
    531    
    532     /*
    533      *  Always have the maximum size available so the current performance
    534      *  figures are create are met.  If the user moves past the maximum
    535      *  number then a performance hit is taken.
    536      */
    537    
    538     _Objects_Extend_information( information );
    539    
    540   }
    541 
    542   /*
    543    *  Take care of multiprocessing
    544    */
    545 
    546   if ( supports_global == TRUE && _System_state_Is_multiprocessing ) {
    547 
    548     information->global_table =
    549       (Chain_Control *) _Workspace_Allocate_or_fatal_error(
    550         (_Objects_Maximum_nodes + 1) * sizeof(Chain_Control)
    551       );
    552 
    553     for ( index=1; index <= _Objects_Maximum_nodes ; index++ )
    554       _Chain_Initialize_empty( &information->global_table[ index ] );
    555    }
    556    else
    557      information->global_table = NULL;
    558 }
    559 
    560 /*PAGE
    561  *
    562  *  _Objects_Allocate
    563  *
    564  *  DESCRIPTION:
    565  *
    566  *  This function allocates a object control block from
    567  *  the inactive chain of free object control blocks.
    568  */
    569 
    570 Objects_Control *_Objects_Allocate(
    571   Objects_Information *information
    572 )
    573 {
    574   Objects_Control *the_object = 
    575     (Objects_Control *) _Chain_Get( &information->Inactive );
    576 
    577   if ( information->auto_extend ) {
    578     /*
    579      *  If the list is empty then we are out of objects and need to
    580      *  extend information base.
    581      */
    582  
    583     if ( !the_object ) {
    584       _Objects_Extend_information( information );
    585       the_object =  (Objects_Control *) _Chain_Get( &information->Inactive );
    586     }
    587  
    588     if ( the_object ) {
    589       unsigned32 block;
    590    
    591       block = _Objects_Get_index( the_object->id ) -
    592               _Objects_Get_index( information->minimum_id );
    593       block /= information->allocation_size;
    594      
    595       information->inactive_per_block[ block ]--;
    596       information->inactive--;
    597     }
    598   }
    599  
    600   return the_object;
    601 }
    602 
    603 /*PAGE
    604  *
    605  *  _Objects_Allocate_by_index
    606  *
    607  *  DESCRIPTION:
    608  *
    609  *  This function allocates the object control block
    610  *  specified by the index from the inactive chain of
    611  *  free object control blocks.
    612  */
    613 
    614 Objects_Control *_Objects_Allocate_by_index(
    615   Objects_Information *information,
    616   unsigned32           index,
    617   unsigned32           sizeof_control
    618 )
    619 {
    620   Objects_Control *the_object;
    621   void            *p;
    622 
    623   if ( index && information->maximum >= index ) {
    624     the_object = _Objects_Get_local_object( information, index );
    625     if ( the_object )
    626       return NULL;
    627 
    628     /* XXX
    629      *  This whole section of code needs to be addressed.
    630      *    +  The 0 should be dealt with more properly so we can autoextend.
    631      *    +  The pointer arithmetic is probably too expensive.
    632      *    +  etc.
    633      */
    634    
    635     p = _Addresses_Add_offset( information->object_blocks[ 0 ],
    636         (information->allocation_size * information->name_length) ),
    637 
    638     p = _Addresses_Add_offset( p, (sizeof_control * (index - 1)) );
    639     the_object = (Objects_Control *)p;
    640     _Chain_Extract( &the_object->Node );
    641  
    642     return the_object;   
    643   }   
    644 
    645   /*
    646    *  Autoextend will have to be thought out as it applies
    647    *  to user assigned indices.
    648    */
    649 
    650   return NULL;
    651 }
    652 
    653 
    654 
    655 /*PAGE
    656  *
    657  *  _Objects_Free
    658  *
    659  *  DESCRIPTION:
    660  *
    661  *  This function frees a object control block to the
    662  *  inactive chain of free object control blocks.
    663  */
    664 
    665 void _Objects_Free(
    666   Objects_Information *information,
    667   Objects_Control     *the_object
    668 )
    669 {
    670   unsigned32  allocation_size = information->allocation_size;
    671 
    672   _Chain_Append( &information->Inactive, &the_object->Node );
    673 
    674   if ( information->auto_extend ) {
    675     unsigned32  block;
    676    
    677     block =
    678       _Objects_Get_index( the_object->id ) - _Objects_Get_index( information->minimum_id );
    679     block /= information->allocation_size;
    680      
    681     information->inactive_per_block[ block ]++;
    682     information->inactive++;
    683  
    684     /*
    685      *  Check if the threshold level has been met of
    686      *  1.5 x allocation_size are free.
    687      */
    688 
    689     if ( information->inactive > ( allocation_size + ( allocation_size >> 1 ) ) ) {
    690       _Objects_Shrink_information( information );
    691     }
    692   }
    693 }
    694 
    695 /*PAGE
    696  *
    697  *  _Objects_Clear_name
    698  *
    699  *  XXX
    700  */
    701 
    702 void _Objects_Clear_name(
    703   void       *name,
    704   unsigned32  length
    705 )
    706 {
    707   unsigned32  index;
    708   unsigned32  maximum = length / OBJECTS_NAME_ALIGNMENT;
    709   unsigned32 *name_ptr = (unsigned32 *) name;
    710 
    711   for ( index=0 ; index < maximum ; index++ )
    712     *name_ptr++ = 0;
    713 }
    714  
    715 /*PAGE
    716  *
    717  *  _Objects_Copy_name_string
    718  *
    719  *  XXX
    720  */
    721  
    722 void _Objects_Copy_name_string(
    723   void       *source,
    724   void       *destination
    725 )
    726 {
    727   unsigned8 *source_p = (unsigned8 *) source;
    728   unsigned8 *destination_p = (unsigned8 *) destination;
    729  
    730   do {
    731     *destination_p++ = *source_p;
    732   } while ( *source_p++ );
    733 }
    734 
    735 /*PAGE
    736  *
    737  *  _Objects_Copy_name_raw
    738  *
    739  *  XXX
    740  */
    741  
    742 void _Objects_Copy_name_raw(
    743   void       *source,
    744   void       *destination,
    745   unsigned32  length
    746 )
    747 {
    748   unsigned32 *source_p = (unsigned32 *) source;
    749   unsigned32 *destination_p = (unsigned32 *) destination;
    750   unsigned32  tmp_length = length / OBJECTS_NAME_ALIGNMENT;
    751  
    752   while ( tmp_length-- )
    753     *destination_p++ = *source_p++;
    754 }
    755 
    756 /*PAGE
    757  *
    758  *  _Objects_Compare_name_string
    759  *
    760  *  XXX
    761  */
    762  
    763 boolean _Objects_Compare_name_string(
    764   void       *name_1,
    765   void       *name_2,
    766   unsigned32  length
    767 )
    768 {
    769   unsigned8 *name_1_p = (unsigned8 *) name_1;
    770   unsigned8 *name_2_p = (unsigned8 *) name_2;
    771   unsigned32 tmp_length = length;
    772  
    773   do {
    774     if ( *name_1_p++ != *name_2_p++ )
    775       return FALSE;
    776     if ( !tmp_length-- )
    777       return FALSE;
    778   } while ( *name_1_p );
    779 
    780   return TRUE;
    781 }
    782  
    783 /*PAGE
    784  *
    785  *  _Objects_Compare_name_raw
    786  *
    787  *  XXX
    788  */
    789  
    790 boolean _Objects_Compare_name_raw(
    791   void       *name_1,
    792   void       *name_2,
    793   unsigned32  length
    794 )
    795 {
    796   unsigned32 *name_1_p = (unsigned32 *) name_1;
    797   unsigned32 *name_2_p = (unsigned32 *) name_2;
    798   unsigned32  tmp_length = length / OBJECTS_NAME_ALIGNMENT;
    799  
    800   while ( tmp_length-- )
    801     if ( *name_1_p++ != *name_2_p++ )
    802       return FALSE;
    803 
    804   return TRUE;
    805 }
    806 
    807 
    808 /*PAGE
    809  *
    810  *  _Objects_Name_to_id
    811  *
    812  *  These kernel routines search the object table(s) for the given
    813  *  object name and returns the associated object id.
    814  *
    815  *  Input parameters:
    816  *    information - object information
    817  *    name        - user defined object name
    818  *    node        - node indentifier (0 indicates any node)
    819  *    id          - address of return ID
    820  *
    821  *  Output parameters:
    822  *    id                 - object id
    823  *    OBJECTS_SUCCESSFUL - if successful
    824  *    error code         - if unsuccessful
    825  */
    826 
    827 Objects_Name_to_id_errors _Objects_Name_to_id(
    828   Objects_Information *information,
    829   Objects_Name         name,
    830   unsigned32           node,
    831   Objects_Id          *id
    832 )
    833 {
    834   boolean                    search_local_node;
    835   Objects_Control           *the_object;
    836   unsigned32                 index;
    837   unsigned32                 name_length;
    838   Objects_Name_comparators   compare_them;
    839 
    840   if ( name == 0 )
    841     return OBJECTS_INVALID_NAME;
    842 
    843   search_local_node = FALSE;
    844 
    845   if ( information->maximum != 0 &&
    846       (node == OBJECTS_SEARCH_ALL_NODES || node == OBJECTS_SEARCH_LOCAL_NODE ||
    847       _Objects_Is_local_node( node ) ) )
    848    search_local_node = TRUE;
    849 
    850   if ( search_local_node ) {
    851     name_length = information->name_length;
    852 
    853     if ( information->is_string ) compare_them = _Objects_Compare_name_string;
    854     else                          compare_them = _Objects_Compare_name_raw;
    855 
    856     for ( index = 1; index <= information->maximum; index++ ) {
    857 
    858       the_object = information->local_table[ index ];
    859 
    860       if ( !the_object || !the_object->name )
    861         continue;
    862 
    863       if ( (*compare_them)( name, the_object->name, name_length ) ) {
    864         *id = the_object->id;
    865         return OBJECTS_SUCCESSFUL;
    866       }
    867     }
    868   }
    869 
    870   if ( _Objects_Is_local_node( node ) || node == OBJECTS_SEARCH_LOCAL_NODE )
    871     return OBJECTS_INVALID_NAME;
    872 
    873 #if defined(RTEMS_MULTIPROCESSING)
    874   return ( _Objects_MP_Global_name_search( information, name, node, id ) );
    875 #else
    876   return OBJECTS_INVALID_NAME;
    877 #endif
    878 }
    879 
    880 /*PAGE
    881  *
    882  * _Objects_Get
    883  *
    884  * This routine sets the object pointer for the given
    885  * object id based on the given object information structure.
    886  *
    887  * Input parameters:
    888  *   information - pointer to entry in table for this class
    889  *   id          - object id to search for
    890  *   location    - address of where to store the location
    891  *
    892  * Output parameters:
    893  *   returns  - address of object if local
    894  *   location - one of the following:
    895  *                  OBJECTS_ERROR  - invalid object ID
    896  *                  OBJECTS_REMOTE - remote object
    897  *                  OBJECTS_LOCAL  - local object
    898  */
    899 
    900 Objects_Control *_Objects_Get(
    901   Objects_Information *information,
    902   Objects_Id           id,
    903   Objects_Locations   *location
    904 )
    905 {
    906   Objects_Control *the_object;
    907   unsigned32       index;
    908 
    909   index = _Objects_Get_index( id );
    910 
    911   if ( information->maximum >= index ) {
    912     _Thread_Disable_dispatch();
    913     if ( (the_object = _Objects_Get_local_object( information, index )) != NULL ) {
    914       *location = OBJECTS_LOCAL;
    915       return( the_object );
    916     }
    917     _Thread_Enable_dispatch();
    918     *location = OBJECTS_ERROR;
    919     return( NULL );
    920   }
    921   *location = OBJECTS_ERROR;
    922 #if defined(RTEMS_MULTIPROCESSING)
    923   _Objects_MP_Is_remote(
    924     information,
    925     _Objects_Build_id( information->the_class, _Objects_Local_node, index ),
    926     location,
    927     &the_object
    928   );
    929   return the_object;
    930 #else
    931   return NULL;
    932 #endif
    933 }
    934 
    935 /*PAGE
    936  *
    937  * _Objects_Get_by_index
    938  *
    939  * This routine sets the object pointer for the given
    940  * object id based on the given object information structure.
    941  *
    942  * Input parameters:
    943  *   information - pointer to entry in table for this class
    944  *   index       - object index to check for
    945  *   location    - address of where to store the location
    946  *
    947  * Output parameters:
    948  *   returns  - address of object if local
    949  *   location - one of the following:
    950  *                  OBJECTS_ERROR  - invalid object ID
    951  *                  OBJECTS_REMOTE - remote object
    952  *                  OBJECTS_LOCAL  - local object
    953  */
    954 
    955 Objects_Control *_Objects_Get_by_index(
    956   Objects_Information *information,
    957   unsigned32           index,
    958   Objects_Locations   *location
    959 )
    960 {
    961   Objects_Control *the_object;
    962 
    963   if ( information->maximum >= index ) {
    964     _Thread_Disable_dispatch();
    965     if ( (the_object = _Objects_Get_local_object( information, index )) != NULL ) {
    966       *location = OBJECTS_LOCAL;
    967       return( the_object );
    968     }
    969     _Thread_Enable_dispatch();
    970     *location = OBJECTS_ERROR;
    971     return( NULL );
    972   }
    973 
    974   /*
    975    *  With just an index, you can't access a remote object.
    976    */
    977 
    978   _Thread_Enable_dispatch();
    979   *location = OBJECTS_ERROR;
    980   return NULL;
    981 }
    982 
    983 /*PAGE
    984  *
    985  * _Objects_Get_next
    986  *
    987  * Like _Objects_Get, but considers the 'id' as a "hint" and
    988  * finds next valid one after that point.
    989  * Mostly used for monitor and debug traversal of an object.
    990  *
    991  * Input parameters:
    992  *   information - pointer to entry in table for this class
    993  *   id          - object id to search for
    994  *   location    - address of where to store the location
    995  *   next_id     - address to store next id to try
    996  *
    997  * Output parameters:
    998  *   returns     - address of object if local
    999  *   location    - one of the following:
    1000  *                  OBJECTS_ERROR  - invalid object ID
    1001  *                  OBJECTS_REMOTE - remote object
    1002  *                  OBJECTS_LOCAL  - local object
    1003  *   next_id     - will contain a reasonable "next" id to continue traversal
    1004  *
    1005  * NOTE:
    1006  *      assumes can add '1' to an id to get to next index.
    1007  */
    1008 
    1009 Objects_Control *
    1010 _Objects_Get_next(
    1011     Objects_Information *information,
    1012     Objects_Id           id,
    1013     Objects_Locations   *location_p,
    1014     Objects_Id          *next_id_p
    1015 )
    1016 {
    1017     Objects_Control *object;
    1018     Objects_Id       next_id;
    1019    
    1020     if (_Objects_Get_index(id) == OBJECTS_ID_INITIAL_INDEX)
    1021         next_id = information->minimum_id;
    1022     else
    1023         next_id = id;
    1024 
    1025     do {
    1026         /* walked off end of list? */
    1027         if (_Objects_Get_index(next_id) > information->maximum)
    1028         {
    1029             *location_p = OBJECTS_ERROR;
    1030             goto final;
    1031         }
    1032        
    1033         /* try to grab one */
    1034         object = _Objects_Get(information, next_id, location_p);
    1035 
    1036         next_id++;
    1037 
    1038     } while (*location_p != OBJECTS_LOCAL);
    1039 
    1040     *next_id_p = next_id;
    1041     return object;
    1042 
    1043 final:
    1044     *next_id_p = OBJECTS_ID_FINAL;
    1045     return 0;
    1046 }
    1047 
  • cpukit/score/src/object.c

    r811fae1 r317a5b5  
    6464#endif
    6565}
    66 
    67 /*PAGE
    68  *
    69  *  _Objects_Extend_information
    70  *
    71  *  This routine extends all object information related data structures.
    72  *
    73  *  Input parameters:
    74  *    information     - object information table
    75  *
    76  *  Output parameters:  NONE
    77  */
    78 
    79 void _Objects_Extend_information(
    80   Objects_Information *information
    81 )
    82 {
    83   Objects_Control  *the_object;
    84   void             *name_area;
    85   Chain_Control     Inactive;
    86   unsigned32        block_count;
    87   unsigned32        block;
    88   unsigned32        index_base;
    89   unsigned32        minimum_index;
    90   unsigned32        index;
    91 
    92   /*
    93    *  Search for a free block of indexes. The block variable ends up set
    94    *  to block_count + 1 if the table needs to be extended.
    95    */
    96 
    97   minimum_index = _Objects_Get_index( information->minimum_id );
    98   index_base    = minimum_index;
    99   block         = 0;
    100  
    101   if ( information->maximum < minimum_index )
    102     block_count = 0;
    103   else {
    104     block_count = information->maximum / information->allocation_size;
    105  
    106     for ( ; block < block_count; block++ ) {
    107       if ( information->object_blocks[ block ] == NULL )
    108         break;
    109       else
    110         index_base += information->allocation_size;
    111     }
    112   }
    113 
    114   /*
    115    *  If the index_base is the maximum we need to grow the tables.
    116    */
    117 
    118   if (index_base >= information->maximum ) {
    119     ISR_Level         level;
    120     void            **object_blocks;
    121     Objects_Name     *name_table;
    122     unsigned32       *inactive_per_block;
    123     Objects_Control **local_table;
    124     unsigned32        maximum;
    125     void             *old_tables;   
    126    
    127     /*
    128      *  Growing the tables means allocating a new area, doing a copy and
    129      *  updating the information table.
    130      *
    131      *  If the maximum is minimum we do not have a table to copy. First
    132      *  time through.
    133      *
    134      *  The allocation has :
    135      *
    136      *      void            *objects[block_count];
    137      *      unsigned32       inactive_count[block_count];
    138      *      Objects_Name    *name_table[block_count];
    139      *      Objects_Control *local_table[maximum];
    140      *
    141      *  This is the order in memory. Watch changing the order. See the memcpy
    142      *  below.
    143      */
    144 
    145     /*
    146      *  Up the block count and maximum
    147      */
    148 
    149     block_count++;
    150    
    151     maximum = information->maximum + information->allocation_size;
    152 
    153     /*
    154      *  Allocate the tables and break it up.
    155      */
    156    
    157     if ( information->auto_extend ) {
    158       object_blocks = (void**)
    159         _Workspace_Allocate(
    160           block_count *
    161              (sizeof(void *) + sizeof(unsigned32) + sizeof(Objects_Name *)) +
    162           ((maximum + minimum_index) * sizeof(Objects_Control *))
    163           );
    164 
    165       if ( !object_blocks )
    166         return;
    167     }
    168     else {
    169       object_blocks = (void**)
    170         _Workspace_Allocate_or_fatal_error(
    171           block_count *
    172              (sizeof(void *) + sizeof(unsigned32) + sizeof(Objects_Name *)) +
    173           ((maximum + minimum_index) * sizeof(Objects_Control *))
    174         );
    175     }
    176 
    177     /*
    178      *  Break the block into the various sections.
    179      *
    180      */
    181      
    182     inactive_per_block = (unsigned32 *) _Addresses_Add_offset(
    183         object_blocks, block_count * sizeof(void*) );
    184     name_table = (Objects_Name *) _Addresses_Add_offset(
    185         inactive_per_block, block_count * sizeof(unsigned32) );
    186     local_table = (Objects_Control **) _Addresses_Add_offset(
    187         name_table, block_count * sizeof(Objects_Name *) );
    188    
    189     /*
    190      *  Take the block count down. Saves all the (block_count - 1)
    191      *  in the copies.
    192      */
    193 
    194     block_count--;
    195    
    196     if ( information->maximum > minimum_index ) {
    197      
    198       /*
    199        *  Copy each section of the table over. This has to be performed as
    200        *  separate parts as size of each block has changed.
    201        */
    202    
    203       memcpy( object_blocks,
    204               information->object_blocks,
    205               block_count * sizeof(void*) );
    206       memcpy( inactive_per_block,
    207               information->inactive_per_block,
    208               block_count * sizeof(unsigned32) );
    209       memcpy( name_table,
    210               information->name_table,
    211               block_count * sizeof(Objects_Name *) );
    212       memcpy( local_table,
    213               information->local_table,
    214               (information->maximum + minimum_index) * sizeof(Objects_Control *) );
    215     }
    216     else {
    217 
    218       /*
    219        *  Deal with the special case of the 0 to minimum_index
    220        */
    221       for ( index = 0; index < minimum_index; index++ ) {
    222         local_table[ index ] = NULL;
    223       }
    224     }
    225    
    226     /*
    227      *  Initialise the new entries in the table.
    228      */
    229    
    230     object_blocks[block_count] = NULL;
    231     inactive_per_block[block_count] = 0;
    232     name_table[block_count] = NULL;
    233 
    234     for ( index=index_base ;
    235           index < ( information->allocation_size + index_base );
    236           index++ ) {
    237       local_table[ index ] = NULL;
    238     }
    239    
    240     _ISR_Disable( level );
    241 
    242     old_tables = information->object_blocks;
    243    
    244     information->object_blocks = object_blocks;
    245     information->inactive_per_block = inactive_per_block;
    246     information->name_table = name_table;
    247     information->local_table = local_table;
    248     information->maximum = maximum;
    249     information->maximum_id =
    250       _Objects_Build_id(
    251         information->the_class, _Objects_Local_node, information->maximum
    252       );
    253 
    254     _ISR_Enable( level );
    255 
    256     if ( old_tables )
    257       _Workspace_Free( old_tables );
    258    
    259     block_count++;
    260   }
    261            
    262   /*
    263    *  Allocate the name table, and the objects
    264    */
    265 
    266   if ( information->auto_extend ) {
    267     information->object_blocks[ block ] =
    268       _Workspace_Allocate(
    269         (information->allocation_size * information->name_length) +
    270         (information->allocation_size * information->size)
    271       );
    272 
    273     if ( !information->object_blocks[ block ] )
    274       return;
    275   }
    276   else {
    277     information->object_blocks[ block ] =
    278       _Workspace_Allocate_or_fatal_error(
    279         (information->allocation_size * information->name_length) +
    280         (information->allocation_size * information->size)
    281       );
    282   }
    283  
    284   name_area = (Objects_Name *) _Addresses_Add_offset(
    285     information->object_blocks[ block ],
    286     (information->allocation_size * information->size)
    287   );
    288   information->name_table[ block ] = name_area;
    289 
    290   /*
    291    *  Initialize objects .. add to a local chain first.
    292    */
    293 
    294   _Chain_Initialize(
    295     &Inactive,
    296     information->object_blocks[ block ],
    297     information->allocation_size,
    298     information->size
    299   );
    300 
    301   /*
    302    *  Move from the local chain, initialise, then append to the inactive chain
    303    */
    304 
    305   index = index_base;
    306  
    307   while ( (the_object = (Objects_Control *) _Chain_Get( &Inactive ) ) != NULL ) {
    308    
    309     the_object->id =
    310       _Objects_Build_id(
    311         information->the_class, _Objects_Local_node, index
    312       );
    313      
    314     the_object->name = (void *) name_area;
    315 
    316     name_area = _Addresses_Add_offset( name_area, information->name_length );
    317 
    318     _Chain_Append( &information->Inactive, &the_object->Node );
    319 
    320     index++;
    321   }
    322  
    323   information->inactive_per_block[ block ] = information->allocation_size;
    324   information->inactive += information->allocation_size;
    325 }
    326 
    327 /*PAGE
    328  *
    329  *  _Objects_Shrink_information
    330  *
    331  *  This routine shrinks object information related data structures.
    332  *  The object's name and object space are released. The local_table
    333  *  etc block does not shrink. The InActive list needs to be scanned
    334  *  to find the objects are remove them.
    335  *  Input parameters:
    336  *    information     - object information table
    337  *    the_block       - the block to remove
    338  *
    339  *  Output parameters:  NONE
    340  */
    341 
    342 void _Objects_Shrink_information(
    343   Objects_Information *information
    344 )
    345 {
    346   Objects_Control  *the_object;
    347   Objects_Control  *extract_me;
    348   unsigned32        block_count;
    349   unsigned32        block;
    350   unsigned32        index_base;
    351   unsigned32        index;
    352 
    353   /*
    354    * Search the list to find block or chunnk with all objects inactive.
    355    */
    356 
    357   index_base = _Objects_Get_index( information->minimum_id );
    358   block_count = ( information->maximum - index_base ) / information->allocation_size;
    359  
    360   for ( block = 0; block < block_count; block++ ) {
    361     if ( information->inactive_per_block[ block ] == information->allocation_size ) {
    362 
    363       /*
    364        * XXX - Not to sure how to use a chain where you need to iterate and
    365        *       and remove elements.
    366        */
    367      
    368       the_object = (Objects_Control *) information->Inactive.first;
    369 
    370       /*
    371        *  Assume the Inactive chain is never empty at this point
    372        */
    373 
    374       do {
    375         index = _Objects_Get_index( the_object->id );
    376 
    377         if ((index >= index_base) &&
    378             (index < (index_base + information->allocation_size))) {
    379          
    380           /*
    381            *  Get the next node before the node is extracted
    382            */
    383          
    384           extract_me = the_object;
    385 
    386           if ( !_Chain_Is_last( &the_object->Node ) )
    387             the_object = (Objects_Control *) the_object->Node.next;
    388           else
    389             the_object = NULL;
    390          
    391           _Chain_Extract( &extract_me->Node );
    392         }
    393         else {
    394           the_object = (Objects_Control *) the_object->Node.next;
    395         }
    396       }
    397       while ( the_object && !_Chain_Is_last( &the_object->Node ) );
    398 
    399       /*
    400        *  Free the memory and reset the structures in the object' information
    401        */
    402 
    403       _Workspace_Free( information->object_blocks[ block ] );
    404       information->name_table[ block ] = NULL;
    405       information->object_blocks[ block ] = NULL;
    406       information->inactive_per_block[ block ] = 0;
    407 
    408       information->inactive -= information->allocation_size;
    409      
    410       return;
    411     }
    412    
    413     index_base += information->allocation_size;
    414   }
    415 }
    416 
    417 /*PAGE
    418  *
    419  *  _Objects_Initialize_information
    420  *
    421  *  This routine initializes all object information related data structures.
    422  *
    423  *  Input parameters:
    424  *    information         - object information table
    425  *    the_class           - object class
    426  *    supports_global     - TRUE if this is a global object class
    427  *    maximum             - maximum objects of this class
    428  *    size                - size of this object's control block
    429  *    is_string           - TRUE if names for this object are strings
    430  *    maximum_name_length - maximum length of each object's name
    431  *    is_thread           - TRUE if this class is threads
    432  *
    433  *  Output parameters:  NONE
    434  */
    435 
    436 void _Objects_Initialize_information(
    437   Objects_Information *information,
    438   Objects_Classes      the_class,
    439   boolean              supports_global,
    440   unsigned32           maximum,
    441   unsigned32           size,
    442   boolean              is_string,
    443   unsigned32           maximum_name_length,
    444   boolean              is_thread
    445 )
    446 {
    447   static Objects_Control *null_local_table = NULL;
    448  
    449   unsigned32       minimum_index;
    450   unsigned32       index;
    451   unsigned32       name_length;
    452 
    453   information->the_class          = the_class;
    454   information->is_string          = is_string;
    455   information->is_thread          = is_thread;
    456  
    457   information->local_table        = 0;
    458   information->name_table         = 0;
    459   information->inactive_per_block = 0;
    460   information->object_blocks      = 0;
    461  
    462   information->inactive           = 0;
    463  
    464   /*
    465    *  Set the entry in the object information table.
    466    */
    467 
    468   _Objects_Information_table[ the_class ] = information;
    469 
    470   /*
    471    *  Set the size of the object
    472    */
    473 
    474   information->size = size;
    475  
    476   /*
    477    *  Are we operating in unlimited, or auto-extend mode
    478    */
    479 
    480   information->auto_extend = (maximum & OBJECTS_UNLIMITED_OBJECTS) ? TRUE : FALSE;
    481   maximum                 &= ~OBJECTS_UNLIMITED_OBJECTS;
    482  
    483   /*
    484    *  The allocation unit is the maximum value
    485    */
    486 
    487   information->allocation_size = maximum;
    488 
    489   /*
    490    *  Provide a null local table entry for the case of any empty table.
    491    */
    492 
    493   information->local_table = &null_local_table;
    494 
    495   /*
    496    *  Calculate minimum and maximum Id's
    497    */
    498 
    499   if ( maximum == 0 ) minimum_index = 0;
    500   else                minimum_index = 1;
    501 
    502   information->minimum_id =
    503     _Objects_Build_id( the_class, _Objects_Local_node, minimum_index );
    504 
    505   /*
    506    *  Calculate the maximum name length
    507    */
    508 
    509   name_length = maximum_name_length;
    510 
    511   if ( name_length & (OBJECTS_NAME_ALIGNMENT-1) )
    512     name_length = (name_length + OBJECTS_NAME_ALIGNMENT) &
    513                   ~(OBJECTS_NAME_ALIGNMENT-1);
    514 
    515   information->name_length = name_length;
    516 
    517   _Chain_Initialize_empty( &information->Inactive );
    518    
    519   /*
    520    *  Initialize objects .. if there are any
    521    */
    522 
    523   if ( maximum ) {
    524 
    525     /*
    526      *  Reset the maximum value. It will be updated when the information is
    527      *  extended.
    528      */
    529    
    530     information->maximum = 0;
    531    
    532     /*
    533      *  Always have the maximum size available so the current performance
    534      *  figures are create are met.  If the user moves past the maximum
    535      *  number then a performance hit is taken.
    536      */
    537    
    538     _Objects_Extend_information( information );
    539    
    540   }
    541 
    542   /*
    543    *  Take care of multiprocessing
    544    */
    545 
    546   if ( supports_global == TRUE && _System_state_Is_multiprocessing ) {
    547 
    548     information->global_table =
    549       (Chain_Control *) _Workspace_Allocate_or_fatal_error(
    550         (_Objects_Maximum_nodes + 1) * sizeof(Chain_Control)
    551       );
    552 
    553     for ( index=1; index <= _Objects_Maximum_nodes ; index++ )
    554       _Chain_Initialize_empty( &information->global_table[ index ] );
    555    }
    556    else
    557      information->global_table = NULL;
    558 }
    559 
    560 /*PAGE
    561  *
    562  *  _Objects_Allocate
    563  *
    564  *  DESCRIPTION:
    565  *
    566  *  This function allocates a object control block from
    567  *  the inactive chain of free object control blocks.
    568  */
    569 
    570 Objects_Control *_Objects_Allocate(
    571   Objects_Information *information
    572 )
    573 {
    574   Objects_Control *the_object = 
    575     (Objects_Control *) _Chain_Get( &information->Inactive );
    576 
    577   if ( information->auto_extend ) {
    578     /*
    579      *  If the list is empty then we are out of objects and need to
    580      *  extend information base.
    581      */
    582  
    583     if ( !the_object ) {
    584       _Objects_Extend_information( information );
    585       the_object =  (Objects_Control *) _Chain_Get( &information->Inactive );
    586     }
    587  
    588     if ( the_object ) {
    589       unsigned32 block;
    590    
    591       block = _Objects_Get_index( the_object->id ) -
    592               _Objects_Get_index( information->minimum_id );
    593       block /= information->allocation_size;
    594      
    595       information->inactive_per_block[ block ]--;
    596       information->inactive--;
    597     }
    598   }
    599  
    600   return the_object;
    601 }
    602 
    603 /*PAGE
    604  *
    605  *  _Objects_Allocate_by_index
    606  *
    607  *  DESCRIPTION:
    608  *
    609  *  This function allocates the object control block
    610  *  specified by the index from the inactive chain of
    611  *  free object control blocks.
    612  */
    613 
    614 Objects_Control *_Objects_Allocate_by_index(
    615   Objects_Information *information,
    616   unsigned32           index,
    617   unsigned32           sizeof_control
    618 )
    619 {
    620   Objects_Control *the_object;
    621   void            *p;
    622 
    623   if ( index && information->maximum >= index ) {
    624     the_object = _Objects_Get_local_object( information, index );
    625     if ( the_object )
    626       return NULL;
    627 
    628     /* XXX
    629      *  This whole section of code needs to be addressed.
    630      *    +  The 0 should be dealt with more properly so we can autoextend.
    631      *    +  The pointer arithmetic is probably too expensive.
    632      *    +  etc.
    633      */
    634    
    635     p = _Addresses_Add_offset( information->object_blocks[ 0 ],
    636         (information->allocation_size * information->name_length) ),
    637 
    638     p = _Addresses_Add_offset( p, (sizeof_control * (index - 1)) );
    639     the_object = (Objects_Control *)p;
    640     _Chain_Extract( &the_object->Node );
    641  
    642     return the_object;   
    643   }   
    644 
    645   /*
    646    *  Autoextend will have to be thought out as it applies
    647    *  to user assigned indices.
    648    */
    649 
    650   return NULL;
    651 }
    652 
    653 
    654 
    655 /*PAGE
    656  *
    657  *  _Objects_Free
    658  *
    659  *  DESCRIPTION:
    660  *
    661  *  This function frees a object control block to the
    662  *  inactive chain of free object control blocks.
    663  */
    664 
    665 void _Objects_Free(
    666   Objects_Information *information,
    667   Objects_Control     *the_object
    668 )
    669 {
    670   unsigned32  allocation_size = information->allocation_size;
    671 
    672   _Chain_Append( &information->Inactive, &the_object->Node );
    673 
    674   if ( information->auto_extend ) {
    675     unsigned32  block;
    676    
    677     block =
    678       _Objects_Get_index( the_object->id ) - _Objects_Get_index( information->minimum_id );
    679     block /= information->allocation_size;
    680      
    681     information->inactive_per_block[ block ]++;
    682     information->inactive++;
    683  
    684     /*
    685      *  Check if the threshold level has been met of
    686      *  1.5 x allocation_size are free.
    687      */
    688 
    689     if ( information->inactive > ( allocation_size + ( allocation_size >> 1 ) ) ) {
    690       _Objects_Shrink_information( information );
    691     }
    692   }
    693 }
    694 
    695 /*PAGE
    696  *
    697  *  _Objects_Clear_name
    698  *
    699  *  XXX
    700  */
    701 
    702 void _Objects_Clear_name(
    703   void       *name,
    704   unsigned32  length
    705 )
    706 {
    707   unsigned32  index;
    708   unsigned32  maximum = length / OBJECTS_NAME_ALIGNMENT;
    709   unsigned32 *name_ptr = (unsigned32 *) name;
    710 
    711   for ( index=0 ; index < maximum ; index++ )
    712     *name_ptr++ = 0;
    713 }
    714  
    715 /*PAGE
    716  *
    717  *  _Objects_Copy_name_string
    718  *
    719  *  XXX
    720  */
    721  
    722 void _Objects_Copy_name_string(
    723   void       *source,
    724   void       *destination
    725 )
    726 {
    727   unsigned8 *source_p = (unsigned8 *) source;
    728   unsigned8 *destination_p = (unsigned8 *) destination;
    729  
    730   do {
    731     *destination_p++ = *source_p;
    732   } while ( *source_p++ );
    733 }
    734 
    735 /*PAGE
    736  *
    737  *  _Objects_Copy_name_raw
    738  *
    739  *  XXX
    740  */
    741  
    742 void _Objects_Copy_name_raw(
    743   void       *source,
    744   void       *destination,
    745   unsigned32  length
    746 )
    747 {
    748   unsigned32 *source_p = (unsigned32 *) source;
    749   unsigned32 *destination_p = (unsigned32 *) destination;
    750   unsigned32  tmp_length = length / OBJECTS_NAME_ALIGNMENT;
    751  
    752   while ( tmp_length-- )
    753     *destination_p++ = *source_p++;
    754 }
    755 
    756 /*PAGE
    757  *
    758  *  _Objects_Compare_name_string
    759  *
    760  *  XXX
    761  */
    762  
    763 boolean _Objects_Compare_name_string(
    764   void       *name_1,
    765   void       *name_2,
    766   unsigned32  length
    767 )
    768 {
    769   unsigned8 *name_1_p = (unsigned8 *) name_1;
    770   unsigned8 *name_2_p = (unsigned8 *) name_2;
    771   unsigned32 tmp_length = length;
    772  
    773   do {
    774     if ( *name_1_p++ != *name_2_p++ )
    775       return FALSE;
    776     if ( !tmp_length-- )
    777       return FALSE;
    778   } while ( *name_1_p );
    779 
    780   return TRUE;
    781 }
    782  
    783 /*PAGE
    784  *
    785  *  _Objects_Compare_name_raw
    786  *
    787  *  XXX
    788  */
    789  
    790 boolean _Objects_Compare_name_raw(
    791   void       *name_1,
    792   void       *name_2,
    793   unsigned32  length
    794 )
    795 {
    796   unsigned32 *name_1_p = (unsigned32 *) name_1;
    797   unsigned32 *name_2_p = (unsigned32 *) name_2;
    798   unsigned32  tmp_length = length / OBJECTS_NAME_ALIGNMENT;
    799  
    800   while ( tmp_length-- )
    801     if ( *name_1_p++ != *name_2_p++ )
    802       return FALSE;
    803 
    804   return TRUE;
    805 }
    806 
    807 
    808 /*PAGE
    809  *
    810  *  _Objects_Name_to_id
    811  *
    812  *  These kernel routines search the object table(s) for the given
    813  *  object name and returns the associated object id.
    814  *
    815  *  Input parameters:
    816  *    information - object information
    817  *    name        - user defined object name
    818  *    node        - node indentifier (0 indicates any node)
    819  *    id          - address of return ID
    820  *
    821  *  Output parameters:
    822  *    id                 - object id
    823  *    OBJECTS_SUCCESSFUL - if successful
    824  *    error code         - if unsuccessful
    825  */
    826 
    827 Objects_Name_to_id_errors _Objects_Name_to_id(
    828   Objects_Information *information,
    829   Objects_Name         name,
    830   unsigned32           node,
    831   Objects_Id          *id
    832 )
    833 {
    834   boolean                    search_local_node;
    835   Objects_Control           *the_object;
    836   unsigned32                 index;
    837   unsigned32                 name_length;
    838   Objects_Name_comparators   compare_them;
    839 
    840   if ( name == 0 )
    841     return OBJECTS_INVALID_NAME;
    842 
    843   search_local_node = FALSE;
    844 
    845   if ( information->maximum != 0 &&
    846       (node == OBJECTS_SEARCH_ALL_NODES || node == OBJECTS_SEARCH_LOCAL_NODE ||
    847       _Objects_Is_local_node( node ) ) )
    848    search_local_node = TRUE;
    849 
    850   if ( search_local_node ) {
    851     name_length = information->name_length;
    852 
    853     if ( information->is_string ) compare_them = _Objects_Compare_name_string;
    854     else                          compare_them = _Objects_Compare_name_raw;
    855 
    856     for ( index = 1; index <= information->maximum; index++ ) {
    857 
    858       the_object = information->local_table[ index ];
    859 
    860       if ( !the_object || !the_object->name )
    861         continue;
    862 
    863       if ( (*compare_them)( name, the_object->name, name_length ) ) {
    864         *id = the_object->id;
    865         return OBJECTS_SUCCESSFUL;
    866       }
    867     }
    868   }
    869 
    870   if ( _Objects_Is_local_node( node ) || node == OBJECTS_SEARCH_LOCAL_NODE )
    871     return OBJECTS_INVALID_NAME;
    872 
    873 #if defined(RTEMS_MULTIPROCESSING)
    874   return ( _Objects_MP_Global_name_search( information, name, node, id ) );
    875 #else
    876   return OBJECTS_INVALID_NAME;
    877 #endif
    878 }
    879 
    880 /*PAGE
    881  *
    882  * _Objects_Get
    883  *
    884  * This routine sets the object pointer for the given
    885  * object id based on the given object information structure.
    886  *
    887  * Input parameters:
    888  *   information - pointer to entry in table for this class
    889  *   id          - object id to search for
    890  *   location    - address of where to store the location
    891  *
    892  * Output parameters:
    893  *   returns  - address of object if local
    894  *   location - one of the following:
    895  *                  OBJECTS_ERROR  - invalid object ID
    896  *                  OBJECTS_REMOTE - remote object
    897  *                  OBJECTS_LOCAL  - local object
    898  */
    899 
    900 Objects_Control *_Objects_Get(
    901   Objects_Information *information,
    902   Objects_Id           id,
    903   Objects_Locations   *location
    904 )
    905 {
    906   Objects_Control *the_object;
    907   unsigned32       index;
    908 
    909   index = _Objects_Get_index( id );
    910 
    911   if ( information->maximum >= index ) {
    912     _Thread_Disable_dispatch();
    913     if ( (the_object = _Objects_Get_local_object( information, index )) != NULL ) {
    914       *location = OBJECTS_LOCAL;
    915       return( the_object );
    916     }
    917     _Thread_Enable_dispatch();
    918     *location = OBJECTS_ERROR;
    919     return( NULL );
    920   }
    921   *location = OBJECTS_ERROR;
    922 #if defined(RTEMS_MULTIPROCESSING)
    923   _Objects_MP_Is_remote(
    924     information,
    925     _Objects_Build_id( information->the_class, _Objects_Local_node, index ),
    926     location,
    927     &the_object
    928   );
    929   return the_object;
    930 #else
    931   return NULL;
    932 #endif
    933 }
    934 
    935 /*PAGE
    936  *
    937  * _Objects_Get_by_index
    938  *
    939  * This routine sets the object pointer for the given
    940  * object id based on the given object information structure.
    941  *
    942  * Input parameters:
    943  *   information - pointer to entry in table for this class
    944  *   index       - object index to check for
    945  *   location    - address of where to store the location
    946  *
    947  * Output parameters:
    948  *   returns  - address of object if local
    949  *   location - one of the following:
    950  *                  OBJECTS_ERROR  - invalid object ID
    951  *                  OBJECTS_REMOTE - remote object
    952  *                  OBJECTS_LOCAL  - local object
    953  */
    954 
    955 Objects_Control *_Objects_Get_by_index(
    956   Objects_Information *information,
    957   unsigned32           index,
    958   Objects_Locations   *location
    959 )
    960 {
    961   Objects_Control *the_object;
    962 
    963   if ( information->maximum >= index ) {
    964     _Thread_Disable_dispatch();
    965     if ( (the_object = _Objects_Get_local_object( information, index )) != NULL ) {
    966       *location = OBJECTS_LOCAL;
    967       return( the_object );
    968     }
    969     _Thread_Enable_dispatch();
    970     *location = OBJECTS_ERROR;
    971     return( NULL );
    972   }
    973 
    974   /*
    975    *  With just an index, you can't access a remote object.
    976    */
    977 
    978   _Thread_Enable_dispatch();
    979   *location = OBJECTS_ERROR;
    980   return NULL;
    981 }
    982 
    983 /*PAGE
    984  *
    985  * _Objects_Get_next
    986  *
    987  * Like _Objects_Get, but considers the 'id' as a "hint" and
    988  * finds next valid one after that point.
    989  * Mostly used for monitor and debug traversal of an object.
    990  *
    991  * Input parameters:
    992  *   information - pointer to entry in table for this class
    993  *   id          - object id to search for
    994  *   location    - address of where to store the location
    995  *   next_id     - address to store next id to try
    996  *
    997  * Output parameters:
    998  *   returns     - address of object if local
    999  *   location    - one of the following:
    1000  *                  OBJECTS_ERROR  - invalid object ID
    1001  *                  OBJECTS_REMOTE - remote object
    1002  *                  OBJECTS_LOCAL  - local object
    1003  *   next_id     - will contain a reasonable "next" id to continue traversal
    1004  *
    1005  * NOTE:
    1006  *      assumes can add '1' to an id to get to next index.
    1007  */
    1008 
    1009 Objects_Control *
    1010 _Objects_Get_next(
    1011     Objects_Information *information,
    1012     Objects_Id           id,
    1013     Objects_Locations   *location_p,
    1014     Objects_Id          *next_id_p
    1015 )
    1016 {
    1017     Objects_Control *object;
    1018     Objects_Id       next_id;
    1019    
    1020     if (_Objects_Get_index(id) == OBJECTS_ID_INITIAL_INDEX)
    1021         next_id = information->minimum_id;
    1022     else
    1023         next_id = id;
    1024 
    1025     do {
    1026         /* walked off end of list? */
    1027         if (_Objects_Get_index(next_id) > information->maximum)
    1028         {
    1029             *location_p = OBJECTS_ERROR;
    1030             goto final;
    1031         }
    1032        
    1033         /* try to grab one */
    1034         object = _Objects_Get(information, next_id, location_p);
    1035 
    1036         next_id++;
    1037 
    1038     } while (*location_p != OBJECTS_LOCAL);
    1039 
    1040     *next_id_p = next_id;
    1041     return object;
    1042 
    1043 final:
    1044     *next_id_p = OBJECTS_ID_FINAL;
    1045     return 0;
    1046 }
    1047 
Note: See TracChangeset for help on using the changeset viewer.