summaryrefslogblamecommitdiffstats
path: root/cpukit/score/include/rtems/score/userextimpl.h
blob: a79b858b2677378189d5ac2a54e8f0ac66686809 (plain) (tree)
1
2
3
4
5
6




                        
                                    














                                                           
                                  





                  



                                                
                           
   
        












                                                    
   
        

































































































                                                                              
                                                        









                                     
   
        









































                                                                               
                                                  

                            














                                                               




























                                                                               
                         
/**
 * @file
 *
 * @ingroup ScoreUserExt
 *
 * @brief User Extension Handler API
 */

/*
 *  COPYRIGHT (c) 1989-2009.
 *  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.
 */

#ifndef _RTEMS_SCORE_USEREXTIMPL_H
#define _RTEMS_SCORE_USEREXTIMPL_H

#include <rtems/score/userext.h>
#include <rtems/score/chainimpl.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defgroup ScoreUserExt User Extension Handler
 *
 * @ingroup Score
 *
 * @addtogroup ScoreUserExt
 */
/**@{**/

/**
 * @brief List of active extensions.
 */
extern Chain_Control _User_extensions_List;

/**
 * @brief List of active task switch extensions.
 */
extern Chain_Control _User_extensions_Switches_list;

/**
 * @name Extension Maintainance
 */
/**@{**/

void _User_extensions_Handler_initialization( void );

void _User_extensions_Add_set(
  User_extensions_Control *extension
);

RTEMS_INLINE_ROUTINE void _User_extensions_Add_API_set(
  User_extensions_Control *extension
)
{
  _User_extensions_Add_set( extension );
}

RTEMS_INLINE_ROUTINE void _User_extensions_Add_set_with_table(
  User_extensions_Control     *extension,
  const User_extensions_Table *extension_table
)
{
  extension->Callouts = *extension_table;

  _User_extensions_Add_set( extension );
}

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

static inline void _User_extensions_Thread_switch(
  Thread_Control *executing,
  Thread_Control *heir
)
{
  const Chain_Control *chain = &_User_extensions_Switches_list;
  const Chain_Node    *tail = _Chain_Immutable_tail( chain );
  const Chain_Node    *node = _Chain_Immutable_first( chain );

  while ( node != tail ) {
    const User_extensions_Switch_control *extension =
      (const User_extensions_Switch_control *) node;

    (*extension->thread_switch)( executing, heir );

    node = _Chain_Immutable_next( node );
  }
}

static inline void _User_extensions_Thread_exitted( Thread_Control *executing )
{
  _User_extensions_Iterate(
    executing,
    _User_extensions_Thread_exitted_visitor
  );
}

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

/** @} */

/** @} */

#ifdef __cplusplus
}
#endif

#endif
/* end of include file */