diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-06-11 14:31:03 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-07-08 16:30:48 +0200 |
commit | 8568341d69d16609a3dcf71716a89839b16ac881 (patch) | |
tree | 900c88db84557962dda75671eedd39911e1f2dc5 /cpukit/score/include/rtems | |
parent | score: Add _Scheduler_Help() (diff) | |
download | rtems-8568341d69d16609a3dcf71716a89839b16ac881.tar.bz2 |
score: Need for help indicator for scheduler ops
Return a thread in need for help for the following scheduler operations
- unblock,
- change priority, and
- yield.
A thread in need for help is a thread that encounters a scheduler state
change from scheduled to ready or a thread that cannot be scheduled in
an unblock operation. Such a thread can ask threads which depend on
resources owned by this thread for help.
Diffstat (limited to 'cpukit/score/include/rtems')
10 files changed, 137 insertions, 50 deletions
diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h index bb30a8e61e..993ae55b29 100644 --- a/cpukit/score/include/rtems/score/scheduler.h +++ b/cpukit/score/include/rtems/score/scheduler.h @@ -44,6 +44,16 @@ typedef struct Scheduler_Control Scheduler_Control; typedef struct Scheduler_Node Scheduler_Node; +#if defined(RTEMS_SMP) + typedef Thread_Control * Scheduler_Void_or_thread; + + #define SCHEDULER_RETURN_VOID_OR_NULL return NULL +#else + typedef void Scheduler_Void_or_thread; + + #define SCHEDULER_RETURN_VOID_OR_NULL return +#endif + /** * @brief The scheduler operations. */ @@ -55,16 +65,25 @@ typedef struct { void ( *schedule )( const Scheduler_Control *, Thread_Control *); /** @see _Scheduler_Yield() */ - void ( *yield )( const Scheduler_Control *, Thread_Control *); + Scheduler_Void_or_thread ( *yield )( + const Scheduler_Control *, + Thread_Control * + ); /** @see _Scheduler_Block() */ - void ( *block )( const Scheduler_Control *, Thread_Control * ); + void ( *block )( + const Scheduler_Control *, + Thread_Control * + ); /** @see _Scheduler_Unblock() */ - void ( *unblock )( const Scheduler_Control *, Thread_Control * ); + Scheduler_Void_or_thread ( *unblock )( + const Scheduler_Control *, + Thread_Control * + ); /** @see _Scheduler_Change_priority() */ - void ( *change_priority )( + Scheduler_Void_or_thread ( *change_priority )( const Scheduler_Control *, Thread_Control *, Priority_Control, diff --git a/cpukit/score/include/rtems/score/schedulercbs.h b/cpukit/score/include/rtems/score/schedulercbs.h index 3b59301125..008cc91261 100644 --- a/cpukit/score/include/rtems/score/schedulercbs.h +++ b/cpukit/score/include/rtems/score/schedulercbs.h @@ -153,7 +153,7 @@ extern Scheduler_CBS_Server _Scheduler_CBS_Server_list[]; * * @note This has to be asessed as missed deadline of the current job. */ -void _Scheduler_CBS_Unblock( +Scheduler_Void_or_thread _Scheduler_CBS_Unblock( const Scheduler_Control *scheduler, Thread_Control *the_thread ); diff --git a/cpukit/score/include/rtems/score/scheduleredf.h b/cpukit/score/include/rtems/score/scheduleredf.h index 6d759f5535..1dda767cf6 100644 --- a/cpukit/score/include/rtems/score/scheduleredf.h +++ b/cpukit/score/include/rtems/score/scheduleredf.h @@ -177,12 +177,12 @@ void _Scheduler_EDF_Update_priority( * * @param[in] the_thread will be unblocked. */ -void _Scheduler_EDF_Unblock( +Scheduler_Void_or_thread _Scheduler_EDF_Unblock( const Scheduler_Control *scheduler, Thread_Control *the_thread ); -void _Scheduler_EDF_Change_priority( +Scheduler_Void_or_thread _Scheduler_EDF_Change_priority( const Scheduler_Control *scheduler, Thread_Control *the_thread, Priority_Control new_priority, @@ -204,7 +204,7 @@ void _Scheduler_EDF_Change_priority( * * @param[in,out] thread The yielding thread. */ -void _Scheduler_EDF_Yield( +Scheduler_Void_or_thread _Scheduler_EDF_Yield( const Scheduler_Control *scheduler, Thread_Control *the_thread ); diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h index edb68b649a..5e4e5098d2 100644 --- a/cpukit/score/include/rtems/score/schedulerimpl.h +++ b/cpukit/score/include/rtems/score/schedulerimpl.h @@ -116,6 +116,24 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Schedule( Thread_Control *the_thread ) ( *scheduler->Operations.schedule )( scheduler, the_thread ); } +#if defined(RTEMS_SMP) +/** + * @brief Ask threads depending on resources owned by the thread for help. + * + * A thread is in need for help if it lost its assigned processor due to + * pre-emption by a higher priority thread or it was not possible to assign it + * a processor since its priority is to low on its current scheduler instance. + * + * @param[in] needs_help The thread needing help. + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Ask_for_help_if_necessary( + Thread_Control *needs_help +) +{ + (void) needs_help; +} +#endif + /** * @brief Scheduler yield with a particular thread. * @@ -127,8 +145,16 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Schedule( Thread_Control *the_thread ) RTEMS_INLINE_ROUTINE void _Scheduler_Yield( Thread_Control *the_thread ) { const Scheduler_Control *scheduler = _Scheduler_Get( the_thread ); +#if defined(RTEMS_SMP) + Thread_Control *needs_help; + needs_help = +#endif ( *scheduler->Operations.yield )( scheduler, the_thread ); + +#if defined(RTEMS_SMP) + _Scheduler_Ask_for_help_if_necessary( needs_help ); +#endif } /** @@ -161,8 +187,16 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Block( Thread_Control *the_thread ) RTEMS_INLINE_ROUTINE void _Scheduler_Unblock( Thread_Control *the_thread ) { const Scheduler_Control *scheduler = _Scheduler_Get( the_thread ); +#if defined(RTEMS_SMP) + Thread_Control *needs_help; + needs_help = +#endif ( *scheduler->Operations.unblock )( scheduler, the_thread ); + +#if defined(RTEMS_SMP) + _Scheduler_Ask_for_help_if_necessary( needs_help ); +#endif } /** @@ -185,13 +219,21 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Change_priority( ) { const Scheduler_Control *scheduler = _Scheduler_Get( the_thread ); +#if defined(RTEMS_SMP) + Thread_Control *needs_help; + needs_help = +#endif ( *scheduler->Operations.change_priority )( scheduler, the_thread, new_priority, prepend_it ); + +#if defined(RTEMS_SMP) + _Scheduler_Ask_for_help_if_necessary( needs_help ); +#endif } /** diff --git a/cpukit/score/include/rtems/score/schedulerpriority.h b/cpukit/score/include/rtems/score/schedulerpriority.h index e412bab6bf..805e30257d 100644 --- a/cpukit/score/include/rtems/score/schedulerpriority.h +++ b/cpukit/score/include/rtems/score/schedulerpriority.h @@ -149,12 +149,12 @@ void _Scheduler_priority_Update_priority( * * @param[in] the_thread will be unblocked */ -void _Scheduler_priority_Unblock( +Scheduler_Void_or_thread _Scheduler_priority_Unblock( const Scheduler_Control *scheduler, Thread_Control *the_thread ); -void _Scheduler_priority_Change_priority( +Scheduler_Void_or_thread _Scheduler_priority_Change_priority( const Scheduler_Control *scheduler, Thread_Control *the_thread, Priority_Control new_priority, @@ -180,7 +180,7 @@ void _Scheduler_priority_Change_priority( * * @param[in,out] thread The yielding thread. */ -void _Scheduler_priority_Yield( +Scheduler_Void_or_thread _Scheduler_priority_Yield( const Scheduler_Control *scheduler, Thread_Control *the_thread ); diff --git a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h index 831d1d47a6..3a235104cf 100644 --- a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h +++ b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h @@ -101,7 +101,7 @@ void _Scheduler_priority_affinity_SMP_Block( * @param[in] scheduler is the scheduler instance information * @param[in] thread is the thread to unblock */ -void _Scheduler_priority_affinity_SMP_Unblock( +Thread_Control *_Scheduler_priority_affinity_SMP_Unblock( const Scheduler_Control *scheduler, Thread_Control *thread ); @@ -132,7 +132,7 @@ bool _Scheduler_priority_affinity_SMP_Get_affinity( * @param[in] new_priority The new priority for the thread. * @param[in] prepend_it Append or prepend the thread to its priority FIFO. */ -void _Scheduler_priority_affinity_SMP_Change_priority( +Thread_Control *_Scheduler_priority_affinity_SMP_Change_priority( const Scheduler_Control *scheduler, Thread_Control *the_thread, Priority_Control new_priority, diff --git a/cpukit/score/include/rtems/score/schedulerprioritysmp.h b/cpukit/score/include/rtems/score/schedulerprioritysmp.h index e922c2b998..a1a148173d 100644 --- a/cpukit/score/include/rtems/score/schedulerprioritysmp.h +++ b/cpukit/score/include/rtems/score/schedulerprioritysmp.h @@ -106,12 +106,12 @@ void _Scheduler_priority_SMP_Block( Thread_Control *thread ); -void _Scheduler_priority_SMP_Unblock( +Thread_Control *_Scheduler_priority_SMP_Unblock( const Scheduler_Control *scheduler, Thread_Control *thread ); -void _Scheduler_priority_SMP_Change_priority( +Thread_Control *_Scheduler_priority_SMP_Change_priority( const Scheduler_Control *scheduler, Thread_Control *the_thread, Priority_Control new_priority, @@ -124,7 +124,7 @@ void _Scheduler_priority_SMP_Update_priority( Priority_Control new_priority ); -void _Scheduler_priority_SMP_Yield( +Thread_Control *_Scheduler_priority_SMP_Yield( const Scheduler_Control *scheduler, Thread_Control *thread ); diff --git a/cpukit/score/include/rtems/score/schedulersimple.h b/cpukit/score/include/rtems/score/schedulersimple.h index ef60613d1b..c97ad2f3c6 100644 --- a/cpukit/score/include/rtems/score/schedulersimple.h +++ b/cpukit/score/include/rtems/score/schedulersimple.h @@ -101,7 +101,7 @@ void _Scheduler_simple_Schedule( * * @param[in,out] thread The yielding thread. */ -void _Scheduler_simple_Yield( +Scheduler_Void_or_thread _Scheduler_simple_Yield( const Scheduler_Control *scheduler, Thread_Control *the_thread ); @@ -130,12 +130,12 @@ void _Scheduler_simple_Block( * * @param[in] the_thread is the thread that is to be unblocked */ -void _Scheduler_simple_Unblock( +Scheduler_Void_or_thread _Scheduler_simple_Unblock( const Scheduler_Control *scheduler, Thread_Control *the_thread ); -void _Scheduler_simple_Change_priority( +Scheduler_Void_or_thread _Scheduler_simple_Change_priority( const Scheduler_Control *scheduler, Thread_Control *the_thread, Priority_Control new_priority, diff --git a/cpukit/score/include/rtems/score/schedulersimplesmp.h b/cpukit/score/include/rtems/score/schedulersimplesmp.h index 790ceddc1d..de338ab168 100644 --- a/cpukit/score/include/rtems/score/schedulersimplesmp.h +++ b/cpukit/score/include/rtems/score/schedulersimplesmp.h @@ -87,12 +87,12 @@ void _Scheduler_simple_SMP_Block( Thread_Control *thread ); -void _Scheduler_simple_SMP_Unblock( +Thread_Control *_Scheduler_simple_SMP_Unblock( const Scheduler_Control *scheduler, Thread_Control *thread ); -void _Scheduler_simple_SMP_Change_priority( +Thread_Control *_Scheduler_simple_SMP_Change_priority( const Scheduler_Control *scheduler, Thread_Control *the_thread, Priority_Control new_priority, @@ -105,7 +105,7 @@ void _Scheduler_simple_SMP_Update_priority( Priority_Control new_priority ); -void _Scheduler_simple_SMP_Yield( +Thread_Control *_Scheduler_simple_SMP_Yield( const Scheduler_Control *scheduler, Thread_Control *thread ); diff --git a/cpukit/score/include/rtems/score/schedulersmpimpl.h b/cpukit/score/include/rtems/score/schedulersmpimpl.h index b7d86a36e8..55d0697df1 100644 --- a/cpukit/score/include/rtems/score/schedulersmpimpl.h +++ b/cpukit/score/include/rtems/score/schedulersmpimpl.h @@ -306,7 +306,13 @@ typedef void ( *Scheduler_SMP_Update )( Priority_Control new_priority ); -typedef void ( *Scheduler_SMP_Enqueue )( +typedef Thread_Control *( *Scheduler_SMP_Enqueue )( + Scheduler_Context *context, + Scheduler_Node *node_to_enqueue, + Thread_Control *needs_help +); + +typedef Thread_Control *( *Scheduler_SMP_Enqueue_scheduled )( Scheduler_Context *context, Scheduler_Node *node_to_enqueue ); @@ -492,6 +498,8 @@ static inline Scheduler_Node *_Scheduler_SMP_Get_lowest_scheduled( * * @param[in] context The scheduler instance context. * @param[in] node The node to enqueue. + * @param[in] needs_help The thread needing help in case the node cannot be + * scheduled. * @param[in] order The order function. * @param[in] insert_ready Function to insert a node into the set of ready * nodes. @@ -506,9 +514,10 @@ static inline Scheduler_Node *_Scheduler_SMP_Get_lowest_scheduled( * @param[in] allocate_processor Function to allocate a processor to a node * based on the rules of the scheduler. */ -static inline void _Scheduler_SMP_Enqueue_ordered( +static inline Thread_Control *_Scheduler_SMP_Enqueue_ordered( Scheduler_Context *context, Scheduler_Node *node, + Thread_Control *needs_help, Chain_Node_order order, Scheduler_SMP_Insert insert_ready, Scheduler_SMP_Insert insert_scheduled, @@ -535,9 +544,13 @@ static inline void _Scheduler_SMP_Enqueue_ordered( ( *insert_scheduled )( context, node ); ( *move_from_scheduled_to_ready )( context, lowest_scheduled ); + + needs_help = _Scheduler_Node_get_user( lowest_scheduled ); } else { ( *insert_ready )( context, node ); } + + return needs_help; } /** @@ -557,7 +570,7 @@ static inline void _Scheduler_SMP_Enqueue_ordered( * @param[in] allocate_processor Function to allocate a processor to a node * based on the rules of the scheduler. */ -static inline void _Scheduler_SMP_Enqueue_scheduled_ordered( +static inline Thread_Control *_Scheduler_SMP_Enqueue_scheduled_ordered( Scheduler_Context *context, Scheduler_Node *node, Chain_Node_order order, @@ -569,6 +582,7 @@ static inline void _Scheduler_SMP_Enqueue_scheduled_ordered( ) { Scheduler_Node *highest_ready = ( *get_highest_ready )( context, node ); + Thread_Control *needs_help; _Assert( highest_ready != NULL ); @@ -578,6 +592,8 @@ static inline void _Scheduler_SMP_Enqueue_scheduled_ordered( */ if ( ( *order )( &node->Node, &highest_ready->Node ) ) { ( *insert_scheduled )( context, node ); + + needs_help = NULL; } else { _Scheduler_SMP_Node_change_state( _Scheduler_SMP_Node_downcast( node ), @@ -593,7 +609,11 @@ static inline void _Scheduler_SMP_Enqueue_scheduled_ordered( ( *insert_ready )( context, node ); ( *move_from_ready_to_scheduled )( context, highest_ready ); + + needs_help = _Scheduler_Node_get_user( node ); } + + return needs_help; } static inline void _Scheduler_SMP_Extract_from_scheduled( @@ -663,7 +683,7 @@ static inline void _Scheduler_SMP_Block( } } -static inline void _Scheduler_SMP_Unblock( +static inline Thread_Control *_Scheduler_SMP_Unblock( Scheduler_Context *context, Thread_Control *thread, Scheduler_SMP_Enqueue enqueue_fifo @@ -673,23 +693,24 @@ static inline void _Scheduler_SMP_Unblock( _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY ); - ( *enqueue_fifo )( context, &node->Base ); + return ( *enqueue_fifo )( context, &node->Base, thread ); } -static inline void _Scheduler_SMP_Change_priority( - Scheduler_Context *context, - Thread_Control *thread, - Priority_Control new_priority, - bool prepend_it, - Scheduler_SMP_Extract extract_from_ready, - Scheduler_SMP_Update update, - Scheduler_SMP_Enqueue enqueue_fifo, - Scheduler_SMP_Enqueue enqueue_lifo, - Scheduler_SMP_Enqueue enqueue_scheduled_fifo, - Scheduler_SMP_Enqueue enqueue_scheduled_lifo +static inline Thread_Control *_Scheduler_SMP_Change_priority( + Scheduler_Context *context, + Thread_Control *thread, + Priority_Control new_priority, + bool prepend_it, + Scheduler_SMP_Extract extract_from_ready, + Scheduler_SMP_Update update, + Scheduler_SMP_Enqueue enqueue_fifo, + Scheduler_SMP_Enqueue enqueue_lifo, + Scheduler_SMP_Enqueue_scheduled enqueue_scheduled_fifo, + Scheduler_SMP_Enqueue_scheduled enqueue_scheduled_lifo ) { Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_node( thread ); + Thread_Control *needs_help; if ( node->state == SCHEDULER_SMP_NODE_SCHEDULED ) { _Scheduler_SMP_Extract_from_scheduled( &node->Base ); @@ -697,9 +718,9 @@ static inline void _Scheduler_SMP_Change_priority( ( *update )( context, &node->Base, new_priority ); if ( prepend_it ) { - ( *enqueue_scheduled_lifo )( context, &node->Base ); + needs_help = ( *enqueue_scheduled_lifo )( context, &node->Base ); } else { - ( *enqueue_scheduled_fifo )( context, &node->Base ); + needs_help = ( *enqueue_scheduled_fifo )( context, &node->Base ); } } else { ( *extract_from_ready )( context, &node->Base ); @@ -707,32 +728,37 @@ static inline void _Scheduler_SMP_Change_priority( ( *update )( context, &node->Base, new_priority ); if ( prepend_it ) { - ( *enqueue_lifo )( context, &node->Base ); + needs_help = ( *enqueue_lifo )( context, &node->Base, NULL ); } else { - ( *enqueue_fifo )( context, &node->Base ); + needs_help = ( *enqueue_fifo )( context, &node->Base, NULL ); } } + + return needs_help; } -static inline void _Scheduler_SMP_Yield( - Scheduler_Context *context, - Thread_Control *thread, - Scheduler_SMP_Extract extract_from_ready, - Scheduler_SMP_Enqueue enqueue_fifo, - Scheduler_SMP_Enqueue enqueue_scheduled_fifo +static inline Thread_Control *_Scheduler_SMP_Yield( + Scheduler_Context *context, + Thread_Control *thread, + Scheduler_SMP_Extract extract_from_ready, + Scheduler_SMP_Enqueue enqueue_fifo, + Scheduler_SMP_Enqueue_scheduled enqueue_scheduled_fifo ) { Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_node( thread ); + Thread_Control *needs_help; if ( node->state == SCHEDULER_SMP_NODE_SCHEDULED ) { _Scheduler_SMP_Extract_from_scheduled( &node->Base ); - ( *enqueue_scheduled_fifo )( context, &node->Base ); + needs_help = ( *enqueue_scheduled_fifo )( context, &node->Base ); } else { ( *extract_from_ready )( context, &node->Base ); - ( *enqueue_fifo )( context, &node->Base ); + needs_help = ( *enqueue_fifo )( context, &node->Base, NULL ); } + + return needs_help; } static inline void _Scheduler_SMP_Insert_scheduled_lifo( |