summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2012-11-07 13:59:19 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2012-11-13 09:20:57 +0100
commit466cf31d81cf0cc5fd659aed0924a1f6ee7d18be (patch)
treed1381235011ecaced397b15ba14e4522dd8db72c
parente5ae7c927c793fbb66fd00697d61aeb27c4c6e2c (diff)
downloadrtems-466cf31d81cf0cc5fd659aed0924a1f6ee7d18be.tar.bz2
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.
-rw-r--r--cpukit/sapi/include/confdefs.h10
-rw-r--r--cpukit/score/include/rtems/score/userext.h4
-rw-r--r--cpukit/score/src/userext.c59
-rw-r--r--cpukit/score/src/userextiterate.c19
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 <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 9f645e5056..bab63ef99b 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;