forked from Imagelibrary/rtems
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:
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
133
cpukit/score/src/userextiterate.c
Normal file
133
cpukit/score/src/userextiterate.c
Normal 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 );
|
||||
}
|
||||
}
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user