Changeset f4a8ee1 in rtems


Ignore:
Timestamp:
Mar 17, 1999, 4:01:03 PM (22 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
55b8fef2
Parents:
e9e01dd6
Message:

Unlimited objects patch from Chris Johns <ccj@…>. Email follows:

First, the unlimited patch. I have compiled the unlmited patch for the
Linux posix BSP only and it seems to work cleanly. I would like a really
major application run on this change before commiting as the changes are
very core and significant. I am currently building all the tests to run.

I have no targets suitable to test on at the moment.

I have tested the patch for inline functions and macros.

Turning macros on has found some core bugs. I have fixed these but have
not run all the tests. Please review the patch for these changes. They
are:

1) The conditional compilation for MP support broke the core messages
code. You cannot embed a conditional macro in another macro. The Send
and Urgent Send calls are macros.

2) User extensions handler initialisation now has two parameters. I have
updated the macros to support the extra parameter.

The patch also contains the gcc-target-default.cfg fix required to build
the kernel. More of a by product than a fix for you.

Files:
15 added
19 edited

Legend:

Unmodified
Added
Removed
  • c/src/exec/rtems/src/msg.c

    re9e01dd6 rf4a8ee1  
    3131#include <rtems/rtems/options.h>
    3232#include <rtems/rtems/support.h>
     33
     34/*PAGE
     35 *
     36 *  _MESSAGE_QUEUE_CORE_MESSAGE_QUEUE_MP_SUPPORT
     37 *
     38 *  Condition support for the MP. Helps the macro build.
     39 *
     40 */
     41
     42#if defined(RTEMS_MULTIPROCESSING)
     43#define _MESSAGE_QUEUE_CORE_MESSAGE_QUEUE_MP_SUPPORT _Message_queue_Core_message_queue_mp_support
     44#else
     45#define _MESSAGE_QUEUE_CORE_MESSAGE_QUEUE_MP_SUPPORT NULL
     46#endif
    3347
    3448/*PAGE
     
    451465                      size,
    452466                      id,
    453 #if defined(RTEMS_MULTIPROCESSING)
    454                       _Message_queue_Core_message_queue_mp_support,
    455 #else
    456                       NULL,
    457 #endif
     467                      _MESSAGE_QUEUE_CORE_MESSAGE_QUEUE_MP_SUPPORT,
    458468                      count
    459469                    );
     
    719729                          size,
    720730                          id,
    721 #if defined(RTEMS_MULTIPROCESSING)
    722                           _Message_queue_Core_message_queue_mp_support
    723 #else
    724                           NULL
    725 #endif
     731                          _MESSAGE_QUEUE_CORE_MESSAGE_QUEUE_MP_SUPPORT
    726732                        );
    727733          break;
     
    732738                          size,
    733739                          id,
    734 #if defined(RTEMS_MULTIPROCESSING)
    735                           _Message_queue_Core_message_queue_mp_support
    736 #else
    737                           NULL
    738 #endif
     740                          _MESSAGE_QUEUE_CORE_MESSAGE_QUEUE_MP_SUPPORT
    739741                        );
    740742          break;
  • c/src/exec/sapi/include/rtems/config.h

    re9e01dd6 rf4a8ee1  
    2222#endif
    2323
     24/*
     25 *  Unlimited object support. Changes the configuration table entry for POSIX
     26 *  or RTEMS APIs to bounded only by the memory of the work-space.
     27 *
     28 *  Use the macro to define the resource unlimited before placing in the configuration
     29 *  table.
     30 */
     31
     32#include <rtems/score/object.h>
     33#define RTEMS_UNLIMITED_OBJECTS OBJECTS_UNLIMITED_OBJECTS
     34 
     35#define rtems_resource_unlimited(resource) \
     36  ( resource | RTEMS_UNLIMITED_OBJECTS )
     37   
    2438/*
    2539 *  This is kind of kludgy but it allows targets to totally ignore the
  • c/src/exec/score/include/rtems/score/object.h

    re9e01dd6 rf4a8ee1  
    2525
    2626#include <rtems/score/chain.h>
     27
     28/*
     29 *  Mask to enable unlimited objects
     30 *
     31 *  XXX - needs to be moved to the API some-where
     32 */
     33
     34#define OBJECTS_UNLIMITED_OBJECTS 0x80000000
    2735
    2836/*
     
    122130
    123131typedef struct {
    124   Chain_Node    Node;
    125   Objects_Id    id;
    126   Objects_Name  name;
     132  Chain_Node     Node;
     133  Objects_Id     id;
     134  Objects_Name   name;
    127135}   Objects_Control;
    128136
     
    133141
    134142typedef struct {
    135   Objects_Classes   the_class;       /* Class of this object */
    136   Objects_Id        minimum_id;      /* minimum valid id of this type */
    137   Objects_Id        maximum_id;      /* maximum valid id of this type */
    138   unsigned32        maximum;         /* maximum number of objects */
    139   Objects_Control **local_table;     /* table of local object pointers */
    140   Objects_Name     *name_table;      /* table of local object names */
    141   Chain_Control    *global_table;    /* pointer to global table */
    142   Chain_Control     Inactive;        /* chain of inactive ctl blocks */
    143   boolean           is_string;       /* TRUE if names are strings */
    144   unsigned32        name_length;     /* maximum length of names */
    145   boolean           is_thread;       /* TRUE if these are threads */
    146                                      /*   irregardless of API */
     143  Objects_Classes   the_class;          /* Class of this object */
     144  Objects_Id        minimum_id;         /* minimum valid id of this type */
     145  Objects_Id        maximum_id;         /* maximum valid id of this type */
     146  unsigned32        maximum;            /* maximum number of objects */
     147  boolean           auto_extend;        /* TRUE if unlimited objects */
     148  unsigned32        allocation_size;    /* number of objects in a block */
     149  unsigned32        size;               /* size of the objects */
     150  Objects_Control **local_table;
     151  Objects_Name     *name_table;
     152  Chain_Control    *global_table;       /* pointer to global table */
     153  Chain_Control     Inactive;           /* chain of inactive ctl blocks */
     154  unsigned32        inactive;           /* number of objects on the InActive list */
     155  unsigned32       *inactive_per_block; /* used to release a block */
     156  void            **object_blocks;      /* the object memory to remove */
     157  boolean           is_string;          /* TRUE if names are strings */
     158  unsigned32        name_length;        /* maximum length of names */
     159  boolean           is_thread;          /* TRUE if these are threads */
     160                                        /*   irregardless of API */
    147161}   Objects_Information;
    148162
     
    206220  unsigned32 maximum_nodes,
    207221  unsigned32 maximum_global_objects
     222);
     223
     224/*
     225 *  _Objects_Extend_information
     226 *
     227 *  DESCRIPTION:
     228 *
     229 *  This function extends an object class information record.
     230 */
     231
     232void _Objects_Extend_information(
     233  Objects_Information *information
     234);
     235
     236/*
     237 *  _Objects_Shrink_information
     238 *
     239 *  DESCRIPTION:
     240 *
     241 *  This function shrink an object class information record.
     242 */
     243
     244void _Objects_Shrink_information(
     245  Objects_Information *information
    208246);
    209247
     
    233271);
    234272
     273/*PAGE
     274 *
     275 *  _Objects_Allocate
     276 *
     277 *  DESCRIPTION:
     278 *
     279 *  This function allocates a object control block from
     280 *  the inactive chain of free object control blocks.
     281 */
     282
     283Objects_Control *_Objects_Allocate(
     284  Objects_Information *information
     285);
     286
     287/*PAGE
     288 *
     289 *  _Objects_Free
     290 *
     291 *  DESCRIPTION:
     292 *
     293 *  This function frees a object control block to the
     294 *  inactive chain of free object control blocks.
     295 */
     296
     297void _Objects_Free(
     298  Objects_Information *information,
     299  Objects_Control     *the_object
     300);
     301
    235302/*
    236303 *  _Objects_Clear_name
     
    371438
    372439/*
    373  *  _Objects_Get_information
    374  *
    375  *  DESCRIPTION:
    376  *
    377  *  Returns the information control block for the class of objects
    378  *  corresponding to this id.
    379  */
    380 
    381 Objects_Information *_Objects_Get_information(
    382   Objects_Id  id
    383 );
    384  
    385 /*
    386440 *  Pieces of object.inl are promoted out to the user
    387441 */
  • c/src/exec/score/inline/rtems/score/coremsg.inl

    re9e01dd6 rf4a8ee1  
    4242    size,
    4343    id,
     44#if defined(RTEMS_MULTIPROCESSING)
    4445    api_message_queue_mp_support,
     46#else
     47    NULL,
     48#endif
    4549    CORE_MESSAGE_QUEUE_SEND_REQUEST
    4650  );
     
    6973    size,
    7074    id,
     75#if defined(RTEMS_MULTIPROCESSING)
    7176    api_message_queue_mp_support,
     77#else
     78    NULL,
     79#endif
    7280    CORE_MESSAGE_QUEUE_URGENT_REQUEST
    7381 );
  • c/src/exec/score/inline/rtems/score/object.inl

    re9e01dd6 rf4a8ee1  
    159159/*PAGE
    160160 *
    161  *  _Objects_Allocate
    162  *
    163  *  DESCRIPTION:
    164  *
    165  *  This function allocates a object control block from
    166  *  the inactive chain of free object control blocks.
    167  */
    168 
    169 RTEMS_INLINE_ROUTINE Objects_Control *_Objects_Allocate(
    170   Objects_Information *information
    171 )
    172 {
    173   return (Objects_Control *) _Chain_Get( &information->Inactive );
    174 }
    175 
    176 /*PAGE
    177  *
    178  *  _Objects_Free
    179  *
    180  *  DESCRIPTION:
    181  *
    182  *  This function frees a object control block to the
    183  *  inactive chain of free object control blocks.
    184  */
    185 
    186 RTEMS_INLINE_ROUTINE void _Objects_Free(
     161 *  _Objects_Get_local_object
     162 *
     163 *  DESCRIPTION:
     164 *
     165 *  This function returns a pointer to the local_table object
     166 *  referenced by the index.
     167 */
     168
     169RTEMS_INLINE_ROUTINE Objects_Control *_Objects_Get_local_object(
    187170  Objects_Information *information,
     171  unsigned32           index
     172)
     173{
     174  if ( index > information->maximum)
     175    return NULL;
     176  return ( information->local_table[ index ] );
     177}
     178
     179/*PAGE
     180 *
     181 *  _Objects_Set_local_object
     182 *
     183 *  DESCRIPTION:
     184 *
     185 *  This function sets the pointer to the local_table object
     186 *  referenced by the index.
     187 */
     188
     189RTEMS_INLINE_ROUTINE void _Objects_Set_local_object(
     190  Objects_Information *information,
     191  unsigned32           index,
    188192  Objects_Control     *the_object
    189193)
    190194{
    191   _Chain_Append( &information->Inactive, &the_object->Node );
     195  if ( index <= information->maximum)
     196    information->local_table[ index ] = the_object;
     197}
     198
     199
     200/*PAGE
     201 *
     202 *  _Objects_Get_information
     203 *
     204 *  DESCRIPTION:
     205 *
     206 *  This function return the information structure given
     207 *  an id of an object.
     208 */
     209 
     210RTEMS_INLINE_ROUTINE Objects_Information *_Objects_Get_information(
     211  Objects_Id  id
     212)
     213{
     214  Objects_Classes  the_class;
     215
     216  the_class = _Objects_Get_class( id );
     217
     218  if ( !_Objects_Is_class_valid( the_class ) )
     219    return NULL;
     220
     221  return _Objects_Information_table[ the_class ];
    192222}
    193223
     
    211241
    212242  index = _Objects_Get_index( the_object->id );
    213   information->local_table[ index ] = the_object;
     243  _Objects_Set_local_object( information, index, the_object );
    214244
    215245  if ( information->is_string )
     
    237267
    238268  index = _Objects_Get_index( the_object->id );
    239   information->local_table[ index ] = (Objects_Control *) NULL;
     269  _Objects_Set_local_object( information, index, NULL );
    240270  _Objects_Clear_name( the_object->name, information->name_length );
    241271}
  • c/src/exec/score/macros/rtems/score/object.inl

    re9e01dd6 rf4a8ee1  
    9494/*PAGE
    9595 *
    96  *  _Objects_Allocate
     96 *  _Objects_Get_local_object
    9797 *
    9898 */
    9999
    100 #define _Objects_Allocate( _information )  \
    101   (Objects_Control *) _Chain_Get( &(_information)->Inactive )
     100#define _Objects_Get_local_object( information, index ) \
     101  ( ( index > information->maximum) ?  NULL : \
     102                       information->local_table[ index ] )
    102103
    103104/*PAGE
    104105 *
    105  *  _Objects_Free
     106 *  _Objects_Set_local_object
    106107 *
    107108 */
    108109
    109 #define _Objects_Free( _information, _the_object )  \
    110   _Chain_Append( &(_information)->Inactive, &(_the_object)->Node )
     110#define _Objects_Set_local_object( information, index, the_object ) \
     111  { \
     112    if ( index <= information->maximum) \
     113      information->local_table[ index ] = the_object; \
     114  }
     115
     116
     117/*PAGE
     118 *
     119 *  _Objects_Get_information
     120 *
     121 */
     122 
     123#define _Objects_Get_information( id ) \
     124 ( \
     125   ( !_Objects_Is_class_valid( _Objects_Get_class( id ) ) ) ? \
     126     NULL : \
     127     _Objects_Information_table[ _Objects_Get_class( id ) ] \
     128 )
    111129
    112130/*PAGE
  • c/src/exec/score/macros/rtems/score/userext.inl

    re9e01dd6 rf4a8ee1  
    2424 */
    2525
    26 #define _User_extensions_Handler_initialization( _initial_extensions ) \
     26#define _User_extensions_Handler_initialization( \
     27  number_of_extensions, _initial_extensions \
     28) \
    2729  { \
     30    User_extensions_Control *extension; \
     31    unsigned32               i; \
    2832    _Chain_Initialize_empty( &_User_extensions_List ); \
    2933    \
    3034    if ( (_initial_extensions) ) { \
    31       _User_extensions_Initial.Callouts = *(_initial_extensions); \
    32       _Chain_Append( \
    33         &_User_extensions_List, &_User_extensions_Initial.Node ); \
     35      for (i=0 ; i<number_of_extensions ; i++ ) { \
     36        extension = \
     37           _Workspace_Allocate_or_fatal_error( sizeof(User_extensions_Control) ); \
     38        \
     39        extension->Callouts = _initial_extensions[i]; \
     40        _Chain_Append( &_User_extensions_List, &extension->Node ); \
     41      } \
    3442    } \
    3543  }
  • c/src/exec/score/src/object.c

    re9e01dd6 rf4a8ee1  
    1515
    1616#include <rtems/system.h>
     17#include <rtems/score/address.h>
    1718#include <rtems/score/chain.h>
    1819#include <rtems/score/object.h>
     
    2324#include <rtems/score/wkspace.h>
    2425#include <rtems/score/sysstate.h>
     26#include <rtems/score/isr.h>
    2527
    2628/*PAGE
     
    6163  );
    6264#endif
     65}
     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
     79void _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 updating
     129     *  the information table.
     130     *
     131     *  If the maximum is minimum we do not have a table to copy. First time through.
     132     *
     133     *  The allocation has :
     134     *
     135     *      void            *objects[block_count];
     136     *      unsiged32        inactive_count[block_count];
     137     *      Objects_Name    *name_table[block_count];
     138     *      Objects_Control *local_table[maximum];
     139     *
     140     *  This is the order in memory. Watch changing the order. See the memcpy
     141     *  below.
     142     */
     143
     144    /*
     145     *  Up the block count and maximum
     146     */
     147
     148    block_count++;
     149   
     150    maximum = information->maximum + information->allocation_size;
     151
     152    /*
     153     *  Allocate the tables and break it up.
     154     */
     155   
     156    if ( information->auto_extend ) {
     157      object_blocks = (void**)
     158        _Workspace_Allocate(
     159          block_count * (sizeof(void *) + sizeof(unsigned32) + sizeof(Objects_Name *)) +
     160          ((maximum + minimum_index) * sizeof(Objects_Control *))
     161          );
     162
     163      if ( !object_blocks )
     164        return;
     165    }
     166    else {
     167      object_blocks = (void**)
     168        _Workspace_Allocate_or_fatal_error(
     169          block_count * (sizeof(void *) + sizeof(unsigned32) + sizeof(Objects_Name *)) +
     170          ((maximum + minimum_index) * sizeof(Objects_Control *))
     171        );
     172    }
     173
     174    /*
     175     *  Break the block into the various sections.
     176     *
     177     */
     178     
     179    inactive_per_block =
     180      (unsigned32 *) _Addresses_Add_offset( object_blocks, block_count * sizeof(void*) );
     181    name_table =
     182        (Objects_Name *) _Addresses_Add_offset( inactive_per_block,
     183                                                block_count * sizeof(unsigned32) );
     184    local_table =
     185      (Objects_Control **) _Addresses_Add_offset( name_table,
     186                                                  block_count * sizeof(Objects_Name *) );
     187   
     188    /*
     189     *  Take the block count down. Saves all the (block_count - 1) in the copies.
     190     */
     191
     192    block_count--;
     193   
     194    if ( information->maximum > minimum_index ) {
     195     
     196      /*
     197       *  Copy each section of the table over. This has to be performed as
     198       *  separate parts as size of each block has changed.
     199       */
     200   
     201      memcpy( object_blocks,
     202              information->object_blocks,
     203              block_count * sizeof(void*) );
     204      memcpy( inactive_per_block,
     205              information->inactive_per_block,
     206              block_count * sizeof(unsigned32) );
     207      memcpy( name_table,
     208              information->name_table,
     209              block_count * sizeof(Objects_Name *) );
     210      memcpy( local_table,
     211              information->local_table,
     212              (information->maximum + minimum_index) * sizeof(Objects_Control *) );
     213    }
     214    else {
     215
     216      /*
     217       *  Deal with the special case of the 0 to minimum_index
     218       */
     219      for ( index = 0; index < minimum_index; index++ ) {
     220        local_table[ index ] = NULL;
     221      }
     222    }
     223   
     224    /*
     225     *  Initialise the new entries in the table.
     226     */
     227   
     228    object_blocks[block_count] = NULL;
     229    inactive_per_block[block_count] = 0;
     230    name_table[block_count] = NULL;
     231
     232    for ( index=index_base ;
     233          index < ( information->allocation_size + index_base );
     234          index++ ) {
     235      local_table[ index ] = NULL;
     236    }
     237   
     238    _ISR_Disable( level );
     239
     240    old_tables = information->object_blocks;
     241   
     242    information->object_blocks = object_blocks;
     243    information->inactive_per_block = inactive_per_block;
     244    information->name_table = name_table;
     245    information->local_table = local_table;
     246    information->maximum = maximum;
     247    information->maximum_id =
     248      _Objects_Build_id(
     249        information->the_class, _Objects_Local_node, information->maximum
     250      );
     251
     252    _ISR_Enable( level );
     253
     254    if ( old_tables )
     255      _Workspace_Free( old_tables );
     256   
     257    block_count++;
     258  }
     259           
     260  /*
     261   *  Allocate the name table, and the objects
     262   */
     263
     264  if ( information->auto_extend ) {
     265    information->object_blocks[ block ] =
     266      _Workspace_Allocate(
     267        (information->allocation_size * information->name_length) +
     268        (information->allocation_size * information->size)
     269      );
     270
     271    if ( !information->object_blocks[ block ] )
     272      return;
     273  }
     274  else {
     275    information->object_blocks[ block ] =
     276      _Workspace_Allocate_or_fatal_error(
     277        (information->allocation_size * information->name_length) +
     278        (information->allocation_size * information->size)
     279      );
     280  }
     281 
     282  name_area = (Objects_Name *) information->object_blocks[ block ];
     283  information->name_table[ block ] = name_area;
     284
     285  /*
     286   *  Initialize objects .. add to a local chain first.
     287   */
     288
     289  _Chain_Initialize(
     290    &Inactive,
     291    _Addresses_Add_offset( information->object_blocks[ block ],
     292                           (information->allocation_size * information->name_length) ),
     293    information->allocation_size,
     294    information->size
     295  );
     296
     297  /*
     298   *  Move from the local chain, initialise, then append to the inactive chain
     299   */
     300
     301  index = index_base;
     302 
     303  while ( (the_object = (Objects_Control *) _Chain_Get( &Inactive ) ) != NULL ) {
     304   
     305    the_object->id =
     306      _Objects_Build_id(
     307        information->the_class, _Objects_Local_node, index
     308      );
     309     
     310    the_object->name = (void *) name_area;
     311
     312    name_area = _Addresses_Add_offset( name_area, information->name_length );
     313
     314    _Chain_Append( &information->Inactive, &the_object->Node );
     315
     316    index++;
     317  }
     318 
     319  information->inactive_per_block[ block ] = information->allocation_size;
     320  information->inactive += information->allocation_size;
     321}
     322
     323/*PAGE
     324 *
     325 *  _Objects_Shrink_information
     326 *
     327 *  This routine shrinks object information related data structures.
     328 *  The object's name and object space are released. The local_table
     329 *  etc block does not shrink. The InActive list needs to be scanned
     330 *  to find the objects are remove them.
     331 *  Input parameters:
     332 *    information     - object information table
     333 *    the_block       - the block to remove
     334 *
     335 *  Output parameters:  NONE
     336 */
     337
     338void _Objects_Shrink_information(
     339  Objects_Information *information
     340)
     341{
     342  Objects_Control  *the_object;
     343  Objects_Control  *extract_me;
     344  unsigned32        block_count;
     345  unsigned32        block;
     346  unsigned32        index_base;
     347  unsigned32        index;
     348
     349  /*
     350   * Search the list to find block or chunnk with all objects inactive.
     351   */
     352
     353  index_base = _Objects_Get_index( information->minimum_id );
     354  block_count = ( information->maximum - index_base ) / information->allocation_size;
     355 
     356  for ( block = 0; block < block_count; block++ ) {
     357    if ( information->inactive_per_block[ block ] == information->allocation_size ) {
     358
     359      /*
     360       * XXX - Not to sure how to use a chain where you need to iterate and
     361       *       and remove elements.
     362       */
     363     
     364      the_object = (Objects_Control *) information->Inactive.first;
     365
     366      /*
     367       *  Assume the Inactive chain is never empty at this point
     368       */
     369
     370      do {
     371        index = _Objects_Get_index( the_object->id );
     372
     373        if ((index >= index_base) &&
     374            (index < (index_base + information->allocation_size))) {
     375         
     376          /*
     377           *  Get the next node before the node is extracted
     378           */
     379         
     380          extract_me = the_object;
     381
     382          if ( !_Chain_Is_last( &the_object->Node ) )
     383            the_object = (Objects_Control *) the_object->Node.next;
     384          else
     385            the_object = NULL;
     386         
     387          _Chain_Extract( &extract_me->Node );
     388        }
     389        else {
     390          the_object = (Objects_Control *) the_object->Node.next;
     391        }
     392      }
     393      while ( the_object && !_Chain_Is_last( &the_object->Node ) );
     394
     395      /*
     396       *  Free the memory and reset the structures in the object' information
     397       */
     398
     399      _Workspace_Free( information->object_blocks[ block ] );
     400      information->name_table[ block ] = NULL;
     401      information->object_blocks[ block ] = NULL;
     402      information->inactive_per_block[ block ] = 0;
     403
     404      information->inactive -= information->allocation_size;
     405     
     406      return;
     407    }
     408   
     409    index_base += information->allocation_size;
     410  }
    63411}
    64412
     
    94442  unsigned32       minimum_index;
    95443  unsigned32       index;
    96   Objects_Control *the_object;
    97444  unsigned32       name_length;
    98   void            *name_area;
    99 
    100   information->maximum   = maximum;
    101   information->the_class = the_class;
    102   information->is_string = is_string;
    103   information->is_thread = is_thread;
    104 
     445
     446  information->the_class          = the_class;
     447  information->is_string          = is_string;
     448  information->is_thread          = is_thread;
     449 
     450  information->local_table        = 0;
     451  information->name_table         = 0;
     452  information->inactive_per_block = 0;
     453  information->object_blocks      = 0;
     454 
     455  information->inactive           = 0;
     456 
    105457  /*
    106458   *  Set the entry in the object information table.
     
    108460
    109461  _Objects_Information_table[ the_class ] = information;
     462
     463  /*
     464   *  Set the size of the object
     465   */
     466
     467  information->size = size;
     468 
     469  /*
     470   *  Are we operating in unlimited, or auto-extend mode
     471   */
     472
     473  information->auto_extend = (maximum & OBJECTS_UNLIMITED_OBJECTS) ? TRUE : FALSE;
     474  maximum &= ~OBJECTS_UNLIMITED_OBJECTS;
     475 
     476  /*
     477   *  The allocation unit is the maximum value
     478   */
     479
     480  information->allocation_size = maximum;
    110481
    111482  /*
     
    119490    _Objects_Build_id( the_class, _Objects_Local_node, minimum_index );
    120491
    121   information->maximum_id =
    122     _Objects_Build_id( the_class, _Objects_Local_node, maximum );
    123 
    124   /*
    125    *  Allocate local pointer table
    126    */
    127 
    128   information->local_table =
    129     (Objects_Control **) _Workspace_Allocate_or_fatal_error(
    130       (maximum + 1) * sizeof(Objects_Control *)
    131     );
    132 
    133   /*
    134    *  Allocate name table
     492  /*
     493   *  Calculate the maximum name length
    135494   */
    136495
     
    143502  information->name_length = name_length;
    144503
    145   name_area = (Objects_Name *)
    146     _Workspace_Allocate_or_fatal_error( (maximum + 1) * name_length );
    147   information->name_table = name_area;
    148 
    149   /*
    150    *  Initialize local pointer table
    151    */
    152 
    153   for ( index=0 ; index <= maximum ; index++ ) {
    154      information->local_table[ index ] = NULL;
    155   }
    156 
     504  _Chain_Initialize_empty( &information->Inactive );
     505   
    157506  /*
    158507   *  Initialize objects .. if there are any
    159508   */
    160509
    161   if ( maximum == 0 ) {
    162     _Chain_Initialize_empty( &information->Inactive );
    163   } else {
    164 
    165     _Chain_Initialize(
    166       &information->Inactive,
    167       _Workspace_Allocate_or_fatal_error( maximum * size ),
    168       maximum,
    169       size
    170     );
    171 
    172     the_object = (Objects_Control *) information->Inactive.first;
    173     for ( index=1; index <= maximum ; index++ ) {
    174       the_object->id =
    175         _Objects_Build_id( the_class, _Objects_Local_node, index );
    176      
    177       the_object->name = (void *) name_area;
    178 
    179       name_area = _Addresses_Add_offset( name_area, name_length );
    180 
    181       the_object = (Objects_Control *) the_object->Node.next;
    182     }
    183 
     510  if ( maximum ) {
     511
     512    /*
     513     *  Reset the maximum value. It will be updated when the information is
     514     *  extended.
     515     */
     516   
     517    information->maximum = 0;
     518   
     519    /*
     520     *  Always have the maximum size available so the current performance
     521     *  figures are create are met.  If the user moves past the maximum
     522     *  number then a performance hit is taken.
     523     */
     524   
     525    _Objects_Extend_information( information );
     526   
    184527  }
    185528
     
    200543   else
    201544     information->global_table = NULL;
     545}
     546
     547/*PAGE
     548 *
     549 *  _Objects_Allocate
     550 *
     551 *  DESCRIPTION:
     552 *
     553 *  This function allocates a object control block from
     554 *  the inactive chain of free object control blocks.
     555 */
     556
     557Objects_Control *_Objects_Allocate(
     558  Objects_Information *information
     559)
     560{
     561  Objects_Control *the_object = 
     562    (Objects_Control *) _Chain_Get( &information->Inactive );
     563
     564  if ( information->auto_extend ) {
     565    /*
     566     *  If the list is empty then we are out of objects and need to
     567     *  extend information base.
     568     */
     569 
     570    if ( !the_object ) {
     571      _Objects_Extend_information( information );
     572      the_object =  (Objects_Control *) _Chain_Get( &information->Inactive );
     573    }
     574 
     575    if ( the_object ) {
     576      unsigned32 block;
     577   
     578      block =
     579        _Objects_Get_index( the_object->id ) - _Objects_Get_index( information->minimum_id );
     580      block /= information->allocation_size;
     581     
     582      information->inactive_per_block[ block ]--;
     583      information->inactive--;
     584    }
     585  }
     586 
     587  return the_object;
     588}
     589
     590/*PAGE
     591 *
     592 *  _Objects_Free
     593 *
     594 *  DESCRIPTION:
     595 *
     596 *  This function frees a object control block to the
     597 *  inactive chain of free object control blocks.
     598 */
     599
     600void _Objects_Free(
     601  Objects_Information *information,
     602  Objects_Control     *the_object
     603)
     604{
     605  unsigned32  allocation_size = information->allocation_size;
     606
     607  _Chain_Append( &information->Inactive, &the_object->Node );
     608
     609  if ( information->auto_extend ) {
     610    unsigned32  block;
     611   
     612    block =
     613      _Objects_Get_index( the_object->id ) - _Objects_Get_index( information->minimum_id );
     614    block /= information->allocation_size;
     615     
     616    information->inactive_per_block[ block ]++;
     617    information->inactive++;
     618 
     619    /*
     620     *  Check if the threshold level has been met of
     621     *  1.5 x allocation_size are free.
     622     */
     623
     624    if ( information->inactive > ( allocation_size + ( allocation_size >> 1 ) ) ) {
     625      _Objects_Shrink_information( information );
     626    }
     627  }
    202628}
    203629
     
    342768{
    343769  boolean                    search_local_node;
    344   Objects_Control          **objects;
    345770  Objects_Control           *the_object;
    346771  unsigned32                 index;
     
    359784
    360785  if ( search_local_node ) {
    361     objects = information->local_table;
    362 
    363786    name_length = information->name_length;
    364787
     
    368791    for ( index = 1; index <= information->maximum; index++ ) {
    369792
    370       the_object = objects[ index ];
     793      the_object = information->local_table[ index ];
    371794
    372795      if ( !the_object || !the_object->name )
     
    419842  unsigned32       index;
    420843
    421   index = id - information->minimum_id;
     844  index = _Objects_Get_index( id );
    422845
    423846  if ( information->maximum >= index ) {
    424847    _Thread_Disable_dispatch();
    425     if ( (the_object = information->local_table[index+1]) != NULL ) {
     848    if ( (the_object = _Objects_Get_local_object( information, index )) != NULL ) {
    426849      *location = OBJECTS_LOCAL;
    427850      return( the_object );
     
    506929}
    507930
    508 /*PAGE
    509  *
    510  *  _Objects_Get_information
    511  *
    512  *  XXX
    513  */
    514  
    515 Objects_Information *_Objects_Get_information(
    516   Objects_Id  id
    517 )
    518 {
    519   Objects_Classes  the_class;
    520 
    521   the_class = _Objects_Get_class( id );
    522 
    523   if ( !_Objects_Is_class_valid( the_class ) )
    524     return NULL;
    525 
    526   return _Objects_Information_table[ the_class ];
    527 }
    528 
  • c/src/make/compilers/gcc-target-default.cfg

    re9e01dd6 rf4a8ee1  
    7373CXX += $(GCCSPECS)
    7474
    75 CPPFLAGS += -I$(srcdir) $(INCLUDE_NETWORKING)
     75CPPFLAGS += $(INCLUDE_NETWORKING)
    7676
    7777# default location of Standard C Library
  • c/src/tests/samples/Makefile.in

    re9e01dd6 rf4a8ee1  
    2828FP_TESTS = paranoia
    2929
    30 SUB_DIRS=hello ticker base_sp \
     30SUB_DIRS=hello ticker base_sp unlimited \
    3131         $(MP_TESTS) $(CPLUSPLUS_TESTS) $(FP_TESTS)
    3232
  • cpukit/rtems/src/msg.c

    re9e01dd6 rf4a8ee1  
    3131#include <rtems/rtems/options.h>
    3232#include <rtems/rtems/support.h>
     33
     34/*PAGE
     35 *
     36 *  _MESSAGE_QUEUE_CORE_MESSAGE_QUEUE_MP_SUPPORT
     37 *
     38 *  Condition support for the MP. Helps the macro build.
     39 *
     40 */
     41
     42#if defined(RTEMS_MULTIPROCESSING)
     43#define _MESSAGE_QUEUE_CORE_MESSAGE_QUEUE_MP_SUPPORT _Message_queue_Core_message_queue_mp_support
     44#else
     45#define _MESSAGE_QUEUE_CORE_MESSAGE_QUEUE_MP_SUPPORT NULL
     46#endif
    3347
    3448/*PAGE
     
    451465                      size,
    452466                      id,
    453 #if defined(RTEMS_MULTIPROCESSING)
    454                       _Message_queue_Core_message_queue_mp_support,
    455 #else
    456                       NULL,
    457 #endif
     467                      _MESSAGE_QUEUE_CORE_MESSAGE_QUEUE_MP_SUPPORT,
    458468                      count
    459469                    );
     
    719729                          size,
    720730                          id,
    721 #if defined(RTEMS_MULTIPROCESSING)
    722                           _Message_queue_Core_message_queue_mp_support
    723 #else
    724                           NULL
    725 #endif
     731                          _MESSAGE_QUEUE_CORE_MESSAGE_QUEUE_MP_SUPPORT
    726732                        );
    727733          break;
     
    732738                          size,
    733739                          id,
    734 #if defined(RTEMS_MULTIPROCESSING)
    735                           _Message_queue_Core_message_queue_mp_support
    736 #else
    737                           NULL
    738 #endif
     740                          _MESSAGE_QUEUE_CORE_MESSAGE_QUEUE_MP_SUPPORT
    739741                        );
    740742          break;
  • cpukit/sapi/include/rtems/config.h

    re9e01dd6 rf4a8ee1  
    2222#endif
    2323
     24/*
     25 *  Unlimited object support. Changes the configuration table entry for POSIX
     26 *  or RTEMS APIs to bounded only by the memory of the work-space.
     27 *
     28 *  Use the macro to define the resource unlimited before placing in the configuration
     29 *  table.
     30 */
     31
     32#include <rtems/score/object.h>
     33#define RTEMS_UNLIMITED_OBJECTS OBJECTS_UNLIMITED_OBJECTS
     34 
     35#define rtems_resource_unlimited(resource) \
     36  ( resource | RTEMS_UNLIMITED_OBJECTS )
     37   
    2438/*
    2539 *  This is kind of kludgy but it allows targets to totally ignore the
  • cpukit/score/include/rtems/score/object.h

    re9e01dd6 rf4a8ee1  
    2525
    2626#include <rtems/score/chain.h>
     27
     28/*
     29 *  Mask to enable unlimited objects
     30 *
     31 *  XXX - needs to be moved to the API some-where
     32 */
     33
     34#define OBJECTS_UNLIMITED_OBJECTS 0x80000000
    2735
    2836/*
     
    122130
    123131typedef struct {
    124   Chain_Node    Node;
    125   Objects_Id    id;
    126   Objects_Name  name;
     132  Chain_Node     Node;
     133  Objects_Id     id;
     134  Objects_Name   name;
    127135}   Objects_Control;
    128136
     
    133141
    134142typedef struct {
    135   Objects_Classes   the_class;       /* Class of this object */
    136   Objects_Id        minimum_id;      /* minimum valid id of this type */
    137   Objects_Id        maximum_id;      /* maximum valid id of this type */
    138   unsigned32        maximum;         /* maximum number of objects */
    139   Objects_Control **local_table;     /* table of local object pointers */
    140   Objects_Name     *name_table;      /* table of local object names */
    141   Chain_Control    *global_table;    /* pointer to global table */
    142   Chain_Control     Inactive;        /* chain of inactive ctl blocks */
    143   boolean           is_string;       /* TRUE if names are strings */
    144   unsigned32        name_length;     /* maximum length of names */
    145   boolean           is_thread;       /* TRUE if these are threads */
    146                                      /*   irregardless of API */
     143  Objects_Classes   the_class;          /* Class of this object */
     144  Objects_Id        minimum_id;         /* minimum valid id of this type */
     145  Objects_Id        maximum_id;         /* maximum valid id of this type */
     146  unsigned32        maximum;            /* maximum number of objects */
     147  boolean           auto_extend;        /* TRUE if unlimited objects */
     148  unsigned32        allocation_size;    /* number of objects in a block */
     149  unsigned32        size;               /* size of the objects */
     150  Objects_Control **local_table;
     151  Objects_Name     *name_table;
     152  Chain_Control    *global_table;       /* pointer to global table */
     153  Chain_Control     Inactive;           /* chain of inactive ctl blocks */
     154  unsigned32        inactive;           /* number of objects on the InActive list */
     155  unsigned32       *inactive_per_block; /* used to release a block */
     156  void            **object_blocks;      /* the object memory to remove */
     157  boolean           is_string;          /* TRUE if names are strings */
     158  unsigned32        name_length;        /* maximum length of names */
     159  boolean           is_thread;          /* TRUE if these are threads */
     160                                        /*   irregardless of API */
    147161}   Objects_Information;
    148162
     
    206220  unsigned32 maximum_nodes,
    207221  unsigned32 maximum_global_objects
     222);
     223
     224/*
     225 *  _Objects_Extend_information
     226 *
     227 *  DESCRIPTION:
     228 *
     229 *  This function extends an object class information record.
     230 */
     231
     232void _Objects_Extend_information(
     233  Objects_Information *information
     234);
     235
     236/*
     237 *  _Objects_Shrink_information
     238 *
     239 *  DESCRIPTION:
     240 *
     241 *  This function shrink an object class information record.
     242 */
     243
     244void _Objects_Shrink_information(
     245  Objects_Information *information
    208246);
    209247
     
    233271);
    234272
     273/*PAGE
     274 *
     275 *  _Objects_Allocate
     276 *
     277 *  DESCRIPTION:
     278 *
     279 *  This function allocates a object control block from
     280 *  the inactive chain of free object control blocks.
     281 */
     282
     283Objects_Control *_Objects_Allocate(
     284  Objects_Information *information
     285);
     286
     287/*PAGE
     288 *
     289 *  _Objects_Free
     290 *
     291 *  DESCRIPTION:
     292 *
     293 *  This function frees a object control block to the
     294 *  inactive chain of free object control blocks.
     295 */
     296
     297void _Objects_Free(
     298  Objects_Information *information,
     299  Objects_Control     *the_object
     300);
     301
    235302/*
    236303 *  _Objects_Clear_name
     
    371438
    372439/*
    373  *  _Objects_Get_information
    374  *
    375  *  DESCRIPTION:
    376  *
    377  *  Returns the information control block for the class of objects
    378  *  corresponding to this id.
    379  */
    380 
    381 Objects_Information *_Objects_Get_information(
    382   Objects_Id  id
    383 );
    384  
    385 /*
    386440 *  Pieces of object.inl are promoted out to the user
    387441 */
  • cpukit/score/inline/rtems/score/coremsg.inl

    re9e01dd6 rf4a8ee1  
    4242    size,
    4343    id,
     44#if defined(RTEMS_MULTIPROCESSING)
    4445    api_message_queue_mp_support,
     46#else
     47    NULL,
     48#endif
    4549    CORE_MESSAGE_QUEUE_SEND_REQUEST
    4650  );
     
    6973    size,
    7074    id,
     75#if defined(RTEMS_MULTIPROCESSING)
    7176    api_message_queue_mp_support,
     77#else
     78    NULL,
     79#endif
    7280    CORE_MESSAGE_QUEUE_URGENT_REQUEST
    7381 );
  • cpukit/score/inline/rtems/score/object.inl

    re9e01dd6 rf4a8ee1  
    159159/*PAGE
    160160 *
    161  *  _Objects_Allocate
    162  *
    163  *  DESCRIPTION:
    164  *
    165  *  This function allocates a object control block from
    166  *  the inactive chain of free object control blocks.
    167  */
    168 
    169 RTEMS_INLINE_ROUTINE Objects_Control *_Objects_Allocate(
    170   Objects_Information *information
    171 )
    172 {
    173   return (Objects_Control *) _Chain_Get( &information->Inactive );
    174 }
    175 
    176 /*PAGE
    177  *
    178  *  _Objects_Free
    179  *
    180  *  DESCRIPTION:
    181  *
    182  *  This function frees a object control block to the
    183  *  inactive chain of free object control blocks.
    184  */
    185 
    186 RTEMS_INLINE_ROUTINE void _Objects_Free(
     161 *  _Objects_Get_local_object
     162 *
     163 *  DESCRIPTION:
     164 *
     165 *  This function returns a pointer to the local_table object
     166 *  referenced by the index.
     167 */
     168
     169RTEMS_INLINE_ROUTINE Objects_Control *_Objects_Get_local_object(
    187170  Objects_Information *information,
     171  unsigned32           index
     172)
     173{
     174  if ( index > information->maximum)
     175    return NULL;
     176  return ( information->local_table[ index ] );
     177}
     178
     179/*PAGE
     180 *
     181 *  _Objects_Set_local_object
     182 *
     183 *  DESCRIPTION:
     184 *
     185 *  This function sets the pointer to the local_table object
     186 *  referenced by the index.
     187 */
     188
     189RTEMS_INLINE_ROUTINE void _Objects_Set_local_object(
     190  Objects_Information *information,
     191  unsigned32           index,
    188192  Objects_Control     *the_object
    189193)
    190194{
    191   _Chain_Append( &information->Inactive, &the_object->Node );
     195  if ( index <= information->maximum)
     196    information->local_table[ index ] = the_object;
     197}
     198
     199
     200/*PAGE
     201 *
     202 *  _Objects_Get_information
     203 *
     204 *  DESCRIPTION:
     205 *
     206 *  This function return the information structure given
     207 *  an id of an object.
     208 */
     209 
     210RTEMS_INLINE_ROUTINE Objects_Information *_Objects_Get_information(
     211  Objects_Id  id
     212)
     213{
     214  Objects_Classes  the_class;
     215
     216  the_class = _Objects_Get_class( id );
     217
     218  if ( !_Objects_Is_class_valid( the_class ) )
     219    return NULL;
     220
     221  return _Objects_Information_table[ the_class ];
    192222}
    193223
     
    211241
    212242  index = _Objects_Get_index( the_object->id );
    213   information->local_table[ index ] = the_object;
     243  _Objects_Set_local_object( information, index, the_object );
    214244
    215245  if ( information->is_string )
     
    237267
    238268  index = _Objects_Get_index( the_object->id );
    239   information->local_table[ index ] = (Objects_Control *) NULL;
     269  _Objects_Set_local_object( information, index, NULL );
    240270  _Objects_Clear_name( the_object->name, information->name_length );
    241271}
  • cpukit/score/macros/rtems/score/object.inl

    re9e01dd6 rf4a8ee1  
    9494/*PAGE
    9595 *
    96  *  _Objects_Allocate
     96 *  _Objects_Get_local_object
    9797 *
    9898 */
    9999
    100 #define _Objects_Allocate( _information )  \
    101   (Objects_Control *) _Chain_Get( &(_information)->Inactive )
     100#define _Objects_Get_local_object( information, index ) \
     101  ( ( index > information->maximum) ?  NULL : \
     102                       information->local_table[ index ] )
    102103
    103104/*PAGE
    104105 *
    105  *  _Objects_Free
     106 *  _Objects_Set_local_object
    106107 *
    107108 */
    108109
    109 #define _Objects_Free( _information, _the_object )  \
    110   _Chain_Append( &(_information)->Inactive, &(_the_object)->Node )
     110#define _Objects_Set_local_object( information, index, the_object ) \
     111  { \
     112    if ( index <= information->maximum) \
     113      information->local_table[ index ] = the_object; \
     114  }
     115
     116
     117/*PAGE
     118 *
     119 *  _Objects_Get_information
     120 *
     121 */
     122 
     123#define _Objects_Get_information( id ) \
     124 ( \
     125   ( !_Objects_Is_class_valid( _Objects_Get_class( id ) ) ) ? \
     126     NULL : \
     127     _Objects_Information_table[ _Objects_Get_class( id ) ] \
     128 )
    111129
    112130/*PAGE
  • cpukit/score/macros/rtems/score/userext.inl

    re9e01dd6 rf4a8ee1  
    2424 */
    2525
    26 #define _User_extensions_Handler_initialization( _initial_extensions ) \
     26#define _User_extensions_Handler_initialization( \
     27  number_of_extensions, _initial_extensions \
     28) \
    2729  { \
     30    User_extensions_Control *extension; \
     31    unsigned32               i; \
    2832    _Chain_Initialize_empty( &_User_extensions_List ); \
    2933    \
    3034    if ( (_initial_extensions) ) { \
    31       _User_extensions_Initial.Callouts = *(_initial_extensions); \
    32       _Chain_Append( \
    33         &_User_extensions_List, &_User_extensions_Initial.Node ); \
     35      for (i=0 ; i<number_of_extensions ; i++ ) { \
     36        extension = \
     37           _Workspace_Allocate_or_fatal_error( sizeof(User_extensions_Control) ); \
     38        \
     39        extension->Callouts = _initial_extensions[i]; \
     40        _Chain_Append( &_User_extensions_List, &extension->Node ); \
     41      } \
    3442    } \
    3543  }
  • cpukit/score/src/object.c

    re9e01dd6 rf4a8ee1  
    1515
    1616#include <rtems/system.h>
     17#include <rtems/score/address.h>
    1718#include <rtems/score/chain.h>
    1819#include <rtems/score/object.h>
     
    2324#include <rtems/score/wkspace.h>
    2425#include <rtems/score/sysstate.h>
     26#include <rtems/score/isr.h>
    2527
    2628/*PAGE
     
    6163  );
    6264#endif
     65}
     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
     79void _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 updating
     129     *  the information table.
     130     *
     131     *  If the maximum is minimum we do not have a table to copy. First time through.
     132     *
     133     *  The allocation has :
     134     *
     135     *      void            *objects[block_count];
     136     *      unsiged32        inactive_count[block_count];
     137     *      Objects_Name    *name_table[block_count];
     138     *      Objects_Control *local_table[maximum];
     139     *
     140     *  This is the order in memory. Watch changing the order. See the memcpy
     141     *  below.
     142     */
     143
     144    /*
     145     *  Up the block count and maximum
     146     */
     147
     148    block_count++;
     149   
     150    maximum = information->maximum + information->allocation_size;
     151
     152    /*
     153     *  Allocate the tables and break it up.
     154     */
     155   
     156    if ( information->auto_extend ) {
     157      object_blocks = (void**)
     158        _Workspace_Allocate(
     159          block_count * (sizeof(void *) + sizeof(unsigned32) + sizeof(Objects_Name *)) +
     160          ((maximum + minimum_index) * sizeof(Objects_Control *))
     161          );
     162
     163      if ( !object_blocks )
     164        return;
     165    }
     166    else {
     167      object_blocks = (void**)
     168        _Workspace_Allocate_or_fatal_error(
     169          block_count * (sizeof(void *) + sizeof(unsigned32) + sizeof(Objects_Name *)) +
     170          ((maximum + minimum_index) * sizeof(Objects_Control *))
     171        );
     172    }
     173
     174    /*
     175     *  Break the block into the various sections.
     176     *
     177     */
     178     
     179    inactive_per_block =
     180      (unsigned32 *) _Addresses_Add_offset( object_blocks, block_count * sizeof(void*) );
     181    name_table =
     182        (Objects_Name *) _Addresses_Add_offset( inactive_per_block,
     183                                                block_count * sizeof(unsigned32) );
     184    local_table =
     185      (Objects_Control **) _Addresses_Add_offset( name_table,
     186                                                  block_count * sizeof(Objects_Name *) );
     187   
     188    /*
     189     *  Take the block count down. Saves all the (block_count - 1) in the copies.
     190     */
     191
     192    block_count--;
     193   
     194    if ( information->maximum > minimum_index ) {
     195     
     196      /*
     197       *  Copy each section of the table over. This has to be performed as
     198       *  separate parts as size of each block has changed.
     199       */
     200   
     201      memcpy( object_blocks,
     202              information->object_blocks,
     203              block_count * sizeof(void*) );
     204      memcpy( inactive_per_block,
     205              information->inactive_per_block,
     206              block_count * sizeof(unsigned32) );
     207      memcpy( name_table,
     208              information->name_table,
     209              block_count * sizeof(Objects_Name *) );
     210      memcpy( local_table,
     211              information->local_table,
     212              (information->maximum + minimum_index) * sizeof(Objects_Control *) );
     213    }
     214    else {
     215
     216      /*
     217       *  Deal with the special case of the 0 to minimum_index
     218       */
     219      for ( index = 0; index < minimum_index; index++ ) {
     220        local_table[ index ] = NULL;
     221      }
     222    }
     223   
     224    /*
     225     *  Initialise the new entries in the table.
     226     */
     227   
     228    object_blocks[block_count] = NULL;
     229    inactive_per_block[block_count] = 0;
     230    name_table[block_count] = NULL;
     231
     232    for ( index=index_base ;
     233          index < ( information->allocation_size + index_base );
     234          index++ ) {
     235      local_table[ index ] = NULL;
     236    }
     237   
     238    _ISR_Disable( level );
     239
     240    old_tables = information->object_blocks;
     241   
     242    information->object_blocks = object_blocks;
     243    information->inactive_per_block = inactive_per_block;
     244    information->name_table = name_table;
     245    information->local_table = local_table;
     246    information->maximum = maximum;
     247    information->maximum_id =
     248      _Objects_Build_id(
     249        information->the_class, _Objects_Local_node, information->maximum
     250      );
     251
     252    _ISR_Enable( level );
     253
     254    if ( old_tables )
     255      _Workspace_Free( old_tables );
     256   
     257    block_count++;
     258  }
     259           
     260  /*
     261   *  Allocate the name table, and the objects
     262   */
     263
     264  if ( information->auto_extend ) {
     265    information->object_blocks[ block ] =
     266      _Workspace_Allocate(
     267        (information->allocation_size * information->name_length) +
     268        (information->allocation_size * information->size)
     269      );
     270
     271    if ( !information->object_blocks[ block ] )
     272      return;
     273  }
     274  else {
     275    information->object_blocks[ block ] =
     276      _Workspace_Allocate_or_fatal_error(
     277        (information->allocation_size * information->name_length) +
     278        (information->allocation_size * information->size)
     279      );
     280  }
     281 
     282  name_area = (Objects_Name *) information->object_blocks[ block ];
     283  information->name_table[ block ] = name_area;
     284
     285  /*
     286   *  Initialize objects .. add to a local chain first.
     287   */
     288
     289  _Chain_Initialize(
     290    &Inactive,
     291    _Addresses_Add_offset( information->object_blocks[ block ],
     292                           (information->allocation_size * information->name_length) ),
     293    information->allocation_size,
     294    information->size
     295  );
     296
     297  /*
     298   *  Move from the local chain, initialise, then append to the inactive chain
     299   */
     300
     301  index = index_base;
     302 
     303  while ( (the_object = (Objects_Control *) _Chain_Get( &Inactive ) ) != NULL ) {
     304   
     305    the_object->id =
     306      _Objects_Build_id(
     307        information->the_class, _Objects_Local_node, index
     308      );
     309     
     310    the_object->name = (void *) name_area;
     311
     312    name_area = _Addresses_Add_offset( name_area, information->name_length );
     313
     314    _Chain_Append( &information->Inactive, &the_object->Node );
     315
     316    index++;
     317  }
     318 
     319  information->inactive_per_block[ block ] = information->allocation_size;
     320  information->inactive += information->allocation_size;
     321}
     322
     323/*PAGE
     324 *
     325 *  _Objects_Shrink_information
     326 *
     327 *  This routine shrinks object information related data structures.
     328 *  The object's name and object space are released. The local_table
     329 *  etc block does not shrink. The InActive list needs to be scanned
     330 *  to find the objects are remove them.
     331 *  Input parameters:
     332 *    information     - object information table
     333 *    the_block       - the block to remove
     334 *
     335 *  Output parameters:  NONE
     336 */
     337
     338void _Objects_Shrink_information(
     339  Objects_Information *information
     340)
     341{
     342  Objects_Control  *the_object;
     343  Objects_Control  *extract_me;
     344  unsigned32        block_count;
     345  unsigned32        block;
     346  unsigned32        index_base;
     347  unsigned32        index;
     348
     349  /*
     350   * Search the list to find block or chunnk with all objects inactive.
     351   */
     352
     353  index_base = _Objects_Get_index( information->minimum_id );
     354  block_count = ( information->maximum - index_base ) / information->allocation_size;
     355 
     356  for ( block = 0; block < block_count; block++ ) {
     357    if ( information->inactive_per_block[ block ] == information->allocation_size ) {
     358
     359      /*
     360       * XXX - Not to sure how to use a chain where you need to iterate and
     361       *       and remove elements.
     362       */
     363     
     364      the_object = (Objects_Control *) information->Inactive.first;
     365
     366      /*
     367       *  Assume the Inactive chain is never empty at this point
     368       */
     369
     370      do {
     371        index = _Objects_Get_index( the_object->id );
     372
     373        if ((index >= index_base) &&
     374            (index < (index_base + information->allocation_size))) {
     375         
     376          /*
     377           *  Get the next node before the node is extracted
     378           */
     379         
     380          extract_me = the_object;
     381
     382          if ( !_Chain_Is_last( &the_object->Node ) )
     383            the_object = (Objects_Control *) the_object->Node.next;
     384          else
     385            the_object = NULL;
     386         
     387          _Chain_Extract( &extract_me->Node );
     388        }
     389        else {
     390          the_object = (Objects_Control *) the_object->Node.next;
     391        }
     392      }
     393      while ( the_object && !_Chain_Is_last( &the_object->Node ) );
     394
     395      /*
     396       *  Free the memory and reset the structures in the object' information
     397       */
     398
     399      _Workspace_Free( information->object_blocks[ block ] );
     400      information->name_table[ block ] = NULL;
     401      information->object_blocks[ block ] = NULL;
     402      information->inactive_per_block[ block ] = 0;
     403
     404      information->inactive -= information->allocation_size;
     405     
     406      return;
     407    }
     408   
     409    index_base += information->allocation_size;
     410  }
    63411}
    64412
     
    94442  unsigned32       minimum_index;
    95443  unsigned32       index;
    96   Objects_Control *the_object;
    97444  unsigned32       name_length;
    98   void            *name_area;
    99 
    100   information->maximum   = maximum;
    101   information->the_class = the_class;
    102   information->is_string = is_string;
    103   information->is_thread = is_thread;
    104 
     445
     446  information->the_class          = the_class;
     447  information->is_string          = is_string;
     448  information->is_thread          = is_thread;
     449 
     450  information->local_table        = 0;
     451  information->name_table         = 0;
     452  information->inactive_per_block = 0;
     453  information->object_blocks      = 0;
     454 
     455  information->inactive           = 0;
     456 
    105457  /*
    106458   *  Set the entry in the object information table.
     
    108460
    109461  _Objects_Information_table[ the_class ] = information;
     462
     463  /*
     464   *  Set the size of the object
     465   */
     466
     467  information->size = size;
     468 
     469  /*
     470   *  Are we operating in unlimited, or auto-extend mode
     471   */
     472
     473  information->auto_extend = (maximum & OBJECTS_UNLIMITED_OBJECTS) ? TRUE : FALSE;
     474  maximum &= ~OBJECTS_UNLIMITED_OBJECTS;
     475 
     476  /*
     477   *  The allocation unit is the maximum value
     478   */
     479
     480  information->allocation_size = maximum;
    110481
    111482  /*
     
    119490    _Objects_Build_id( the_class, _Objects_Local_node, minimum_index );
    120491
    121   information->maximum_id =
    122     _Objects_Build_id( the_class, _Objects_Local_node, maximum );
    123 
    124   /*
    125    *  Allocate local pointer table
    126    */
    127 
    128   information->local_table =
    129     (Objects_Control **) _Workspace_Allocate_or_fatal_error(
    130       (maximum + 1) * sizeof(Objects_Control *)
    131     );
    132 
    133   /*
    134    *  Allocate name table
     492  /*
     493   *  Calculate the maximum name length
    135494   */
    136495
     
    143502  information->name_length = name_length;
    144503
    145   name_area = (Objects_Name *)
    146     _Workspace_Allocate_or_fatal_error( (maximum + 1) * name_length );
    147   information->name_table = name_area;
    148 
    149   /*
    150    *  Initialize local pointer table
    151    */
    152 
    153   for ( index=0 ; index <= maximum ; index++ ) {
    154      information->local_table[ index ] = NULL;
    155   }
    156 
     504  _Chain_Initialize_empty( &information->Inactive );
     505   
    157506  /*
    158507   *  Initialize objects .. if there are any
    159508   */
    160509
    161   if ( maximum == 0 ) {
    162     _Chain_Initialize_empty( &information->Inactive );
    163   } else {
    164 
    165     _Chain_Initialize(
    166       &information->Inactive,
    167       _Workspace_Allocate_or_fatal_error( maximum * size ),
    168       maximum,
    169       size
    170     );
    171 
    172     the_object = (Objects_Control *) information->Inactive.first;
    173     for ( index=1; index <= maximum ; index++ ) {
    174       the_object->id =
    175         _Objects_Build_id( the_class, _Objects_Local_node, index );
    176      
    177       the_object->name = (void *) name_area;
    178 
    179       name_area = _Addresses_Add_offset( name_area, name_length );
    180 
    181       the_object = (Objects_Control *) the_object->Node.next;
    182     }
    183 
     510  if ( maximum ) {
     511
     512    /*
     513     *  Reset the maximum value. It will be updated when the information is
     514     *  extended.
     515     */
     516   
     517    information->maximum = 0;
     518   
     519    /*
     520     *  Always have the maximum size available so the current performance
     521     *  figures are create are met.  If the user moves past the maximum
     522     *  number then a performance hit is taken.
     523     */
     524   
     525    _Objects_Extend_information( information );
     526   
    184527  }
    185528
     
    200543   else
    201544     information->global_table = NULL;
     545}
     546
     547/*PAGE
     548 *
     549 *  _Objects_Allocate
     550 *
     551 *  DESCRIPTION:
     552 *
     553 *  This function allocates a object control block from
     554 *  the inactive chain of free object control blocks.
     555 */
     556
     557Objects_Control *_Objects_Allocate(
     558  Objects_Information *information
     559)
     560{
     561  Objects_Control *the_object = 
     562    (Objects_Control *) _Chain_Get( &information->Inactive );
     563
     564  if ( information->auto_extend ) {
     565    /*
     566     *  If the list is empty then we are out of objects and need to
     567     *  extend information base.
     568     */
     569 
     570    if ( !the_object ) {
     571      _Objects_Extend_information( information );
     572      the_object =  (Objects_Control *) _Chain_Get( &information->Inactive );
     573    }
     574 
     575    if ( the_object ) {
     576      unsigned32 block;
     577   
     578      block =
     579        _Objects_Get_index( the_object->id ) - _Objects_Get_index( information->minimum_id );
     580      block /= information->allocation_size;
     581     
     582      information->inactive_per_block[ block ]--;
     583      information->inactive--;
     584    }
     585  }
     586 
     587  return the_object;
     588}
     589
     590/*PAGE
     591 *
     592 *  _Objects_Free
     593 *
     594 *  DESCRIPTION:
     595 *
     596 *  This function frees a object control block to the
     597 *  inactive chain of free object control blocks.
     598 */
     599
     600void _Objects_Free(
     601  Objects_Information *information,
     602  Objects_Control     *the_object
     603)
     604{
     605  unsigned32  allocation_size = information->allocation_size;
     606
     607  _Chain_Append( &information->Inactive, &the_object->Node );
     608
     609  if ( information->auto_extend ) {
     610    unsigned32  block;
     611   
     612    block =
     613      _Objects_Get_index( the_object->id ) - _Objects_Get_index( information->minimum_id );
     614    block /= information->allocation_size;
     615     
     616    information->inactive_per_block[ block ]++;
     617    information->inactive++;
     618 
     619    /*
     620     *  Check if the threshold level has been met of
     621     *  1.5 x allocation_size are free.
     622     */
     623
     624    if ( information->inactive > ( allocation_size + ( allocation_size >> 1 ) ) ) {
     625      _Objects_Shrink_information( information );
     626    }
     627  }
    202628}
    203629
     
    342768{
    343769  boolean                    search_local_node;
    344   Objects_Control          **objects;
    345770  Objects_Control           *the_object;
    346771  unsigned32                 index;
     
    359784
    360785  if ( search_local_node ) {
    361     objects = information->local_table;
    362 
    363786    name_length = information->name_length;
    364787
     
    368791    for ( index = 1; index <= information->maximum; index++ ) {
    369792
    370       the_object = objects[ index ];
     793      the_object = information->local_table[ index ];
    371794
    372795      if ( !the_object || !the_object->name )
     
    419842  unsigned32       index;
    420843
    421   index = id - information->minimum_id;
     844  index = _Objects_Get_index( id );
    422845
    423846  if ( information->maximum >= index ) {
    424847    _Thread_Disable_dispatch();
    425     if ( (the_object = information->local_table[index+1]) != NULL ) {
     848    if ( (the_object = _Objects_Get_local_object( information, index )) != NULL ) {
    426849      *location = OBJECTS_LOCAL;
    427850      return( the_object );
     
    506929}
    507930
    508 /*PAGE
    509  *
    510  *  _Objects_Get_information
    511  *
    512  *  XXX
    513  */
    514  
    515 Objects_Information *_Objects_Get_information(
    516   Objects_Id  id
    517 )
    518 {
    519   Objects_Classes  the_class;
    520 
    521   the_class = _Objects_Get_class( id );
    522 
    523   if ( !_Objects_Is_class_valid( the_class ) )
    524     return NULL;
    525 
    526   return _Objects_Information_table[ the_class ];
    527 }
    528 
  • make/compilers/gcc-target-default.cfg

    re9e01dd6 rf4a8ee1  
    7373CXX += $(GCCSPECS)
    7474
    75 CPPFLAGS += -I$(srcdir) $(INCLUDE_NETWORKING)
     75CPPFLAGS += $(INCLUDE_NETWORKING)
    7676
    7777# default location of Standard C Library
Note: See TracChangeset for help on using the changeset viewer.