[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