score: Add and use _User_extensions_Iterate()

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.
This commit is contained in:
Sebastian Huber
2012-11-07 10:11:17 +01:00
parent 9ed2befb6b
commit e5ae7c927c
8 changed files with 261 additions and 284 deletions

View File

@@ -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

View File

@@ -274,6 +274,83 @@ void _User_extensions_Remove_set(
User_extensions_Control *extension
);
/**
* @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
);
void _User_extensions_Thread_restart_visitor(
Thread_Control *executing,
void *arg,
const User_extensions_Table *callouts
);
void _User_extensions_Thread_begin_visitor(
Thread_Control *executing,
void *arg,
const User_extensions_Table *callouts
);
void _User_extensions_Thread_exitted_visitor(
Thread_Control *executing,
void *arg,
const User_extensions_Table *callouts
);
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
);
/**
* @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
);
/** @} */
/**
@@ -282,40 +359,70 @@ void _User_extensions_Remove_set(
* @{
*/
bool _User_extensions_Thread_create(
Thread_Control *created
);
static inline bool _User_extensions_Thread_create( Thread_Control *created )
{
User_extensions_Thread_create_context ctx = { created, true };
void _User_extensions_Thread_delete(
Thread_Control *deleted
);
_User_extensions_Iterate( &ctx, _User_extensions_Thread_create_visitor );
void _User_extensions_Thread_start(
Thread_Control *started
);
return ctx.ok;
}
void _User_extensions_Thread_restart(
Thread_Control *restarted
);
static inline void _User_extensions_Thread_delete( Thread_Control *deleted )
{
_User_extensions_Iterate(
deleted,
_User_extensions_Thread_delete_visitor
);
}
void _User_extensions_Thread_begin(
Thread_Control *executing
);
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 );
}
/** @} */

View File

@@ -0,0 +1,133 @@
/*
* Copyright (c) 2012 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Obere Lagerstr. 30
* 82178 Puchheim
* Germany
* <rtems@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 );
}
}

View File

@@ -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 );
}
}

View File

@@ -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;
}

View File

@@ -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
);
}
}

View File

@@ -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
);
}
}

View File

@@ -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
);
}
}