[PATCH 3/8] score: Statically initialize user extensions
Sebastian Huber
sebastian.huber at embedded-brains.de
Wed Nov 7 16:05:58 UTC 2012
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 | 9 ++--
cpukit/score/include/rtems/score/userext.h | 4 +-
cpukit/score/src/userext.c | 59 +++++++++++++++------------
cpukit/score/src/userextiterate.c | 19 ++++++++-
4 files changed, 56 insertions(+), 35 deletions(-)
diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h
index 5afac3a..ce67168 100644
--- a/cpukit/sapi/include/confdefs.h
+++ b/cpukit/sapi/include/confdefs.h
@@ -2090,11 +2090,10 @@ 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_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 a3cd918..b182e86 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 4b81daa..78162f6 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 <rtems/system.h>
#include <rtems/config.h>
#include <rtems/score/userext.h>
#include <rtems/score/wkspace.h>
-#include <string.h>
-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 9f645e5..bab63ef 100644
--- a/cpukit/score/src/userextiterate.c
+++ b/cpukit/score/src/userextiterate.c
@@ -16,8 +16,11 @@
#include "config.h"
#endif
+#include <rtems/config.h>
#include <rtems/score/userext.h>
+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;
--
1.7.7
More information about the devel
mailing list