summaryrefslogtreecommitdiffstats
path: root/cpukit/score
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1999-03-17 16:01:03 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1999-03-17 16:01:03 +0000
commitf4a8ee1c55788aeb053ede7571b07906a9847a45 (patch)
tree7417825a9a351aaf100374b08d314756523bef5f /cpukit/score
parente9e01dd61f628c4056c93e979086069be4e491e6 (diff)
downloadrtems-f4a8ee1c55788aeb053ede7571b07906a9847a45.tar.bz2
Unlimited objects patch from Chris Johns <ccj@acm.org>. 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.
Diffstat (limited to '')
-rw-r--r--cpukit/score/include/rtems/score/object.h110
-rw-r--r--cpukit/score/inline/rtems/score/coremsg.inl8
-rw-r--r--cpukit/score/inline/rtems/score/object.inl56
-rw-r--r--cpukit/score/macros/rtems/score/object.inl30
-rw-r--r--cpukit/score/macros/rtems/score/userext.inl16
-rw-r--r--cpukit/score/src/object.c564
6 files changed, 652 insertions, 132 deletions
diff --git a/cpukit/score/include/rtems/score/object.h b/cpukit/score/include/rtems/score/object.h
index a0bf3707b6..7c72719679 100644
--- a/cpukit/score/include/rtems/score/object.h
+++ b/cpukit/score/include/rtems/score/object.h
@@ -26,6 +26,14 @@ extern "C" {
#include <rtems/score/chain.h>
/*
+ * Mask to enable unlimited objects
+ *
+ * XXX - needs to be moved to the API some-where
+ */
+
+#define OBJECTS_UNLIMITED_OBJECTS 0x80000000
+
+/*
* The following type defines the control block used to manage
* object names.
*/
@@ -121,9 +129,9 @@ typedef enum {
*/
typedef struct {
- Chain_Node Node;
- Objects_Id id;
- Objects_Name name;
+ Chain_Node Node;
+ Objects_Id id;
+ Objects_Name name;
} Objects_Control;
/*
@@ -132,18 +140,24 @@ typedef struct {
*/
typedef struct {
- Objects_Classes the_class; /* Class of this object */
- Objects_Id minimum_id; /* minimum valid id of this type */
- Objects_Id maximum_id; /* maximum valid id of this type */
- unsigned32 maximum; /* maximum number of objects */
- Objects_Control **local_table; /* table of local object pointers */
- Objects_Name *name_table; /* table of local object names */
- Chain_Control *global_table; /* pointer to global table */
- Chain_Control Inactive; /* chain of inactive ctl blocks */
- boolean is_string; /* TRUE if names are strings */
- unsigned32 name_length; /* maximum length of names */
- boolean is_thread; /* TRUE if these are threads */
- /* irregardless of API */
+ Objects_Classes the_class; /* Class of this object */
+ Objects_Id minimum_id; /* minimum valid id of this type */
+ Objects_Id maximum_id; /* maximum valid id of this type */
+ unsigned32 maximum; /* maximum number of objects */
+ boolean auto_extend; /* TRUE if unlimited objects */
+ unsigned32 allocation_size; /* number of objects in a block */
+ unsigned32 size; /* size of the objects */
+ Objects_Control **local_table;
+ Objects_Name *name_table;
+ Chain_Control *global_table; /* pointer to global table */
+ Chain_Control Inactive; /* chain of inactive ctl blocks */
+ unsigned32 inactive; /* number of objects on the InActive list */
+ unsigned32 *inactive_per_block; /* used to release a block */
+ void **object_blocks; /* the object memory to remove */
+ boolean is_string; /* TRUE if names are strings */
+ unsigned32 name_length; /* maximum length of names */
+ boolean is_thread; /* TRUE if these are threads */
+ /* irregardless of API */
} Objects_Information;
/*
@@ -208,6 +222,30 @@ void _Objects_Handler_initialization(
);
/*
+ * _Objects_Extend_information
+ *
+ * DESCRIPTION:
+ *
+ * This function extends an object class information record.
+ */
+
+void _Objects_Extend_information(
+ Objects_Information *information
+);
+
+/*
+ * _Objects_Shrink_information
+ *
+ * DESCRIPTION:
+ *
+ * This function shrink an object class information record.
+ */
+
+void _Objects_Shrink_information(
+ Objects_Information *information
+);
+
+/*
* _Objects_Initialize_information
*
* DESCRIPTION:
@@ -232,6 +270,35 @@ void _Objects_Initialize_information (
boolean is_task
);
+/*PAGE
+ *
+ * _Objects_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a object control block from
+ * the inactive chain of free object control blocks.
+ */
+
+Objects_Control *_Objects_Allocate(
+ Objects_Information *information
+);
+
+/*PAGE
+ *
+ * _Objects_Free
+ *
+ * DESCRIPTION:
+ *
+ * This function frees a object control block to the
+ * inactive chain of free object control blocks.
+ */
+
+void _Objects_Free(
+ Objects_Information *information,
+ Objects_Control *the_object
+);
+
/*
* _Objects_Clear_name
*
@@ -370,19 +437,6 @@ Objects_Control *_Objects_Get_next(
);
/*
- * _Objects_Get_information
- *
- * DESCRIPTION:
- *
- * Returns the information control block for the class of objects
- * corresponding to this id.
- */
-
-Objects_Information *_Objects_Get_information(
- Objects_Id id
-);
-
-/*
* Pieces of object.inl are promoted out to the user
*/
diff --git a/cpukit/score/inline/rtems/score/coremsg.inl b/cpukit/score/inline/rtems/score/coremsg.inl
index a43b0e7b06..d4dafd8fdc 100644
--- a/cpukit/score/inline/rtems/score/coremsg.inl
+++ b/cpukit/score/inline/rtems/score/coremsg.inl
@@ -41,7 +41,11 @@ RTEMS_INLINE_ROUTINE CORE_message_queue_Status _CORE_message_queue_Send(
buffer,
size,
id,
+#if defined(RTEMS_MULTIPROCESSING)
api_message_queue_mp_support,
+#else
+ NULL,
+#endif
CORE_MESSAGE_QUEUE_SEND_REQUEST
);
}
@@ -68,7 +72,11 @@ RTEMS_INLINE_ROUTINE CORE_message_queue_Status _CORE_message_queue_Urgent(
buffer,
size,
id,
+#if defined(RTEMS_MULTIPROCESSING)
api_message_queue_mp_support,
+#else
+ NULL,
+#endif
CORE_MESSAGE_QUEUE_URGENT_REQUEST
);
}
diff --git a/cpukit/score/inline/rtems/score/object.inl b/cpukit/score/inline/rtems/score/object.inl
index 7e4d12aeec..ce149f33d8 100644
--- a/cpukit/score/inline/rtems/score/object.inl
+++ b/cpukit/score/inline/rtems/score/object.inl
@@ -158,37 +158,67 @@ RTEMS_INLINE_ROUTINE boolean _Objects_Are_ids_equal(
/*PAGE
*
- * _Objects_Allocate
+ * _Objects_Get_local_object
*
* DESCRIPTION:
*
- * This function allocates a object control block from
- * the inactive chain of free object control blocks.
+ * This function returns a pointer to the local_table object
+ * referenced by the index.
*/
-RTEMS_INLINE_ROUTINE Objects_Control *_Objects_Allocate(
- Objects_Information *information
+RTEMS_INLINE_ROUTINE Objects_Control *_Objects_Get_local_object(
+ Objects_Information *information,
+ unsigned32 index
)
{
- return (Objects_Control *) _Chain_Get( &information->Inactive );
+ if ( index > information->maximum)
+ return NULL;
+ return ( information->local_table[ index ] );
}
/*PAGE
*
- * _Objects_Free
+ * _Objects_Set_local_object
*
* DESCRIPTION:
*
- * This function frees a object control block to the
- * inactive chain of free object control blocks.
+ * This function sets the pointer to the local_table object
+ * referenced by the index.
*/
-RTEMS_INLINE_ROUTINE void _Objects_Free(
+RTEMS_INLINE_ROUTINE void _Objects_Set_local_object(
Objects_Information *information,
+ unsigned32 index,
Objects_Control *the_object
)
{
- _Chain_Append( &information->Inactive, &the_object->Node );
+ if ( index <= information->maximum)
+ information->local_table[ index ] = the_object;
+}
+
+
+/*PAGE
+ *
+ * _Objects_Get_information
+ *
+ * DESCRIPTION:
+ *
+ * This function return the information structure given
+ * an id of an object.
+ */
+
+RTEMS_INLINE_ROUTINE Objects_Information *_Objects_Get_information(
+ Objects_Id id
+)
+{
+ Objects_Classes the_class;
+
+ the_class = _Objects_Get_class( id );
+
+ if ( !_Objects_Is_class_valid( the_class ) )
+ return NULL;
+
+ return _Objects_Information_table[ the_class ];
}
/*PAGE
@@ -210,7 +240,7 @@ RTEMS_INLINE_ROUTINE void _Objects_Open(
unsigned32 index;
index = _Objects_Get_index( the_object->id );
- information->local_table[ index ] = the_object;
+ _Objects_Set_local_object( information, index, the_object );
if ( information->is_string )
_Objects_Copy_name_string( name, the_object->name );
@@ -236,7 +266,7 @@ RTEMS_INLINE_ROUTINE void _Objects_Close(
unsigned32 index;
index = _Objects_Get_index( the_object->id );
- information->local_table[ index ] = (Objects_Control *) NULL;
+ _Objects_Set_local_object( information, index, NULL );
_Objects_Clear_name( the_object->name, information->name_length );
}
diff --git a/cpukit/score/macros/rtems/score/object.inl b/cpukit/score/macros/rtems/score/object.inl
index cce2cbde9b..62994ee4e5 100644
--- a/cpukit/score/macros/rtems/score/object.inl
+++ b/cpukit/score/macros/rtems/score/object.inl
@@ -93,21 +93,39 @@
/*PAGE
*
- * _Objects_Allocate
+ * _Objects_Get_local_object
*
*/
-#define _Objects_Allocate( _information ) \
- (Objects_Control *) _Chain_Get( &(_information)->Inactive )
+#define _Objects_Get_local_object( information, index ) \
+ ( ( index > information->maximum) ? NULL : \
+ information->local_table[ index ] )
/*PAGE
*
- * _Objects_Free
+ * _Objects_Set_local_object
*
*/
-#define _Objects_Free( _information, _the_object ) \
- _Chain_Append( &(_information)->Inactive, &(_the_object)->Node )
+#define _Objects_Set_local_object( information, index, the_object ) \
+ { \
+ if ( index <= information->maximum) \
+ information->local_table[ index ] = the_object; \
+ }
+
+
+/*PAGE
+ *
+ * _Objects_Get_information
+ *
+ */
+
+#define _Objects_Get_information( id ) \
+ ( \
+ ( !_Objects_Is_class_valid( _Objects_Get_class( id ) ) ) ? \
+ NULL : \
+ _Objects_Information_table[ _Objects_Get_class( id ) ] \
+ )
/*PAGE
*
diff --git a/cpukit/score/macros/rtems/score/userext.inl b/cpukit/score/macros/rtems/score/userext.inl
index 37b0bf8d2a..69fd0de4b1 100644
--- a/cpukit/score/macros/rtems/score/userext.inl
+++ b/cpukit/score/macros/rtems/score/userext.inl
@@ -23,14 +23,22 @@
*
*/
-#define _User_extensions_Handler_initialization( _initial_extensions ) \
+#define _User_extensions_Handler_initialization( \
+ number_of_extensions, _initial_extensions \
+) \
{ \
+ User_extensions_Control *extension; \
+ unsigned32 i; \
_Chain_Initialize_empty( &_User_extensions_List ); \
\
if ( (_initial_extensions) ) { \
- _User_extensions_Initial.Callouts = *(_initial_extensions); \
- _Chain_Append( \
- &_User_extensions_List, &_User_extensions_Initial.Node ); \
+ for (i=0 ; i<number_of_extensions ; i++ ) { \
+ extension = \
+ _Workspace_Allocate_or_fatal_error( sizeof(User_extensions_Control) ); \
+ \
+ extension->Callouts = _initial_extensions[i]; \
+ _Chain_Append( &_User_extensions_List, &extension->Node ); \
+ } \
} \
}
diff --git a/cpukit/score/src/object.c b/cpukit/score/src/object.c
index 81bca89d7c..cbbe889a79 100644
--- a/cpukit/score/src/object.c
+++ b/cpukit/score/src/object.c
@@ -14,6 +14,7 @@
*/
#include <rtems/system.h>
+#include <rtems/score/address.h>
#include <rtems/score/chain.h>
#include <rtems/score/object.h>
#if defined(RTEMS_MULTIPROCESSING)
@@ -22,6 +23,7 @@
#include <rtems/score/thread.h>
#include <rtems/score/wkspace.h>
#include <rtems/score/sysstate.h>
+#include <rtems/score/isr.h>
/*PAGE
*
@@ -64,6 +66,352 @@ void _Objects_Handler_initialization(
/*PAGE
*
+ * _Objects_Extend_information
+ *
+ * This routine extends all object information related data structures.
+ *
+ * Input parameters:
+ * information - object information table
+ *
+ * Output parameters: NONE
+ */
+
+void _Objects_Extend_information(
+ Objects_Information *information
+)
+{
+ Objects_Control *the_object;
+ void *name_area;
+ Chain_Control Inactive;
+ unsigned32 block_count;
+ unsigned32 block;
+ unsigned32 index_base;
+ unsigned32 minimum_index;
+ unsigned32 index;
+
+ /*
+ * Search for a free block of indexes. The block variable ends up set
+ * to block_count + 1 if the table needs to be extended.
+ */
+
+ minimum_index = _Objects_Get_index( information->minimum_id );
+ index_base = minimum_index;
+ block = 0;
+
+ if (information->maximum < minimum_index)
+ block_count = 0;
+ else {
+ block_count = information->maximum / information->allocation_size;
+
+ for ( ; block < block_count; block++ ) {
+ if ( information->object_blocks[ block ] == NULL )
+ break;
+ else
+ index_base += information->allocation_size;
+ }
+ }
+
+ /*
+ * If the index_base is the maximum we need to grow the tables.
+ */
+
+ if (index_base >= information->maximum ) {
+ ISR_Level level;
+ void **object_blocks;
+ Objects_Name *name_table;
+ unsigned32 *inactive_per_block;
+ Objects_Control **local_table;
+ unsigned32 maximum;
+ void *old_tables;
+
+ /*
+ * Growing the tables means allocating a new area, doing a copy and updating
+ * the information table.
+ *
+ * If the maximum is minimum we do not have a table to copy. First time through.
+ *
+ * The allocation has :
+ *
+ * void *objects[block_count];
+ * unsiged32 inactive_count[block_count];
+ * Objects_Name *name_table[block_count];
+ * Objects_Control *local_table[maximum];
+ *
+ * This is the order in memory. Watch changing the order. See the memcpy
+ * below.
+ */
+
+ /*
+ * Up the block count and maximum
+ */
+
+ block_count++;
+
+ maximum = information->maximum + information->allocation_size;
+
+ /*
+ * Allocate the tables and break it up.
+ */
+
+ if ( information->auto_extend ) {
+ object_blocks = (void**)
+ _Workspace_Allocate(
+ block_count * (sizeof(void *) + sizeof(unsigned32) + sizeof(Objects_Name *)) +
+ ((maximum + minimum_index) * sizeof(Objects_Control *))
+ );
+
+ if ( !object_blocks )
+ return;
+ }
+ else {
+ object_blocks = (void**)
+ _Workspace_Allocate_or_fatal_error(
+ block_count * (sizeof(void *) + sizeof(unsigned32) + sizeof(Objects_Name *)) +
+ ((maximum + minimum_index) * sizeof(Objects_Control *))
+ );
+ }
+
+ /*
+ * Break the block into the various sections.
+ *
+ */
+
+ inactive_per_block =
+ (unsigned32 *) _Addresses_Add_offset( object_blocks, block_count * sizeof(void*) );
+ name_table =
+ (Objects_Name *) _Addresses_Add_offset( inactive_per_block,
+ block_count * sizeof(unsigned32) );
+ local_table =
+ (Objects_Control **) _Addresses_Add_offset( name_table,
+ block_count * sizeof(Objects_Name *) );
+
+ /*
+ * Take the block count down. Saves all the (block_count - 1) in the copies.
+ */
+
+ block_count--;
+
+ if ( information->maximum > minimum_index ) {
+
+ /*
+ * Copy each section of the table over. This has to be performed as
+ * separate parts as size of each block has changed.
+ */
+
+ memcpy( object_blocks,
+ information->object_blocks,
+ block_count * sizeof(void*) );
+ memcpy( inactive_per_block,
+ information->inactive_per_block,
+ block_count * sizeof(unsigned32) );
+ memcpy( name_table,
+ information->name_table,
+ block_count * sizeof(Objects_Name *) );
+ memcpy( local_table,
+ information->local_table,
+ (information->maximum + minimum_index) * sizeof(Objects_Control *) );
+ }
+ else {
+
+ /*
+ * Deal with the special case of the 0 to minimum_index
+ */
+ for ( index = 0; index < minimum_index; index++ ) {
+ local_table[ index ] = NULL;
+ }
+ }
+
+ /*
+ * Initialise the new entries in the table.
+ */
+
+ object_blocks[block_count] = NULL;
+ inactive_per_block[block_count] = 0;
+ name_table[block_count] = NULL;
+
+ for ( index=index_base ;
+ index < ( information->allocation_size + index_base );
+ index++ ) {
+ local_table[ index ] = NULL;
+ }
+
+ _ISR_Disable( level );
+
+ old_tables = information->object_blocks;
+
+ information->object_blocks = object_blocks;
+ information->inactive_per_block = inactive_per_block;
+ information->name_table = name_table;
+ information->local_table = local_table;
+ information->maximum = maximum;
+ information->maximum_id =
+ _Objects_Build_id(
+ information->the_class, _Objects_Local_node, information->maximum
+ );
+
+ _ISR_Enable( level );
+
+ if ( old_tables )
+ _Workspace_Free( old_tables );
+
+ block_count++;
+ }
+
+ /*
+ * Allocate the name table, and the objects
+ */
+
+ if ( information->auto_extend ) {
+ information->object_blocks[ block ] =
+ _Workspace_Allocate(
+ (information->allocation_size * information->name_length) +
+ (information->allocation_size * information->size)
+ );
+
+ if ( !information->object_blocks[ block ] )
+ return;
+ }
+ else {
+ information->object_blocks[ block ] =
+ _Workspace_Allocate_or_fatal_error(
+ (information->allocation_size * information->name_length) +
+ (information->allocation_size * information->size)
+ );
+ }
+
+ name_area = (Objects_Name *) information->object_blocks[ block ];
+ information->name_table[ block ] = name_area;
+
+ /*
+ * Initialize objects .. add to a local chain first.
+ */
+
+ _Chain_Initialize(
+ &Inactive,
+ _Addresses_Add_offset( information->object_blocks[ block ],
+ (information->allocation_size * information->name_length) ),
+ information->allocation_size,
+ information->size
+ );
+
+ /*
+ * Move from the local chain, initialise, then append to the inactive chain
+ */
+
+ index = index_base;
+
+ while ( (the_object = (Objects_Control *) _Chain_Get( &Inactive ) ) != NULL ) {
+
+ the_object->id =
+ _Objects_Build_id(
+ information->the_class, _Objects_Local_node, index
+ );
+
+ the_object->name = (void *) name_area;
+
+ name_area = _Addresses_Add_offset( name_area, information->name_length );
+
+ _Chain_Append( &information->Inactive, &the_object->Node );
+
+ index++;
+ }
+
+ information->inactive_per_block[ block ] = information->allocation_size;
+ information->inactive += information->allocation_size;
+}
+
+/*PAGE
+ *
+ * _Objects_Shrink_information
+ *
+ * This routine shrinks object information related data structures.
+ * The object's name and object space are released. The local_table
+ * etc block does not shrink. The InActive list needs to be scanned
+ * to find the objects are remove them.
+ * Input parameters:
+ * information - object information table
+ * the_block - the block to remove
+ *
+ * Output parameters: NONE
+ */
+
+void _Objects_Shrink_information(
+ Objects_Information *information
+)
+{
+ Objects_Control *the_object;
+ Objects_Control *extract_me;
+ unsigned32 block_count;
+ unsigned32 block;
+ unsigned32 index_base;
+ unsigned32 index;
+
+ /*
+ * Search the list to find block or chunnk with all objects inactive.
+ */
+
+ index_base = _Objects_Get_index( information->minimum_id );
+ block_count = ( information->maximum - index_base ) / information->allocation_size;
+
+ for ( block = 0; block < block_count; block++ ) {
+ if ( information->inactive_per_block[ block ] == information->allocation_size ) {
+
+ /*
+ * XXX - Not to sure how to use a chain where you need to iterate and
+ * and remove elements.
+ */
+
+ the_object = (Objects_Control *) information->Inactive.first;
+
+ /*
+ * Assume the Inactive chain is never empty at this point
+ */
+
+ do {
+ index = _Objects_Get_index( the_object->id );
+
+ if ((index >= index_base) &&
+ (index < (index_base + information->allocation_size))) {
+
+ /*
+ * Get the next node before the node is extracted
+ */
+
+ extract_me = the_object;
+
+ if ( !_Chain_Is_last( &the_object->Node ) )
+ the_object = (Objects_Control *) the_object->Node.next;
+ else
+ the_object = NULL;
+
+ _Chain_Extract( &extract_me->Node );
+ }
+ else {
+ the_object = (Objects_Control *) the_object->Node.next;
+ }
+ }
+ while ( the_object && !_Chain_Is_last( &the_object->Node ) );
+
+ /*
+ * Free the memory and reset the structures in the object' information
+ */
+
+ _Workspace_Free( information->object_blocks[ block ] );
+ information->name_table[ block ] = NULL;
+ information->object_blocks[ block ] = NULL;
+ information->inactive_per_block[ block ] = 0;
+
+ information->inactive -= information->allocation_size;
+
+ return;
+ }
+
+ index_base += information->allocation_size;
+ }
+}
+
+/*PAGE
+ *
* _Objects_Initialize_information
*
* This routine initializes all object information related data structures.
@@ -93,15 +441,19 @@ void _Objects_Initialize_information(
{
unsigned32 minimum_index;
unsigned32 index;
- Objects_Control *the_object;
unsigned32 name_length;
- void *name_area;
-
- information->maximum = maximum;
- information->the_class = the_class;
- information->is_string = is_string;
- information->is_thread = is_thread;
+ information->the_class = the_class;
+ information->is_string = is_string;
+ information->is_thread = is_thread;
+
+ information->local_table = 0;
+ information->name_table = 0;
+ information->inactive_per_block = 0;
+ information->object_blocks = 0;
+
+ information->inactive = 0;
+
/*
* Set the entry in the object information table.
*/
@@ -109,29 +461,36 @@ void _Objects_Initialize_information(
_Objects_Information_table[ the_class ] = information;
/*
- * Calculate minimum and maximum Id's
+ * Set the size of the object
*/
- if ( maximum == 0 ) minimum_index = 0;
- else minimum_index = 1;
+ information->size = size;
+
+ /*
+ * Are we operating in unlimited, or auto-extend mode
+ */
- information->minimum_id =
- _Objects_Build_id( the_class, _Objects_Local_node, minimum_index );
+ information->auto_extend = (maximum & OBJECTS_UNLIMITED_OBJECTS) ? TRUE : FALSE;
+ maximum &= ~OBJECTS_UNLIMITED_OBJECTS;
+
+ /*
+ * The allocation unit is the maximum value
+ */
- information->maximum_id =
- _Objects_Build_id( the_class, _Objects_Local_node, maximum );
+ information->allocation_size = maximum;
/*
- * Allocate local pointer table
+ * Calculate minimum and maximum Id's
*/
- information->local_table =
- (Objects_Control **) _Workspace_Allocate_or_fatal_error(
- (maximum + 1) * sizeof(Objects_Control *)
- );
+ if ( maximum == 0 ) minimum_index = 0;
+ else minimum_index = 1;
+
+ information->minimum_id =
+ _Objects_Build_id( the_class, _Objects_Local_node, minimum_index );
/*
- * Allocate name table
+ * Calculate the maximum name length
*/
name_length = maximum_name_length;
@@ -142,45 +501,29 @@ void _Objects_Initialize_information(
information->name_length = name_length;
- name_area = (Objects_Name *)
- _Workspace_Allocate_or_fatal_error( (maximum + 1) * name_length );
- information->name_table = name_area;
-
- /*
- * Initialize local pointer table
- */
-
- for ( index=0 ; index <= maximum ; index++ ) {
- information->local_table[ index ] = NULL;
- }
-
+ _Chain_Initialize_empty( &information->Inactive );
+
/*
* Initialize objects .. if there are any
*/
- if ( maximum == 0 ) {
- _Chain_Initialize_empty( &information->Inactive );
- } else {
-
- _Chain_Initialize(
- &information->Inactive,
- _Workspace_Allocate_or_fatal_error( maximum * size ),
- maximum,
- size
- );
-
- the_object = (Objects_Control *) information->Inactive.first;
- for ( index=1; index <= maximum ; index++ ) {
- the_object->id =
- _Objects_Build_id( the_class, _Objects_Local_node, index );
-
- the_object->name = (void *) name_area;
-
- name_area = _Addresses_Add_offset( name_area, name_length );
-
- the_object = (Objects_Control *) the_object->Node.next;
- }
+ if ( maximum ) {
+ /*
+ * Reset the maximum value. It will be updated when the information is
+ * extended.
+ */
+
+ information->maximum = 0;
+
+ /*
+ * Always have the maximum size available so the current performance
+ * figures are create are met. If the user moves past the maximum
+ * number then a performance hit is taken.
+ */
+
+ _Objects_Extend_information( information );
+
}
/*
@@ -203,6 +546,89 @@ void _Objects_Initialize_information(
/*PAGE
*
+ * _Objects_Allocate
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a object control block from
+ * the inactive chain of free object control blocks.
+ */
+
+Objects_Control *_Objects_Allocate(
+ Objects_Information *information
+)
+{
+ Objects_Control *the_object =
+ (Objects_Control *) _Chain_Get( &information->Inactive );
+
+ if ( information->auto_extend ) {
+ /*
+ * If the list is empty then we are out of objects and need to
+ * extend information base.
+ */
+
+ if ( !the_object ) {
+ _Objects_Extend_information( information );
+ the_object = (Objects_Control *) _Chain_Get( &information->Inactive );
+ }
+
+ if ( the_object ) {
+ unsigned32 block;
+
+ block =
+ _Objects_Get_index( the_object->id ) - _Objects_Get_index( information->minimum_id );
+ block /= information->allocation_size;
+
+ information->inactive_per_block[ block ]--;
+ information->inactive--;
+ }
+ }
+
+ return the_object;
+}
+
+/*PAGE
+ *
+ * _Objects_Free
+ *
+ * DESCRIPTION:
+ *
+ * This function frees a object control block to the
+ * inactive chain of free object control blocks.
+ */
+
+void _Objects_Free(
+ Objects_Information *information,
+ Objects_Control *the_object
+)
+{
+ unsigned32 allocation_size = information->allocation_size;
+
+ _Chain_Append( &information->Inactive, &the_object->Node );
+
+ if ( information->auto_extend ) {
+ unsigned32 block;
+
+ block =
+ _Objects_Get_index( the_object->id ) - _Objects_Get_index( information->minimum_id );
+ block /= information->allocation_size;
+
+ information->inactive_per_block[ block ]++;
+ information->inactive++;
+
+ /*
+ * Check if the threshold level has been met of
+ * 1.5 x allocation_size are free.
+ */
+
+ if ( information->inactive > ( allocation_size + ( allocation_size >> 1 ) ) ) {
+ _Objects_Shrink_information( information );
+ }
+ }
+}
+
+/*PAGE
+ *
* _Objects_Clear_name
*
* XXX
@@ -341,7 +767,6 @@ Objects_Name_to_id_errors _Objects_Name_to_id(
)
{
boolean search_local_node;
- Objects_Control **objects;
Objects_Control *the_object;
unsigned32 index;
unsigned32 name_length;
@@ -358,8 +783,6 @@ Objects_Name_to_id_errors _Objects_Name_to_id(
search_local_node = TRUE;
if ( search_local_node ) {
- objects = information->local_table;
-
name_length = information->name_length;
if ( information->is_string ) compare_them = _Objects_Compare_name_string;
@@ -367,7 +790,7 @@ Objects_Name_to_id_errors _Objects_Name_to_id(
for ( index = 1; index <= information->maximum; index++ ) {
- the_object = objects[ index ];
+ the_object = information->local_table[ index ];
if ( !the_object || !the_object->name )
continue;
@@ -418,11 +841,11 @@ Objects_Control *_Objects_Get(
Objects_Control *the_object;
unsigned32 index;
- index = id - information->minimum_id;
+ index = _Objects_Get_index( id );
if ( information->maximum >= index ) {
_Thread_Disable_dispatch();
- if ( (the_object = information->local_table[index+1]) != NULL ) {
+ if ( (the_object = _Objects_Get_local_object( information, index )) != NULL ) {
*location = OBJECTS_LOCAL;
return( the_object );
}
@@ -505,24 +928,3 @@ final:
return 0;
}
-/*PAGE
- *
- * _Objects_Get_information
- *
- * XXX
- */
-
-Objects_Information *_Objects_Get_information(
- Objects_Id id
-)
-{
- Objects_Classes the_class;
-
- the_class = _Objects_Get_class( id );
-
- if ( !_Objects_Is_class_valid( the_class ) )
- return NULL;
-
- return _Objects_Information_table[ the_class ];
-}
-