From 466cf31d81cf0cc5fd659aed0924a1f6ee7d18be Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 7 Nov 2012 13:59:19 +0100 Subject: score: Statically initialize user extensions The initial extensions remain now in a read-only table and will not be copied to work space memory. The extension chains are statically initialized. This makes it possible to call _User_extensions_Iterate() independent of the system state. It is now guaranteed that the fatal callout of the initial extensions will be called provided the stack pointer, the read-only data, and code memory are valid. --- cpukit/sapi/include/confdefs.h | 10 ++--- cpukit/score/include/rtems/score/userext.h | 4 +- cpukit/score/src/userext.c | 59 +++++++++++++++++------------- cpukit/score/src/userextiterate.c | 19 +++++++++- 4 files changed, 57 insertions(+), 35 deletions(-) diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h index 5afac3acf4..7e911035ca 100644 --- a/cpukit/sapi/include/confdefs.h +++ b/cpukit/sapi/include/confdefs.h @@ -2090,11 +2090,11 @@ rtems_fs_init_functions_t rtems_fs_init_helper = * user extensions. */ #define CONFIGURE_MEMORY_FOR_STATIC_EXTENSIONS \ - ((CONFIGURE_NEWLIB_EXTENSION * \ - _Configure_From_workspace( sizeof(User_extensions_Control))) + \ - (CONFIGURE_STACK_CHECKER_EXTENSION * \ - _Configure_From_workspace( sizeof(User_extensions_Control))) \ - ) + (CONFIGURE_NUMBER_OF_INITIAL_EXTENSIONS == 0 ? 0 : \ + _Configure_From_workspace( \ + CONFIGURE_NUMBER_OF_INITIAL_EXTENSIONS \ + * sizeof(User_extensions_Switch_control) \ + )) /** * This macro provides a summation of the memory required by the diff --git a/cpukit/score/include/rtems/score/userext.h b/cpukit/score/include/rtems/score/userext.h index a3cd918eba..b182e86172 100644 --- a/cpukit/score/include/rtems/score/userext.h +++ b/cpukit/score/include/rtems/score/userext.h @@ -234,12 +234,12 @@ typedef struct { /** * @brief List of active extensions. */ -SCORE_EXTERN Chain_Control _User_extensions_List; +extern Chain_Control _User_extensions_List; /** * @brief List of active task switch extensions. */ -SCORE_EXTERN Chain_Control _User_extensions_Switches_list; +extern Chain_Control _User_extensions_Switches_list; /** * @name Extension Maintainance diff --git a/cpukit/score/src/userext.c b/cpukit/score/src/userext.c index 4b81daa4ea..78162f6cdd 100644 --- a/cpukit/score/src/userext.c +++ b/cpukit/score/src/userext.c @@ -16,44 +16,51 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include #include #include #include -#include -void _User_extensions_Handler_initialization(void) +CHAIN_DEFINE_EMPTY( _User_extensions_Switches_list ); + +typedef struct { + User_extensions_Switch_control *switch_control; +} User_extensions_Switch_context; + +static void _User_extensions_Switch_visitor( + Thread_Control *executing, + void *arg, + const User_extensions_Table *callouts +) { - User_extensions_Control *extension; - uint32_t i; - uint32_t number_of_extensions; - const User_extensions_Table *initial_extensions; + User_extensions_thread_switch_extension callout = callouts->thread_switch; - number_of_extensions = rtems_configuration_get_number_of_initial_extensions(); - initial_extensions = rtems_configuration_get_user_extension_table(); + if ( callout != NULL ) { + User_extensions_Switch_context *ctx = arg; + User_extensions_Switch_control *ctrl = ctx->switch_control; - _Chain_Initialize_empty( &_User_extensions_List ); - _Chain_Initialize_empty( &_User_extensions_Switches_list ); + _Chain_Append_unprotected( &_User_extensions_Switches_list, &ctrl->Node ); + ctrl->thread_switch = callout; + + ctx->switch_control = ctrl + 1; + } +} - if ( initial_extensions ) { - extension = (User_extensions_Control *) +void _User_extensions_Handler_initialization(void) +{ + uint32_t number_of_initial_extensions = + rtems_configuration_get_number_of_initial_extensions(); + + if ( number_of_initial_extensions > 0 ) { + User_extensions_Switch_control *initial_extension_switch_controls = _Workspace_Allocate_or_fatal_error( - number_of_extensions * sizeof( User_extensions_Control ) + number_of_initial_extensions + * sizeof( *initial_extension_switch_controls ) ); + User_extensions_Switch_context ctx = { initial_extension_switch_controls }; - memset ( - extension, - 0, - number_of_extensions * sizeof( User_extensions_Control ) - ); - - for ( i = 0 ; i < number_of_extensions ; i++ ) { - _User_extensions_Add_set_with_table (extension, &initial_extensions[i]); - extension++; - } + _User_extensions_Iterate( &ctx, _User_extensions_Switch_visitor ); } } - diff --git a/cpukit/score/src/userextiterate.c b/cpukit/score/src/userextiterate.c index 9f645e5056..bab63ef99b 100644 --- a/cpukit/score/src/userextiterate.c +++ b/cpukit/score/src/userextiterate.c @@ -16,8 +16,11 @@ #include "config.h" #endif +#include #include +CHAIN_DEFINE_EMPTY( _User_extensions_List ); + void _User_extensions_Thread_create_visitor( Thread_Control *executing, void *arg, @@ -118,10 +121,22 @@ void _User_extensions_Iterate( User_extensions_Visitor visitor ) { - const Chain_Node *node = _Chain_Immutable_first( &_User_extensions_List ); - const Chain_Node *tail = _Chain_Immutable_tail( &_User_extensions_List ); Thread_Control *executing = _Thread_Executing; + const User_extensions_Table *callouts_current = + rtems_configuration_get_user_extension_table(); + const User_extensions_Table *callouts_end = + callouts_current + rtems_configuration_get_number_of_initial_extensions(); + const Chain_Node *node; + const Chain_Node *tail; + + while ( callouts_current != callouts_end ) { + (*visitor)( executing, arg, callouts_current ); + + ++callouts_current; + } + node = _Chain_Immutable_first( &_User_extensions_List ); + tail = _Chain_Immutable_tail( &_User_extensions_List ); while ( node != tail ) { const User_extensions_Control *extension = (const User_extensions_Control *) node; -- cgit v1.2.3