summaryrefslogtreecommitdiffstats
path: root/cpukit/score
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-11-22 19:14:51 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-12-14 07:03:29 +0100
commit21275b58a5a69c3c838082ffc8a7a3641f32ea9a (patch)
treed331e17c15d71f107d0f14581a93ddf768b05813 /cpukit/score
parentrtems: Use object information to get config max (diff)
downloadrtems-21275b58a5a69c3c838082ffc8a7a3641f32ea9a.tar.bz2
score: Static Objects_Information initialization
Statically allocate the objects information together with the initial set of objects either via <rtems/confdefs.h>. Provide default object informations with zero objects via librtemscpu.a. This greatly simplifies the workspace size estimate. RTEMS applications which do not use the unlimited objects option are easier to debug since all objects reside now in statically allocated objects of the right types. Close #3621.
Diffstat (limited to 'cpukit/score')
-rw-r--r--cpukit/score/src/freechain.c25
-rw-r--r--cpukit/score/src/mpci.c2
-rw-r--r--cpukit/score/src/objectallocate.c11
-rw-r--r--cpukit/score/src/objectextendinformation.c52
-rw-r--r--cpukit/score/src/objectfree.c25
-rw-r--r--cpukit/score/src/objectinitializeinformation.c99
-rw-r--r--cpukit/score/src/objectshrinkinformation.c5
-rw-r--r--cpukit/score/src/thread.c36
-rw-r--r--cpukit/score/src/threadcreateidle.c2
-rw-r--r--cpukit/score/src/threadinitialize.c6
-rw-r--r--cpukit/score/src/threadmp.c3
-rw-r--r--cpukit/score/src/threadrestart.c2
-rw-r--r--cpukit/score/src/wkspace.c20
13 files changed, 98 insertions, 190 deletions
diff --git a/cpukit/score/src/freechain.c b/cpukit/score/src/freechain.c
index 68786b1d7a..57ba293d4b 100644
--- a/cpukit/score/src/freechain.c
+++ b/cpukit/score/src/freechain.c
@@ -20,31 +20,6 @@
#include <rtems/score/freechain.h>
#include <rtems/score/assert.h>
-#include <rtems/score/chainimpl.h>
-
-void _Freechain_Initialize(
- Freechain_Control *freechain,
- Freechain_Allocator allocator,
- size_t number_nodes,
- size_t node_size
-)
-{
- void *starting_address;
-
- if ( number_nodes > 0 ) {
- starting_address = ( *allocator )( number_nodes * node_size );
- number_nodes *= ( starting_address != NULL );
- } else {
- starting_address = NULL;
- }
-
- _Chain_Initialize(
- &freechain->Free,
- starting_address,
- number_nodes,
- node_size
- );
-}
void *_Freechain_Get(
Freechain_Control *freechain,
diff --git a/cpukit/score/src/mpci.c b/cpukit/score/src/mpci.c
index 2d0244d887..9b09caa074 100644
--- a/cpukit/score/src/mpci.c
+++ b/cpukit/score/src/mpci.c
@@ -146,7 +146,7 @@ static void _MPCI_Create_server( void )
name.name_u32 = _Objects_Build_name( 'M', 'P', 'C', 'I' );
_Thread_Initialize(
- &_Thread_Internal_information,
+ &_Thread_Information,
_MPCI_Receive_server_tcb,
&_Scheduler_Table[ 0 ],
NULL, /* allocate the stack */
diff --git a/cpukit/score/src/objectallocate.c b/cpukit/score/src/objectallocate.c
index 9213cf8eb7..ad73884a07 100644
--- a/cpukit/score/src/objectallocate.c
+++ b/cpukit/score/src/objectallocate.c
@@ -68,13 +68,18 @@ Objects_Control *_Objects_Allocate_unprotected(
}
if ( the_object != NULL ) {
+ Objects_Maximum objects_per_block;
Objects_Maximum block;
+ objects_per_block = information->objects_per_block;
block = _Objects_Get_index( the_object->id ) - OBJECTS_INDEX_MINIMUM;
- block /= information->objects_per_block;
- information->inactive_per_block[ block ]--;
- information->inactive--;
+ if ( block > objects_per_block ) {
+ block /= objects_per_block;
+
+ information->inactive_per_block[ block ]--;
+ information->inactive--;
+ }
}
}
diff --git a/cpukit/score/src/objectextendinformation.c b/cpukit/score/src/objectextendinformation.c
index 22b9ec671b..b26f591f6e 100644
--- a/cpukit/score/src/objectextendinformation.c
+++ b/cpukit/score/src/objectextendinformation.c
@@ -61,7 +61,11 @@ void _Objects_Extend_information(
_Objects_Allocator_is_owner()
|| !_System_state_Is_up( _System_state_Get() )
);
+ _Assert( _Objects_Is_auto_extend( information ) );
+ extend_count = _Objects_Extend_size( information );
+ old_maximum = _Objects_Get_maximum_index( information );
+ new_maximum = (uint32_t) old_maximum + extend_count;
api_class_and_node = information->maximum_id & ~OBJECTS_INDEX_MASK;
/*
@@ -69,16 +73,12 @@ void _Objects_Extend_information(
* extend the block table, then we will change do_extend.
*/
do_extend = true;
- index_base = 0;
- block = 0;
+ index_base = extend_count;
+ block = 1;
if ( information->object_blocks == NULL ) {
- extend_count = _Objects_Get_maximum_index( information );
- old_maximum = 0;
- block_count = 0;
+ block_count = 1;
} else {
- extend_count = information->objects_per_block;
- old_maximum = _Objects_Get_maximum_index( information );
block_count = old_maximum / extend_count;
for ( ; block < block_count; block++ ) {
@@ -90,7 +90,6 @@ void _Objects_Extend_information(
}
}
- new_maximum = (uint32_t) old_maximum + extend_count;
index_end = index_base + extend_count;
/*
@@ -107,12 +106,9 @@ void _Objects_Extend_information(
* generate a fatal error depending on auto-extending being active.
*/
object_block_size = extend_count * information->object_size;
- if ( _Objects_Is_auto_extend( information ) ) {
- new_object_block = _Workspace_Allocate( object_block_size );
- if ( !new_object_block )
- return;
- } else {
- new_object_block = _Workspace_Allocate_or_fatal_error( object_block_size );
+ new_object_block = _Workspace_Allocate( object_block_size );
+ if ( new_object_block == NULL ) {
+ return;
}
/*
@@ -158,14 +154,10 @@ void _Objects_Extend_information(
table_size = object_blocks_size
+ local_table_size
+ block_count * sizeof( *inactive_per_block );
- if ( _Objects_Is_auto_extend( information ) ) {
- object_blocks = _Workspace_Allocate( table_size );
- if ( !object_blocks ) {
- _Workspace_Free( new_object_block );
- return;
- }
- } else {
- object_blocks = _Workspace_Allocate_or_fatal_error( table_size );
+ object_blocks = _Workspace_Allocate( table_size );
+ if ( object_blocks == NULL ) {
+ _Workspace_Free( new_object_block );
+ return;
}
/*
@@ -186,7 +178,7 @@ void _Objects_Extend_information(
*/
block_count--;
- if ( old_maximum > 0 ) {
+ if ( old_maximum > extend_count ) {
/*
* Copy each section of the table over. This has to be performed as
* separate parts as size of each block has changed.
@@ -201,13 +193,17 @@ void _Objects_Extend_information(
information->inactive_per_block,
block_count * sizeof( *inactive_per_block )
);
- memcpy(
- local_table,
- information->local_table,
- old_maximum * sizeof( *local_table )
- );
+ } else {
+ object_blocks[ 0 ] = NULL;
+ inactive_per_block[ 0 ] = 0;
}
+ memcpy(
+ local_table,
+ information->local_table,
+ old_maximum * sizeof( *local_table )
+ );
+
/*
* Initialise the new entries in the table.
*/
diff --git a/cpukit/score/src/objectfree.c b/cpukit/score/src/objectfree.c
index 38ae17d739..c9af8ba7cf 100644
--- a/cpukit/score/src/objectfree.c
+++ b/cpukit/score/src/objectfree.c
@@ -38,21 +38,24 @@ void _Objects_Free(
objects_per_block = information->objects_per_block;
block = _Objects_Get_index( the_object->id ) - OBJECTS_INDEX_MINIMUM;
- block /= objects_per_block;
- ++information->inactive_per_block[ block ];
+ if ( block > objects_per_block ) {
+ block /= objects_per_block;
- inactive = information->inactive;
- ++inactive;
- information->inactive = inactive;
+ ++information->inactive_per_block[ block ];
- /*
- * Check if the threshold level has been met of
- * 1.5 x objects_per_block are free.
- */
+ inactive = information->inactive;
+ ++inactive;
+ information->inactive = inactive;
- if ( inactive > ( objects_per_block + ( objects_per_block >> 1 ) ) ) {
- _Objects_Shrink_information( information );
+ /*
+ * Check if the threshold level has been met of
+ * 1.5 x objects_per_block are free.
+ */
+
+ if ( inactive > ( objects_per_block + ( objects_per_block >> 1 ) ) ) {
+ _Objects_Shrink_information( information );
+ }
}
}
}
diff --git a/cpukit/score/src/objectinitializeinformation.c b/cpukit/score/src/objectinitializeinformation.c
index 57e588ad4a..0b2fa2ad0f 100644
--- a/cpukit/score/src/objectinitializeinformation.c
+++ b/cpukit/score/src/objectinitializeinformation.c
@@ -24,83 +24,50 @@
#include <rtems/score/sysstate.h>
#include <rtems/score/wkspace.h>
-void _Objects_Do_initialize_information(
- Objects_Information *information,
- Objects_APIs the_api,
- uint16_t the_class,
- uint32_t maximum,
- uint16_t object_size,
- uint16_t maximum_name_length
-#if defined(RTEMS_MULTIPROCESSING)
- ,
- Objects_Thread_queue_Extract_callout extract
-#endif
+void _Objects_Initialize_information(
+ Objects_Information *information
)
{
- Objects_Maximum maximum_per_allocation;
-
- maximum_per_allocation = _Objects_Maximum_per_allocation( maximum );
- information->maximum_id = _Objects_Build_id(
- the_api,
- the_class,
- _Objects_Local_node,
- maximum_per_allocation
- );
- information->object_size = object_size;
+ Objects_Id maximum_id;
+ Objects_Id api_class_and_node;
+ Objects_Maximum maximum;
+ Objects_Maximum index;
+ Chain_Node *head;
+ Chain_Node *tail;
+ Chain_Node *current;
+ Objects_Control *next;
- /*
- * Register this Object Class in the Object Information Table.
- */
- _Objects_Information_table[ the_api ][ the_class ] = information;
-
- /*
- * Are we operating in limited or unlimited (e.g. auto-extend) mode.
- */
- if ( _Objects_Is_unlimited( maximum ) ) {
- /*
- * Unlimited and maximum of zero is illogical.
- */
- if ( maximum_per_allocation == 0) {
- _Internal_error( INTERNAL_ERROR_UNLIMITED_AND_MAXIMUM_IS_0 );
- }
+ maximum_id = information->maximum_id;
- /*
- * The allocation unit is the maximum value
- */
- information->objects_per_block = maximum_per_allocation;
- }
+#if defined(RTEMS_MULTIPROCESSING)
+ maximum_id |= _Objects_Local_node << OBJECTS_NODE_START_BIT;
+ information->maximum_id = maximum_id;
+#endif
+ maximum = _Objects_Get_index( maximum_id );
+ api_class_and_node = maximum_id & ~OBJECTS_INDEX_MASK;
/*
- * Calculate the maximum name length
- *
- * NOTE: Either 4 bytes for Classic API names or an arbitrary
- * number for POSIX names which are strings that may be
- * an odd number of bytes.
+ * Register this Object Class in the Object Information Table.
*/
+ _Objects_Information_table[ _Objects_Get_API( maximum_id ) ]
+ [ _Objects_Get_class( maximum_id ) ] = information;
- information->name_length = maximum_name_length;
+ head = _Chain_Head( &information->Inactive );
+ tail = _Chain_Tail( &information->Inactive );
+ current = head;
+ next = information->initial_objects;
- _Chain_Initialize_empty( &information->Inactive );
+ head->previous = NULL;
- /*
- * Initialize objects .. if there are any
- */
- if ( maximum_per_allocation ) {
- /*
- * 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 );
+ for ( index = OBJECTS_INDEX_MINIMUM; index <= maximum ; ++index ) {
+ current->next = &next->Node;
+ next->Node.previous = current;
+ current = &next->Node;
+ next->id = api_class_and_node | ( index << OBJECTS_INDEX_START_BIT );
+ next = _Addresses_Add_offset( next, information->object_size );
}
- /*
- * Take care of multiprocessing
- */
- #if defined(RTEMS_MULTIPROCESSING)
- information->extract = extract;
- _RBTree_Initialize_empty( &information->Global_by_id );
- _RBTree_Initialize_empty( &information->Global_by_name );
- #endif
+ current->next = tail;
+ tail->previous = current;
}
diff --git a/cpukit/score/src/objectshrinkinformation.c b/cpukit/score/src/objectshrinkinformation.c
index 5a53be9979..964f3f5ef6 100644
--- a/cpukit/score/src/objectshrinkinformation.c
+++ b/cpukit/score/src/objectshrinkinformation.c
@@ -33,6 +33,7 @@ void _Objects_Shrink_information(
Objects_Maximum index_base;
_Assert( _Objects_Allocator_is_owner() );
+ _Assert( _Objects_Is_auto_extend( information ) );
/*
* Search the list to find block or chunk with all objects inactive.
@@ -40,9 +41,9 @@ void _Objects_Shrink_information(
objects_per_block = information->objects_per_block;
block_count = _Objects_Get_maximum_index( information ) / objects_per_block;
- index_base = 0;
+ index_base = objects_per_block;
- for ( block = 0; block < block_count; block++ ) {
+ for ( block = 1; block < block_count; block++ ) {
if ( information->inactive_per_block[ block ] == objects_per_block ) {
Chain_Node *node;
const Chain_Node *tail;
diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c
index 5c27ee00ef..822fb7cb37 100644
--- a/cpukit/score/src/thread.c
+++ b/cpukit/score/src/thread.c
@@ -20,6 +20,7 @@
#include <rtems/score/threadimpl.h>
#include <rtems/score/interr.h>
+#include <rtems/score/objectimpl.h>
#include <rtems/score/scheduler.h>
#include <rtems/score/wkspace.h>
@@ -43,30 +44,15 @@ THREAD_OFFSET_ASSERT( Timer );
THREAD_OFFSET_ASSERT( receive_packet );
#endif
-Thread_Information _Thread_Internal_information;
-
-void _Thread_Initialize_information(
- Thread_Information *information,
- Objects_APIs the_api,
- uint16_t the_class,
- uint32_t maximum
-)
+void _Thread_Initialize_information( Thread_Information *information )
{
- _Objects_Initialize_information(
- &information->Objects,
- the_api,
- the_class,
- maximum,
- _Thread_Control_size,
- OBJECTS_NO_STRING_NAME,
- NULL
- );
+ _Objects_Initialize_information( &information->Objects );
_Freechain_Initialize(
- &information->Free_thread_queue_heads,
- _Workspace_Allocate_or_fatal_error,
- _Objects_Maximum_per_allocation( maximum ),
- THREAD_QUEUE_HEADS_SIZE( _Scheduler_Count )
+ &information->Thread_queue_heads.Free,
+ information->Thread_queue_heads.initial,
+ _Objects_Get_maximum_index( &information->Objects ),
+ _Thread_queue_Heads_size
);
}
@@ -95,11 +81,5 @@ void _Thread_Handler_initialization(void)
* per CPU in an SMP system. In addition, if this is a loosely
* coupled multiprocessing system, account for the MPCI Server Thread.
*/
- _Thread_Initialize_information(
- &_Thread_Internal_information,
- OBJECTS_INTERNAL_API,
- OBJECTS_INTERNAL_THREADS,
- _Thread_Get_maximum_internal_threads()
- );
-
+ _Thread_Initialize_information( &_Thread_Information );
}
diff --git a/cpukit/score/src/threadcreateidle.c b/cpukit/score/src/threadcreateidle.c
index d8dd2b4197..cdb2b1eebd 100644
--- a/cpukit/score/src/threadcreateidle.c
+++ b/cpukit/score/src/threadcreateidle.c
@@ -51,7 +51,7 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
_Assert( idle != NULL );
_Thread_Initialize(
- &_Thread_Internal_information,
+ &_Thread_Information,
idle,
scheduler,
NULL, /* allocate the stack */
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index df526e9a8e..c15731f99c 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -145,10 +145,10 @@ bool _Thread_Initialize(
* Get thread queue heads
*/
the_thread->Wait.spare_heads = _Freechain_Get(
- &information->Free_thread_queue_heads,
+ &information->Thread_queue_heads.Free,
_Workspace_Allocate,
_Objects_Extend_size( &information->Objects ),
- THREAD_QUEUE_HEADS_SIZE( _Scheduler_Count )
+ _Thread_queue_Heads_size
);
if ( the_thread->Wait.spare_heads == NULL ) {
goto failed;
@@ -308,7 +308,7 @@ failed:
_Workspace_Free( the_thread->Start.tls_area );
_Freechain_Put(
- &information->Free_thread_queue_heads,
+ &information->Thread_queue_heads.Free,
the_thread->Wait.spare_heads
);
diff --git a/cpukit/score/src/threadmp.c b/cpukit/score/src/threadmp.c
index 4868e8fe4e..006d0f5bcf 100644
--- a/cpukit/score/src/threadmp.c
+++ b/cpukit/score/src/threadmp.c
@@ -54,8 +54,7 @@ void _Thread_MP_Handler_initialization (
return;
}
- proxy_size = sizeof( Thread_Proxy_control )
- + THREAD_QUEUE_HEADS_SIZE( _Scheduler_Count );
+ proxy_size = sizeof( Thread_Proxy_control ) + _Thread_queue_Heads_size;
alloc_size = maximum_proxies * proxy_size;
proxies = _Workspace_Allocate_or_fatal_error( alloc_size );
memset( proxies, 0, alloc_size );
diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c
index 66cf4df845..bcd900aa69 100644
--- a/cpukit/score/src/threadrestart.c
+++ b/cpukit/score/src/threadrestart.c
@@ -176,7 +176,7 @@ static void _Thread_Free( Thread_Control *the_thread )
#endif
_Freechain_Put(
- &information->Free_thread_queue_heads,
+ &information->Thread_queue_heads.Free,
the_thread->Wait.spare_heads
);
diff --git a/cpukit/score/src/wkspace.c b/cpukit/score/src/wkspace.c
index c9df793526..95c4127056 100644
--- a/cpukit/score/src/wkspace.c
+++ b/cpukit/score/src/wkspace.c
@@ -42,24 +42,6 @@ RTEMS_LINKER_RWSET(
Heap_Control _Workspace_Area;
-static uint32_t _Workspace_Get_maximum_thread_count( void )
-{
- uint32_t thread_count;
-
- thread_count = 0;
- thread_count += _Thread_Get_maximum_internal_threads();
-
- thread_count += rtems_resource_maximum_per_allocation(
- Configuration_RTEMS_API.maximum_tasks
- );
-
- thread_count += rtems_resource_maximum_per_allocation(
- _Configuration_POSIX_Maximum_threads
- );
-
- return thread_count;
-}
-
static uintptr_t _Workspace_Space_for_TLS( uintptr_t page_size )
{
uintptr_t tls_size;
@@ -86,7 +68,7 @@ static uintptr_t _Workspace_Space_for_TLS( uintptr_t page_size )
*/
space = _Heap_Min_block_size( page_size );
- space += _Workspace_Get_maximum_thread_count()
+ space += _Thread_Initial_thread_count
* _Heap_Size_with_overhead( page_size, tls_alloc, tls_align );
} else {
space = 0;