[PATCH 2/8] score: Add and use _User_extensions_Iterate()

Sebastian Huber sebastian.huber at embedded-brains.de
Wed Nov 7 16:05:57 UTC 2012


Replace the separate user extension iterations with a single iteration
function.  This reduces code size and improves maintainability since the
iteration logic is only in one function.  The runtime overhead is
insignificant.
---
 cpukit/score/Makefile.am                   |    4 +-
 cpukit/score/include/rtems/score/userext.h |  145 ++++++++++++++++++++++++----
 cpukit/score/src/userextiterate.c          |  133 +++++++++++++++++++++++++
 cpukit/score/src/userextthreadbegin.c      |   79 ---------------
 cpukit/score/src/userextthreadcreate.c     |   50 ----------
 cpukit/score/src/userextthreaddelete.c     |   44 ---------
 cpukit/score/src/userextthreadrestart.c    |   44 ---------
 cpukit/score/src/userextthreadstart.c      |   44 ---------
 8 files changed, 260 insertions(+), 283 deletions(-)
 create mode 100644 cpukit/score/src/userextiterate.c
 delete mode 100644 cpukit/score/src/userextthreadbegin.c
 delete mode 100644 cpukit/score/src/userextthreadcreate.c
 delete mode 100644 cpukit/score/src/userextthreaddelete.c
 delete mode 100644 cpukit/score/src/userextthreadrestart.c
 delete mode 100644 cpukit/score/src/userextthreadstart.c

diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index d259acb..7b7757f 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -318,9 +318,7 @@ libscore_a_SOURCES += src/watchdog.c src/watchdogadjust.c \
 
 ## USEREXT_C_FILES
 libscore_a_SOURCES += src/userextaddset.c \
-    src/userext.c src/userextremoveset.c src/userextthreadbegin.c \
-    src/userextthreadcreate.c src/userextthreaddelete.c \
-    src/userextthreadrestart.c src/userextthreadstart.c \
+    src/userext.c src/userextremoveset.c src/userextiterate.c \
     src/userextthreadswitch.c
 
 ## STD_C_FILES
diff --git a/cpukit/score/include/rtems/score/userext.h b/cpukit/score/include/rtems/score/userext.h
index 087df8c..a3cd918 100644
--- a/cpukit/score/include/rtems/score/userext.h
+++ b/cpukit/score/include/rtems/score/userext.h
@@ -274,48 +274,155 @@ void _User_extensions_Remove_set(
   User_extensions_Control *extension
 );
 
-/** @} */
-
 /**
- * @name Extension Callout Dispatcher
+ * @brief User extension visitor.
  *
- * @{
+ * @param[in, out] executing The currently executing thread.
+ * @param[in, out] arg The argument passed to _User_extensions_Iterate().
+ * @param[in] callouts The current callouts.
  */
+typedef void (*User_extensions_Visitor)(
+  Thread_Control              *executing,
+  void                        *arg,
+  const User_extensions_Table *callouts
+);
+
+typedef struct {
+  Thread_Control *created;
+  bool            ok;
+} User_extensions_Thread_create_context;
+
+void _User_extensions_Thread_create_visitor(
+  Thread_Control              *executing,
+  void                        *arg,
+  const User_extensions_Table *callouts
+);
+
+void _User_extensions_Thread_delete_visitor(
+  Thread_Control              *executing,
+  void                        *arg,
+  const User_extensions_Table *callouts
+);
+
+void _User_extensions_Thread_start_visitor(
+  Thread_Control              *executing,
+  void                        *arg,
+  const User_extensions_Table *callouts
+);
 
-bool _User_extensions_Thread_create(
-  Thread_Control *created
+void _User_extensions_Thread_restart_visitor(
+  Thread_Control              *executing,
+  void                        *arg,
+  const User_extensions_Table *callouts
 );
 
-void _User_extensions_Thread_delete(
-  Thread_Control *deleted
+void _User_extensions_Thread_begin_visitor(
+  Thread_Control              *executing,
+  void                        *arg,
+  const User_extensions_Table *callouts
 );
 
-void _User_extensions_Thread_start(
-  Thread_Control *started
+void _User_extensions_Thread_exitted_visitor(
+  Thread_Control              *executing,
+  void                        *arg,
+  const User_extensions_Table *callouts
 );
 
-void _User_extensions_Thread_restart(
-  Thread_Control *restarted
+typedef struct {
+  Internal_errors_Source source;
+  bool                   is_internal;
+  Internal_errors_t      error;
+} User_extensions_Fatal_context;
+
+void _User_extensions_Fatal_visitor(
+  Thread_Control              *executing,
+  void                        *arg,
+  const User_extensions_Table *callouts
 );
 
-void _User_extensions_Thread_begin(
-  Thread_Control *executing
+/**
+ * @brief Iterates through all user extensions and calls the visitor for each.
+ *
+ * @param[in, out] arg The argument passed to the visitor.
+ * @param[in] visitor The visitor for each extension.
+ */
+void _User_extensions_Iterate(
+  void                    *arg,
+  User_extensions_Visitor  visitor
 );
 
+/** @} */
+
+/**
+ * @name Extension Callout Dispatcher
+ *
+ * @{
+ */
+
+static inline bool _User_extensions_Thread_create( Thread_Control *created )
+{
+  User_extensions_Thread_create_context ctx = { created, true };
+
+  _User_extensions_Iterate( &ctx, _User_extensions_Thread_create_visitor );
+
+  return ctx.ok;
+}
+
+static inline void _User_extensions_Thread_delete( Thread_Control *deleted )
+{
+  _User_extensions_Iterate(
+    deleted,
+    _User_extensions_Thread_delete_visitor
+  );
+}
+
+static inline void _User_extensions_Thread_start( Thread_Control *started )
+{
+  _User_extensions_Iterate(
+    started,
+    _User_extensions_Thread_start_visitor
+  );
+}
+
+static inline void _User_extensions_Thread_restart( Thread_Control *restarted )
+{
+  _User_extensions_Iterate(
+    restarted,
+    _User_extensions_Thread_restart_visitor
+  );
+}
+
+static inline void _User_extensions_Thread_begin( Thread_Control *executing )
+{
+  _User_extensions_Iterate(
+    executing,
+    _User_extensions_Thread_begin_visitor
+  );
+}
+
 void _User_extensions_Thread_switch(
   Thread_Control *executing,
   Thread_Control *heir
 );
 
-void _User_extensions_Thread_exitted(
-  Thread_Control *executing
-);
+static inline void _User_extensions_Thread_exitted( Thread_Control *executing )
+{
+  _User_extensions_Iterate(
+    executing,
+    _User_extensions_Thread_exitted_visitor
+  );
+}
 
-void _User_extensions_Fatal(
+static inline void _User_extensions_Fatal(
   Internal_errors_Source source,
   bool                   is_internal,
   Internal_errors_t      error
-);
+)
+{
+  User_extensions_Fatal_context ctx = { source, is_internal, error };
+
+  _User_extensions_Iterate( &ctx, _User_extensions_Fatal_visitor );
+}
 
 /** @} */
 
diff --git a/cpukit/score/src/userextiterate.c b/cpukit/score/src/userextiterate.c
new file mode 100644
index 0000000..9f645e5
--- /dev/null
+++ b/cpukit/score/src/userextiterate.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems/score/userext.h>
+
+void _User_extensions_Thread_create_visitor(
+  Thread_Control              *executing,
+  void                        *arg,
+  const User_extensions_Table *callouts
+)
+{
+  User_extensions_thread_create_extension callout = callouts->thread_create;
+
+  if ( callout != NULL ) {
+    User_extensions_Thread_create_context *ctx = arg;
+
+    ctx->ok = ctx->ok && (*callout)( executing, ctx->created );
+  }
+}
+
+void _User_extensions_Thread_delete_visitor(
+  Thread_Control              *executing,
+  void                        *arg,
+  const User_extensions_Table *callouts
+)
+{
+  User_extensions_thread_delete_extension callout = callouts->thread_delete;
+
+  if ( callout != NULL ) {
+    (*callout)( executing, arg );
+  }
+}
+
+void _User_extensions_Thread_start_visitor(
+  Thread_Control              *executing,
+  void                        *arg,
+  const User_extensions_Table *callouts
+)
+{
+  User_extensions_thread_start_extension callout = callouts->thread_start;
+
+  if ( callout != NULL ) {
+    (*callout)( executing, arg );
+  }
+}
+
+void _User_extensions_Thread_restart_visitor(
+  Thread_Control              *executing,
+  void                        *arg,
+  const User_extensions_Table *callouts
+)
+{
+  User_extensions_thread_restart_extension callout = callouts->thread_restart;
+
+  if ( callout != NULL ) {
+    (*callout)( executing, arg );
+  }
+}
+
+void _User_extensions_Thread_begin_visitor(
+  Thread_Control              *executing,
+  void                        *arg,
+  const User_extensions_Table *callouts
+)
+{
+  User_extensions_thread_begin_extension callout = callouts->thread_begin;
+
+  if ( callout != NULL ) {
+    (*callout)( executing );
+  }
+}
+
+void _User_extensions_Thread_exitted_visitor(
+  Thread_Control              *executing,
+  void                        *arg,
+  const User_extensions_Table *callouts
+)
+{
+  User_extensions_thread_exitted_extension callout = callouts->thread_exitted;
+
+  if ( callout != NULL ) {
+    (*callout)( executing );
+  }
+}
+
+void _User_extensions_Fatal_visitor(
+  Thread_Control              *executing,
+  void                        *arg,
+  const User_extensions_Table *callouts
+)
+{
+  User_extensions_fatal_extension callout = callouts->fatal;
+
+  if ( callout != NULL ) {
+    const User_extensions_Fatal_context *ctx = arg;
+
+    (*callout)( ctx->source, ctx->is_internal, ctx->error );
+  }
+}
+
+void _User_extensions_Iterate(
+  void                    *arg,
+  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;
+
+  while ( node != tail ) {
+    const User_extensions_Control *extension =
+      (const User_extensions_Control *) node;
+
+    (*visitor)( executing, arg, &extension->Callouts );
+
+    node = _Chain_Immutable_next( node );
+  }
+}
diff --git a/cpukit/score/src/userextthreadbegin.c b/cpukit/score/src/userextthreadbegin.c
deleted file mode 100644
index b3e673b..0000000
--- a/cpukit/score/src/userextthreadbegin.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * @file
- *
- * @ingroup ScoreUserExt
- *
- * @brief User Extension Handler implementation.
- */
-
-/*
- *  COPYRIGHT (c) 1989-2007.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.com/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems/system.h>
-#include <rtems/score/userext.h>
-
-void _User_extensions_Thread_begin (
-  Thread_Control *executing
-)
-{
-  Chain_Node              *the_node;
-  User_extensions_Control *the_extension;
-
-  for ( the_node = _Chain_First( &_User_extensions_List );
-        !_Chain_Is_tail( &_User_extensions_List, the_node ) ;
-        the_node = the_node->next ) {
-
-    the_extension = (User_extensions_Control *) the_node;
-
-    if ( the_extension->Callouts.thread_begin != NULL )
-      (*the_extension->Callouts.thread_begin)( executing );
-  }
-}
-
-void _User_extensions_Thread_exitted (
-  Thread_Control *executing
-)
-{
-  Chain_Node              *the_node;
-  User_extensions_Control *the_extension;
-
-  for ( the_node = _Chain_Last( &_User_extensions_List );
-        !_Chain_Is_head( &_User_extensions_List, the_node ) ;
-        the_node = the_node->previous ) {
-
-    the_extension = (User_extensions_Control *) the_node;
-
-    if ( the_extension->Callouts.thread_exitted != NULL )
-      (*the_extension->Callouts.thread_exitted)( executing );
-  }
-}
-
-void _User_extensions_Fatal (
-  Internal_errors_Source  the_source,
-  bool                    is_internal,
-  Internal_errors_t       the_error
-)
-{
-  Chain_Node              *the_node;
-  User_extensions_Control *the_extension;
-
-  for ( the_node = _Chain_Last( &_User_extensions_List );
-        !_Chain_Is_head( &_User_extensions_List, the_node ) ;
-        the_node = the_node->previous ) {
-
-    the_extension = (User_extensions_Control *) the_node;
-
-    if ( the_extension->Callouts.fatal != NULL )
-      (*the_extension->Callouts.fatal)( the_source, is_internal, the_error );
-  }
-}
diff --git a/cpukit/score/src/userextthreadcreate.c b/cpukit/score/src/userextthreadcreate.c
deleted file mode 100644
index 21a1cb3..0000000
--- a/cpukit/score/src/userextthreadcreate.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * @file
- *
- * @ingroup ScoreUserExt
- *
- * @brief User Extension Handler implementation.
- */
-
-/*
- *  COPYRIGHT (c) 1989-2007.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.com/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems/system.h>
-#include <rtems/score/userext.h>
-
-bool _User_extensions_Thread_create (
-  Thread_Control *the_thread
-)
-{
-  Chain_Node              *the_node;
-  User_extensions_Control *the_extension;
-  bool                     status;
-
-  for ( the_node = _Chain_First( &_User_extensions_List );
-        !_Chain_Is_tail( &_User_extensions_List, the_node ) ;
-        the_node = the_node->next ) {
-
-    the_extension = (User_extensions_Control *) the_node;
-
-    if ( the_extension->Callouts.thread_create != NULL ) {
-      status = (*the_extension->Callouts.thread_create)(
-        _Thread_Executing,
-        the_thread
-      );
-      if ( !status )
-        return false;
-    }
-  }
-
-  return true;
-}
diff --git a/cpukit/score/src/userextthreaddelete.c b/cpukit/score/src/userextthreaddelete.c
deleted file mode 100644
index 559bddb..0000000
--- a/cpukit/score/src/userextthreaddelete.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @file
- *
- * @ingroup ScoreUserExt
- *
- * @brief User Extension Handler implementation.
- */
-
-/*
- *  COPYRIGHT (c) 1989-2007.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.com/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems/system.h>
-#include <rtems/score/userext.h>
-
-void _User_extensions_Thread_delete (
-  Thread_Control *the_thread
-)
-{
-  Chain_Node              *the_node;
-  User_extensions_Control *the_extension;
-
-  for ( the_node = _Chain_Last( &_User_extensions_List );
-        !_Chain_Is_head( &_User_extensions_List, the_node ) ;
-        the_node = the_node->previous ) {
-
-    the_extension = (User_extensions_Control *) the_node;
-
-    if ( the_extension->Callouts.thread_delete != NULL )
-      (*the_extension->Callouts.thread_delete)(
-        _Thread_Executing,
-        the_thread
-      );
-  }
-}
diff --git a/cpukit/score/src/userextthreadrestart.c b/cpukit/score/src/userextthreadrestart.c
deleted file mode 100644
index 17079ad..0000000
--- a/cpukit/score/src/userextthreadrestart.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @file
- *
- * @ingroup ScoreUserExt
- *
- * @brief User Extension Handler implementation.
- */
-
-/*
- *  COPYRIGHT (c) 1989-2007.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.com/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems/system.h>
-#include <rtems/score/userext.h>
-
-void _User_extensions_Thread_restart (
-  Thread_Control *the_thread
-)
-{
-  Chain_Node              *the_node;
-  User_extensions_Control *the_extension;
-
-  for ( the_node = _Chain_First( &_User_extensions_List );
-        !_Chain_Is_tail( &_User_extensions_List, the_node ) ;
-        the_node = the_node->next ) {
-
-    the_extension = (User_extensions_Control *) the_node;
-
-    if ( the_extension->Callouts.thread_restart != NULL )
-      (*the_extension->Callouts.thread_restart)(
-        _Thread_Executing,
-        the_thread
-      );
-  }
-}
diff --git a/cpukit/score/src/userextthreadstart.c b/cpukit/score/src/userextthreadstart.c
deleted file mode 100644
index c852e5d..0000000
--- a/cpukit/score/src/userextthreadstart.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @file
- *
- * @ingroup ScoreUserExt
- *
- * @brief User Extension Handler implementation.
- */
-
-/*
- *  COPYRIGHT (c) 1989-2007.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.com/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems/system.h>
-#include <rtems/score/userext.h>
-
-void _User_extensions_Thread_start (
-  Thread_Control *the_thread
-)
-{
-  Chain_Node              *the_node;
-  User_extensions_Control *the_extension;
-
-  for ( the_node = _Chain_First( &_User_extensions_List );
-        !_Chain_Is_tail( &_User_extensions_List, the_node ) ;
-        the_node = the_node->next ) {
-
-    the_extension = (User_extensions_Control *) the_node;
-
-    if ( the_extension->Callouts.thread_start != NULL )
-      (*the_extension->Callouts.thread_start)(
-        _Thread_Executing,
-        the_thread
-      );
-  }
-}
-- 
1.7.7




More information about the devel mailing list