mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-08-30 23:58:11 +08:00
score: Add thread actions
Thread actions are the building block for efficient implementation of - Classic signals delivery, - POSIX signals delivery, - thread restart notification, - thread delete notification, - forced thread migration on SMP configurations, and - the Multiprocessor Resource Sharing Protocol (MrsP).
This commit is contained in:
@@ -340,6 +340,62 @@ typedef enum {
|
||||
/** This macro defines the last API which has threads. */
|
||||
#define THREAD_API_LAST THREAD_API_POSIX
|
||||
|
||||
typedef struct Thread_Action Thread_Action;
|
||||
|
||||
/**
|
||||
* @brief Thread action handler.
|
||||
*
|
||||
* The thread action handler will be called with interrupts disabled and the
|
||||
* thread action lock acquired. The handler must release the thread action
|
||||
* lock with _Thread_Action_release_and_ISR_enable(). So the thread action
|
||||
* lock can be used to protect private data fields of the particular action.
|
||||
*
|
||||
* Since the action is passed to the handler private data fields can be added
|
||||
* below the common thread action fields.
|
||||
*
|
||||
* @param[in] thread The thread performing the action.
|
||||
* @param[in] action The thread action.
|
||||
* @param[in] cpu The processor of the thread.
|
||||
* @param[in] level The ISR level for _Thread_Action_release_and_ISR_enable().
|
||||
*/
|
||||
typedef void ( *Thread_Action_handler )(
|
||||
Thread_Control *thread,
|
||||
Thread_Action *action,
|
||||
Per_CPU_Control *cpu,
|
||||
ISR_Level level
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Thread action.
|
||||
*
|
||||
* Thread actions can be chained together to trigger a set of actions on
|
||||
* particular events like for example a thread post-switch. Use
|
||||
* _Thread_Action_initialize() to initialize this structure.
|
||||
*
|
||||
* Thread actions are the building block for efficient implementation of
|
||||
* - Classic signals delivery,
|
||||
* - POSIX signals delivery,
|
||||
* - thread restart notification,
|
||||
* - thread delete notification,
|
||||
* - forced thread migration on SMP configurations, and
|
||||
* - the Multiprocessor Resource Sharing Protocol (MrsP).
|
||||
*
|
||||
* @see _Thread_Run_post_switch_actions().
|
||||
*/
|
||||
struct Thread_Action {
|
||||
Chain_Node Node;
|
||||
Thread_Action_handler handler;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Control block to manage thread actions.
|
||||
*
|
||||
* Use _Thread_Action_control_initialize() to initialize this structure.
|
||||
*/
|
||||
typedef struct {
|
||||
Chain_Control Chain;
|
||||
} Thread_Action_control;
|
||||
|
||||
/**
|
||||
* This structure defines the Thread Control Block (TCB).
|
||||
*/
|
||||
@@ -457,6 +513,9 @@ struct Thread_Control_struct {
|
||||
* this thread.
|
||||
*/
|
||||
Thread_Start_information Start;
|
||||
|
||||
Thread_Action_control Post_switch_actions;
|
||||
|
||||
/** This field contains the context of this thread. */
|
||||
Context_Control Registers;
|
||||
#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define _RTEMS_SCORE_THREADIMPL_H
|
||||
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/chainimpl.h>
|
||||
#include <rtems/score/interr.h>
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/score/objectimpl.h>
|
||||
@@ -639,6 +640,72 @@ RTEMS_INLINE_ROUTINE void _Thread_Update_cpu_time_used(
|
||||
_Timestamp_Add_to( &executing->cpu_time_used, &ran );
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Thread_Action_control_initialize(
|
||||
Thread_Action_control *action_control
|
||||
)
|
||||
{
|
||||
_Chain_Initialize_empty( &action_control->Chain );
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Thread_Action_initialize(
|
||||
Thread_Action *action,
|
||||
Thread_Action_handler handler
|
||||
)
|
||||
{
|
||||
action->handler = handler;
|
||||
_Chain_Set_off_chain( &action->Node );
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE Per_CPU_Control *
|
||||
_Thread_Action_ISR_disable_and_acquire_for_executing( ISR_Level *level )
|
||||
{
|
||||
Per_CPU_Control *cpu;
|
||||
|
||||
_ISR_Disable_without_giant( *level );
|
||||
cpu = _Per_CPU_Get();
|
||||
_Per_CPU_Acquire( cpu );
|
||||
|
||||
return cpu;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_Action_ISR_disable_and_acquire(
|
||||
Thread_Control *thread,
|
||||
ISR_Level *level
|
||||
)
|
||||
{
|
||||
Per_CPU_Control *cpu;
|
||||
|
||||
_ISR_Disable_without_giant( *level );
|
||||
cpu = _Thread_Get_CPU( thread );
|
||||
_Per_CPU_Acquire( cpu );
|
||||
|
||||
return cpu;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Thread_Action_release_and_ISR_enable(
|
||||
Per_CPU_Control *cpu,
|
||||
ISR_Level level
|
||||
)
|
||||
{
|
||||
_Per_CPU_Release_and_ISR_enable( cpu, level );
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Thread_Add_post_switch_action(
|
||||
Thread_Control *thread,
|
||||
Thread_Action *action
|
||||
)
|
||||
{
|
||||
Per_CPU_Control *cpu;
|
||||
ISR_Level level;
|
||||
|
||||
cpu = _Thread_Action_ISR_disable_and_acquire( thread, &level );
|
||||
_Chain_Append_if_is_off_chain_unprotected(
|
||||
&thread->Post_switch_actions.Chain,
|
||||
&action->Node
|
||||
);
|
||||
_Thread_Action_release_and_ISR_enable( cpu, level );
|
||||
}
|
||||
|
||||
#if !defined(__DYNAMIC_REENT__)
|
||||
/**
|
||||
* This routine returns the C library re-enterant pointer.
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
* COPYRIGHT (c) 1989-2009.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* Copyright (c) 2014 embedded brains GmbH.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
@@ -27,6 +29,36 @@
|
||||
#include <rtems/score/userextimpl.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
|
||||
static Thread_Action *_Thread_Get_post_switch_action(
|
||||
Thread_Control *executing
|
||||
)
|
||||
{
|
||||
Chain_Control *chain = &executing->Post_switch_actions.Chain;
|
||||
|
||||
return (Thread_Action *) _Chain_Get_unprotected( chain );
|
||||
}
|
||||
|
||||
static void _Thread_Run_post_switch_actions( Thread_Control *executing )
|
||||
{
|
||||
ISR_Level level;
|
||||
Per_CPU_Control *cpu;
|
||||
Thread_Action *action;
|
||||
|
||||
cpu = _Thread_Action_ISR_disable_and_acquire( executing, &level );
|
||||
action = _Thread_Get_post_switch_action( executing );
|
||||
|
||||
while ( action != NULL ) {
|
||||
_Chain_Set_off_chain( &action->Node );
|
||||
|
||||
( *action->handler )( executing, action, cpu, level );
|
||||
|
||||
cpu = _Thread_Action_ISR_disable_and_acquire( executing, &level );
|
||||
action = _Thread_Get_post_switch_action( executing );
|
||||
}
|
||||
|
||||
_Thread_Action_release_and_ISR_enable( cpu, level );
|
||||
}
|
||||
|
||||
void _Thread_Dispatch( void )
|
||||
{
|
||||
Per_CPU_Control *per_cpu;
|
||||
@@ -176,4 +208,5 @@ post_switch:
|
||||
_Per_CPU_Release_and_ISR_enable( per_cpu, level );
|
||||
|
||||
_API_extensions_Run_post_switch( executing );
|
||||
_Thread_Run_post_switch_actions( executing );
|
||||
}
|
||||
|
||||
@@ -238,6 +238,8 @@ bool _Thread_Initialize(
|
||||
*/
|
||||
_Chain_Initialize_empty( &the_thread->Key_Chain );
|
||||
|
||||
_Thread_Action_control_initialize( &the_thread->Post_switch_actions );
|
||||
|
||||
/*
|
||||
* Open the object
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user