From 8568341d69d16609a3dcf71716a89839b16ac881 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 11 Jun 2014 14:31:03 +0200 Subject: 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. --- cpukit/score/include/rtems/score/scheduler.h | 27 +- cpukit/score/include/rtems/score/schedulercbs.h | 2 +- cpukit/score/include/rtems/score/scheduleredf.h | 6 +- cpukit/score/include/rtems/score/schedulerimpl.h | 42 +++ .../score/include/rtems/score/schedulerpriority.h | 6 +- .../rtems/score/schedulerpriorityaffinitysmp.h | 4 +- .../include/rtems/score/schedulerprioritysmp.h | 6 +- cpukit/score/include/rtems/score/schedulersimple.h | 6 +- .../score/include/rtems/score/schedulersimplesmp.h | 6 +- .../score/include/rtems/score/schedulersmpimpl.h | 82 +++-- cpukit/score/src/schedulercbsunblock.c | 4 +- cpukit/score/src/scheduleredfchangepriority.c | 4 +- cpukit/score/src/scheduleredfunblock.c | 4 +- cpukit/score/src/scheduleredfyield.c | 4 +- cpukit/score/src/schedulerpriorityaffinitysmp.c | 49 ++- cpukit/score/src/schedulerprioritychangepriority.c | 4 +- cpukit/score/src/schedulerprioritysmp.c | 54 +-- cpukit/score/src/schedulerpriorityunblock.c | 4 +- cpukit/score/src/schedulerpriorityyield.c | 4 +- cpukit/score/src/schedulersimplechangepriority.c | 4 +- cpukit/score/src/schedulersimplesmp.c | 54 +-- cpukit/score/src/schedulersimpleunblock.c | 4 +- cpukit/score/src/schedulersimpleyield.c | 4 +- testsuites/smptests/smpscheduler03/init.c | 403 ++++++++++++++++++++- 24 files changed, 645 insertions(+), 142 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( diff --git a/cpukit/score/src/schedulercbsunblock.c b/cpukit/score/src/schedulercbsunblock.c index 5822af2934..688253c279 100644 --- a/cpukit/score/src/schedulercbsunblock.c +++ b/cpukit/score/src/schedulercbsunblock.c @@ -25,7 +25,7 @@ #include #include -void _Scheduler_CBS_Unblock( +Scheduler_Void_or_thread _Scheduler_CBS_Unblock( const Scheduler_Control *scheduler, Thread_Control *the_thread ) @@ -84,4 +84,6 @@ void _Scheduler_CBS_Unblock( the_thread->current_priority == 0 ) _Thread_Dispatch_necessary = true; } + + SCHEDULER_RETURN_VOID_OR_NULL; } diff --git a/cpukit/score/src/scheduleredfchangepriority.c b/cpukit/score/src/scheduleredfchangepriority.c index 1422fb174e..32b0993d8f 100644 --- a/cpukit/score/src/scheduleredfchangepriority.c +++ b/cpukit/score/src/scheduleredfchangepriority.c @@ -20,7 +20,7 @@ #include -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, @@ -33,4 +33,6 @@ void _Scheduler_EDF_Change_priority( _RBTree_Extract( &context->Ready, &node->Node ); _RBTree_Insert( &context->Ready, &node->Node ); + + SCHEDULER_RETURN_VOID_OR_NULL; } diff --git a/cpukit/score/src/scheduleredfunblock.c b/cpukit/score/src/scheduleredfunblock.c index 30fa4f0163..469655e9d2 100644 --- a/cpukit/score/src/scheduleredfunblock.c +++ b/cpukit/score/src/scheduleredfunblock.c @@ -22,7 +22,7 @@ #include #include -void _Scheduler_EDF_Unblock( +Scheduler_Void_or_thread _Scheduler_EDF_Unblock( const Scheduler_Control *scheduler, Thread_Control *the_thread ) @@ -51,4 +51,6 @@ void _Scheduler_EDF_Unblock( the_thread->current_priority == 0 ) _Thread_Dispatch_necessary = true; } + + SCHEDULER_RETURN_VOID_OR_NULL; } diff --git a/cpukit/score/src/scheduleredfyield.c b/cpukit/score/src/scheduleredfyield.c index 0990ac0b14..5aa2afd8db 100644 --- a/cpukit/score/src/scheduleredfyield.c +++ b/cpukit/score/src/scheduleredfyield.c @@ -21,7 +21,7 @@ #include -void _Scheduler_EDF_Yield( +Scheduler_Void_or_thread _Scheduler_EDF_Yield( const Scheduler_Control *scheduler, Thread_Control *the_thread ) @@ -38,4 +38,6 @@ void _Scheduler_EDF_Yield( _RBTree_Insert( &context->Ready, &node->Node ); _Scheduler_EDF_Schedule_body( scheduler, the_thread, false ); + + SCHEDULER_RETURN_VOID_OR_NULL; } diff --git a/cpukit/score/src/schedulerpriorityaffinitysmp.c b/cpukit/score/src/schedulerpriorityaffinitysmp.c index e6a662e361..14a022e5d7 100644 --- a/cpukit/score/src/schedulerpriorityaffinitysmp.c +++ b/cpukit/score/src/schedulerpriorityaffinitysmp.c @@ -288,14 +288,16 @@ static Scheduler_Node * _Scheduler_priority_affinity_SMP_Get_lowest_scheduled( * _Scheduler_priority_affinity_SMP_Get_lowest_scheduled into * _Scheduler_SMP_Enqueue_ordered. */ -static void _Scheduler_priority_affinity_SMP_Enqueue_fifo( +static Thread_Control *_Scheduler_priority_affinity_SMP_Enqueue_fifo( Scheduler_Context *context, - Scheduler_Node *node + Scheduler_Node *node, + Thread_Control *needs_help ) { - _Scheduler_SMP_Enqueue_ordered( + return _Scheduler_SMP_Enqueue_ordered( context, node, + needs_help, _Scheduler_priority_affinity_SMP_Insert_priority_fifo_order, _Scheduler_priority_SMP_Insert_ready_fifo, _Scheduler_SMP_Insert_scheduled_fifo, @@ -374,14 +376,15 @@ static void _Scheduler_priority_affinity_SMP_Check_for_migrations( /* * This is the public scheduler specific Unblock operation. */ -void _Scheduler_priority_affinity_SMP_Unblock( +Thread_Control *_Scheduler_priority_affinity_SMP_Unblock( const Scheduler_Control *scheduler, Thread_Control *thread ) { Scheduler_Context *context = _Scheduler_Get_context( scheduler ); + Thread_Control *needs_help; - _Scheduler_SMP_Unblock( + needs_help = _Scheduler_SMP_Unblock( context, thread, _Scheduler_priority_affinity_SMP_Enqueue_fifo @@ -391,23 +394,27 @@ void _Scheduler_priority_affinity_SMP_Unblock( * Perform any thread migrations that are needed due to these changes. */ _Scheduler_priority_affinity_SMP_Check_for_migrations( context ); + + return needs_help; } /* * This is unique to this scheduler because it passes scheduler specific * get_lowest_scheduled helper to _Scheduler_SMP_Enqueue_ordered. */ -static void _Scheduler_priority_affinity_SMP_Enqueue_ordered( +static Thread_Control *_Scheduler_priority_affinity_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 ) { - _Scheduler_SMP_Enqueue_ordered( + return _Scheduler_SMP_Enqueue_ordered( context, node, + needs_help, order, insert_ready, insert_scheduled, @@ -422,14 +429,16 @@ static void _Scheduler_priority_affinity_SMP_Enqueue_ordered( * to _Scheduler_priority_affinity_SMP_Enqueue_ordered() which * invokes a scheduler unique get_lowest_scheduled helper. */ -static void _Scheduler_priority_affinity_SMP_Enqueue_lifo( +static Thread_Control *_Scheduler_priority_affinity_SMP_Enqueue_lifo( Scheduler_Context *context, - Scheduler_Node *node + Scheduler_Node *node, + Thread_Control *needs_help ) { - _Scheduler_priority_affinity_SMP_Enqueue_ordered( + return _Scheduler_priority_affinity_SMP_Enqueue_ordered( context, node, + needs_help, _Scheduler_priority_affinity_SMP_Insert_priority_lifo_order, _Scheduler_priority_SMP_Insert_ready_lifo, _Scheduler_SMP_Insert_scheduled_lifo @@ -441,7 +450,8 @@ static void _Scheduler_priority_affinity_SMP_Enqueue_lifo( * invoke _Scheduler_SMP_Enqueue_scheduled_ordered() with * this scheduler's get_highest_ready() helper. */ -static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered( +static Thread_Control * +_Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered( Scheduler_Context *context, Scheduler_Node *node, Chain_Node_order order, @@ -449,7 +459,7 @@ static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered( Scheduler_SMP_Insert insert_scheduled ) { - _Scheduler_SMP_Enqueue_scheduled_ordered( + return _Scheduler_SMP_Enqueue_scheduled_ordered( context, node, order, @@ -466,12 +476,12 @@ static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered( * to _Scheduler_priority_affinity_SMP_Enqueue_scheduled__ordered() which * invokes a scheduler unique get_lowest_scheduled helper. */ -static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_lifo( +static Thread_Control *_Scheduler_priority_affinity_SMP_Enqueue_scheduled_lifo( Scheduler_Context *context, Scheduler_Node *node ) { - _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered( + return _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered( context, node, _Scheduler_SMP_Insert_priority_lifo_order, @@ -485,12 +495,12 @@ static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_lifo( * to _Scheduler_priority_affinity_SMP_Enqueue_scheduled__ordered() which * invokes a scheduler unique get_lowest_scheduled helper. */ -static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_fifo( +static Thread_Control *_Scheduler_priority_affinity_SMP_Enqueue_scheduled_fifo( Scheduler_Context *context, Scheduler_Node *node ) { - _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered( + return _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered( context, node, _Scheduler_SMP_Insert_priority_fifo_order, @@ -502,7 +512,7 @@ static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_fifo( /* * This is the public scheduler specific Change Priority operation. */ -void _Scheduler_priority_affinity_SMP_Change_priority( +Thread_Control *_Scheduler_priority_affinity_SMP_Change_priority( const Scheduler_Control *scheduler, Thread_Control *thread, Priority_Control new_priority, @@ -510,8 +520,9 @@ void _Scheduler_priority_affinity_SMP_Change_priority( ) { Scheduler_Context *context = _Scheduler_Get_context( scheduler ); + Thread_Control *displaced; - _Scheduler_SMP_Change_priority( + displaced = _Scheduler_SMP_Change_priority( context, thread, new_priority, @@ -528,6 +539,8 @@ void _Scheduler_priority_affinity_SMP_Change_priority( * Perform any thread migrations that are needed due to these changes. */ _Scheduler_priority_affinity_SMP_Check_for_migrations( context ); + + return displaced; } /* diff --git a/cpukit/score/src/schedulerprioritychangepriority.c b/cpukit/score/src/schedulerprioritychangepriority.c index 4f00af6ad6..06c5f0f7c6 100644 --- a/cpukit/score/src/schedulerprioritychangepriority.c +++ b/cpukit/score/src/schedulerprioritychangepriority.c @@ -21,7 +21,7 @@ #include -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, @@ -58,4 +58,6 @@ void _Scheduler_priority_Change_priority( &context->Bit_map ); } + + SCHEDULER_RETURN_VOID_OR_NULL; } diff --git a/cpukit/score/src/schedulerprioritysmp.c b/cpukit/score/src/schedulerprioritysmp.c index 1f6d608538..b642c5d6f3 100644 --- a/cpukit/score/src/schedulerprioritysmp.c +++ b/cpukit/score/src/schedulerprioritysmp.c @@ -97,17 +97,19 @@ void _Scheduler_priority_SMP_Block( ); } -static void _Scheduler_priority_SMP_Enqueue_ordered( - Scheduler_Context *context, - Scheduler_Node *node, - Chain_Node_order order, - Scheduler_SMP_Insert insert_ready, - Scheduler_SMP_Insert insert_scheduled +static Thread_Control *_Scheduler_priority_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 ) { - _Scheduler_SMP_Enqueue_ordered( + return _Scheduler_SMP_Enqueue_ordered( context, node, + needs_help, order, insert_ready, insert_scheduled, @@ -117,35 +119,39 @@ static void _Scheduler_priority_SMP_Enqueue_ordered( ); } -static void _Scheduler_priority_SMP_Enqueue_lifo( +static Thread_Control *_Scheduler_priority_SMP_Enqueue_lifo( Scheduler_Context *context, - Scheduler_Node *node + Scheduler_Node *node, + Thread_Control *needs_help ) { - _Scheduler_priority_SMP_Enqueue_ordered( + return _Scheduler_priority_SMP_Enqueue_ordered( context, node, + needs_help, _Scheduler_SMP_Insert_priority_lifo_order, _Scheduler_priority_SMP_Insert_ready_lifo, _Scheduler_SMP_Insert_scheduled_lifo ); } -static void _Scheduler_priority_SMP_Enqueue_fifo( +static Thread_Control *_Scheduler_priority_SMP_Enqueue_fifo( Scheduler_Context *context, - Scheduler_Node *node + Scheduler_Node *node, + Thread_Control *needs_help ) { - _Scheduler_priority_SMP_Enqueue_ordered( + return _Scheduler_priority_SMP_Enqueue_ordered( context, node, + needs_help, _Scheduler_SMP_Insert_priority_fifo_order, _Scheduler_priority_SMP_Insert_ready_fifo, _Scheduler_SMP_Insert_scheduled_fifo ); } -static void _Scheduler_priority_SMP_Enqueue_scheduled_ordered( +static Thread_Control *_Scheduler_priority_SMP_Enqueue_scheduled_ordered( Scheduler_Context *context, Scheduler_Node *node, Chain_Node_order order, @@ -153,7 +159,7 @@ static void _Scheduler_priority_SMP_Enqueue_scheduled_ordered( Scheduler_SMP_Insert insert_scheduled ) { - _Scheduler_SMP_Enqueue_scheduled_ordered( + return _Scheduler_SMP_Enqueue_scheduled_ordered( context, node, order, @@ -165,12 +171,12 @@ static void _Scheduler_priority_SMP_Enqueue_scheduled_ordered( ); } -static void _Scheduler_priority_SMP_Enqueue_scheduled_lifo( +static Thread_Control *_Scheduler_priority_SMP_Enqueue_scheduled_lifo( Scheduler_Context *context, Scheduler_Node *node ) { - _Scheduler_priority_SMP_Enqueue_scheduled_ordered( + return _Scheduler_priority_SMP_Enqueue_scheduled_ordered( context, node, _Scheduler_SMP_Insert_priority_lifo_order, @@ -179,12 +185,12 @@ static void _Scheduler_priority_SMP_Enqueue_scheduled_lifo( ); } -static void _Scheduler_priority_SMP_Enqueue_scheduled_fifo( +static Thread_Control *_Scheduler_priority_SMP_Enqueue_scheduled_fifo( Scheduler_Context *context, Scheduler_Node *node ) { - _Scheduler_priority_SMP_Enqueue_scheduled_ordered( + return _Scheduler_priority_SMP_Enqueue_scheduled_ordered( context, node, _Scheduler_SMP_Insert_priority_fifo_order, @@ -193,21 +199,21 @@ static void _Scheduler_priority_SMP_Enqueue_scheduled_fifo( ); } -void _Scheduler_priority_SMP_Unblock( +Thread_Control *_Scheduler_priority_SMP_Unblock( const Scheduler_Control *scheduler, Thread_Control *thread ) { Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - _Scheduler_SMP_Unblock( + return _Scheduler_SMP_Unblock( context, thread, _Scheduler_priority_SMP_Enqueue_fifo ); } -void _Scheduler_priority_SMP_Change_priority( +Thread_Control *_Scheduler_priority_SMP_Change_priority( const Scheduler_Control *scheduler, Thread_Control *thread, Priority_Control new_priority, @@ -216,7 +222,7 @@ void _Scheduler_priority_SMP_Change_priority( { Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - _Scheduler_SMP_Change_priority( + return _Scheduler_SMP_Change_priority( context, thread, new_priority, @@ -230,7 +236,7 @@ void _Scheduler_priority_SMP_Change_priority( ); } -void _Scheduler_priority_SMP_Yield( +Thread_Control *_Scheduler_priority_SMP_Yield( const Scheduler_Control *scheduler, Thread_Control *thread ) diff --git a/cpukit/score/src/schedulerpriorityunblock.c b/cpukit/score/src/schedulerpriorityunblock.c index c1f12f44c6..06d29f3b91 100644 --- a/cpukit/score/src/schedulerpriorityunblock.c +++ b/cpukit/score/src/schedulerpriorityunblock.c @@ -22,7 +22,7 @@ #include -void _Scheduler_priority_Unblock ( +Scheduler_Void_or_thread _Scheduler_priority_Unblock ( const Scheduler_Control *scheduler, Thread_Control *the_thread ) @@ -57,4 +57,6 @@ void _Scheduler_priority_Unblock ( the_thread->current_priority == 0 ) _Thread_Dispatch_necessary = true; } + + SCHEDULER_RETURN_VOID_OR_NULL; } diff --git a/cpukit/score/src/schedulerpriorityyield.c b/cpukit/score/src/schedulerpriorityyield.c index de4b842513..2ee2d03057 100644 --- a/cpukit/score/src/schedulerpriorityyield.c +++ b/cpukit/score/src/schedulerpriorityyield.c @@ -21,7 +21,7 @@ #include #include -void _Scheduler_priority_Yield( +Scheduler_Void_or_thread _Scheduler_priority_Yield( const Scheduler_Control *scheduler, Thread_Control *the_thread ) @@ -43,4 +43,6 @@ void _Scheduler_priority_Yield( } else if ( !_Thread_Is_heir( the_thread ) ) { _Thread_Dispatch_necessary = true; } + + SCHEDULER_RETURN_VOID_OR_NULL; } diff --git a/cpukit/score/src/schedulersimplechangepriority.c b/cpukit/score/src/schedulersimplechangepriority.c index 010f1dfc79..b8638ad28c 100644 --- a/cpukit/score/src/schedulersimplechangepriority.c +++ b/cpukit/score/src/schedulersimplechangepriority.c @@ -21,7 +21,7 @@ #include -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, @@ -38,4 +38,6 @@ void _Scheduler_simple_Change_priority( } else { _Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread ); } + + SCHEDULER_RETURN_VOID_OR_NULL; } diff --git a/cpukit/score/src/schedulersimplesmp.c b/cpukit/score/src/schedulersimplesmp.c index 7361678e53..ee540bebd0 100644 --- a/cpukit/score/src/schedulersimplesmp.c +++ b/cpukit/score/src/schedulersimplesmp.c @@ -179,17 +179,19 @@ void _Scheduler_simple_SMP_Block( ); } -static void _Scheduler_simple_SMP_Enqueue_ordered( - Scheduler_Context *context, - Scheduler_Node *node, - Chain_Node_order order, - Scheduler_SMP_Insert insert_ready, - Scheduler_SMP_Insert insert_scheduled +static Thread_Control *_Scheduler_simple_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 ) { - _Scheduler_SMP_Enqueue_ordered( + return _Scheduler_SMP_Enqueue_ordered( context, node, + needs_help, order, insert_ready, insert_scheduled, @@ -199,35 +201,39 @@ static void _Scheduler_simple_SMP_Enqueue_ordered( ); } -static void _Scheduler_simple_SMP_Enqueue_lifo( +static Thread_Control *_Scheduler_simple_SMP_Enqueue_lifo( Scheduler_Context *context, - Scheduler_Node *node + Scheduler_Node *node, + Thread_Control *needs_help ) { - _Scheduler_simple_SMP_Enqueue_ordered( + return _Scheduler_simple_SMP_Enqueue_ordered( context, node, + needs_help, _Scheduler_SMP_Insert_priority_lifo_order, _Scheduler_simple_SMP_Insert_ready_lifo, _Scheduler_SMP_Insert_scheduled_lifo ); } -static void _Scheduler_simple_SMP_Enqueue_fifo( +static Thread_Control *_Scheduler_simple_SMP_Enqueue_fifo( Scheduler_Context *context, - Scheduler_Node *node + Scheduler_Node *node, + Thread_Control *needs_help ) { - _Scheduler_simple_SMP_Enqueue_ordered( + return _Scheduler_simple_SMP_Enqueue_ordered( context, node, + needs_help, _Scheduler_SMP_Insert_priority_fifo_order, _Scheduler_simple_SMP_Insert_ready_fifo, _Scheduler_SMP_Insert_scheduled_fifo ); } -static void _Scheduler_simple_SMP_Enqueue_scheduled_ordered( +static Thread_Control *_Scheduler_simple_SMP_Enqueue_scheduled_ordered( Scheduler_Context *context, Scheduler_Node *node, Chain_Node_order order, @@ -235,7 +241,7 @@ static void _Scheduler_simple_SMP_Enqueue_scheduled_ordered( Scheduler_SMP_Insert insert_scheduled ) { - _Scheduler_SMP_Enqueue_scheduled_ordered( + return _Scheduler_SMP_Enqueue_scheduled_ordered( context, node, order, @@ -247,12 +253,12 @@ static void _Scheduler_simple_SMP_Enqueue_scheduled_ordered( ); } -static void _Scheduler_simple_SMP_Enqueue_scheduled_lifo( +static Thread_Control *_Scheduler_simple_SMP_Enqueue_scheduled_lifo( Scheduler_Context *context, Scheduler_Node *node ) { - _Scheduler_simple_SMP_Enqueue_scheduled_ordered( + return _Scheduler_simple_SMP_Enqueue_scheduled_ordered( context, node, _Scheduler_SMP_Insert_priority_lifo_order, @@ -261,12 +267,12 @@ static void _Scheduler_simple_SMP_Enqueue_scheduled_lifo( ); } -static void _Scheduler_simple_SMP_Enqueue_scheduled_fifo( +static Thread_Control *_Scheduler_simple_SMP_Enqueue_scheduled_fifo( Scheduler_Context *context, Scheduler_Node *node ) { - _Scheduler_simple_SMP_Enqueue_scheduled_ordered( + return _Scheduler_simple_SMP_Enqueue_scheduled_ordered( context, node, _Scheduler_SMP_Insert_priority_fifo_order, @@ -275,21 +281,21 @@ static void _Scheduler_simple_SMP_Enqueue_scheduled_fifo( ); } -void _Scheduler_simple_SMP_Unblock( +Thread_Control *_Scheduler_simple_SMP_Unblock( const Scheduler_Control *scheduler, Thread_Control *thread ) { Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - _Scheduler_SMP_Unblock( + return _Scheduler_SMP_Unblock( context, thread, _Scheduler_simple_SMP_Enqueue_fifo ); } -void _Scheduler_simple_SMP_Change_priority( +Thread_Control *_Scheduler_simple_SMP_Change_priority( const Scheduler_Control *scheduler, Thread_Control *thread, Priority_Control new_priority, @@ -298,7 +304,7 @@ void _Scheduler_simple_SMP_Change_priority( { Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - _Scheduler_SMP_Change_priority( + return _Scheduler_SMP_Change_priority( context, thread, new_priority, @@ -312,7 +318,7 @@ void _Scheduler_simple_SMP_Change_priority( ); } -void _Scheduler_simple_SMP_Yield( +Thread_Control *_Scheduler_simple_SMP_Yield( const Scheduler_Control *scheduler, Thread_Control *thread ) diff --git a/cpukit/score/src/schedulersimpleunblock.c b/cpukit/score/src/schedulersimpleunblock.c index 4e49bd6697..6f9b2f719f 100644 --- a/cpukit/score/src/schedulersimpleunblock.c +++ b/cpukit/score/src/schedulersimpleunblock.c @@ -21,7 +21,7 @@ #include #include -void _Scheduler_simple_Unblock( +Scheduler_Void_or_thread _Scheduler_simple_Unblock( const Scheduler_Control *scheduler, Thread_Control *the_thread ) @@ -49,4 +49,6 @@ void _Scheduler_simple_Unblock( the_thread->current_priority == 0 ) _Thread_Dispatch_necessary = true; } + + SCHEDULER_RETURN_VOID_OR_NULL; } diff --git a/cpukit/score/src/schedulersimpleyield.c b/cpukit/score/src/schedulersimpleyield.c index b807530600..66e4450477 100644 --- a/cpukit/score/src/schedulersimpleyield.c +++ b/cpukit/score/src/schedulersimpleyield.c @@ -20,7 +20,7 @@ #include -void _Scheduler_simple_Yield( +Scheduler_Void_or_thread _Scheduler_simple_Yield( const Scheduler_Control *scheduler, Thread_Control *the_thread ) @@ -31,4 +31,6 @@ void _Scheduler_simple_Yield( _Chain_Extract_unprotected( &the_thread->Object.Node ); _Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread ); _Scheduler_simple_Schedule_body( scheduler, the_thread, false ); + + SCHEDULER_RETURN_VOID_OR_NULL; } diff --git a/testsuites/smptests/smpscheduler03/init.c b/testsuites/smptests/smpscheduler03/init.c index a66a6878cf..d919482c8a 100644 --- a/testsuites/smptests/smpscheduler03/init.c +++ b/testsuites/smptests/smpscheduler03/init.c @@ -53,7 +53,40 @@ static void task(rtems_task_argument arg) rtems_test_assert(0); } -static void test_case( +static rtems_id start_task(rtems_task_priority prio) +{ + rtems_status_code sc; + rtems_id task_id; + + sc = rtems_task_create( + rtems_build_name('T', 'A', 'S', 'K'), + prio, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &task_id + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_start(task_id, task, 0); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + return task_id; +} + +static Thread_Control *get_thread_by_id(rtems_id task_id) +{ + Objects_Locations location; + Thread_Control *thread; + + thread = _Thread_Get(task_id, &location); + rtems_test_assert(location == OBJECTS_LOCAL); + _Thread_Enable_dispatch(); + + return thread; +} + +static void test_case_change_priority( Thread_Control *executing, Scheduler_SMP_Node *node, Scheduler_SMP_Node_state start_state, @@ -98,18 +131,7 @@ static void test_change_priority(void) size_t j; size_t k; - sc = rtems_task_create( - rtems_build_name('T', 'A', 'S', 'K'), - 3, - RTEMS_MINIMUM_STACK_SIZE, - RTEMS_DEFAULT_MODES, - RTEMS_DEFAULT_ATTRIBUTES, - &task_id - ); - rtems_test_assert(sc == RTEMS_SUCCESSFUL); - - sc = rtems_task_start(task_id, task, 0); - rtems_test_assert(sc == RTEMS_SUCCESSFUL); + task_id = start_task(3); _Thread_Disable_dispatch(); @@ -119,7 +141,7 @@ static void test_change_priority(void) for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) { for (j = 0; j < RTEMS_ARRAY_SIZE(priorities); ++j) { for (k = 0; k < RTEMS_ARRAY_SIZE(prepend_it); ++k) { - test_case( + test_case_change_priority( executing, node, states[i], @@ -140,11 +162,360 @@ static void test_change_priority(void) rtems_test_assert(sc == RTEMS_SUCCESSFUL); } +static Thread_Control *change_priority_op( + Thread_Control *thread, + Priority_Control new_priority, + bool prepend_it +) +{ + const Scheduler_Control *scheduler = _Scheduler_Get(thread); + Thread_Control *needs_help; + ISR_Level level; + + _ISR_Disable( level ); + thread->current_priority = new_priority; + needs_help = (*scheduler->Operations.change_priority)( + scheduler, + thread, + new_priority, + prepend_it + ); + _ISR_Enable( level ); + + return needs_help; +} + +static void test_case_change_priority_op( + Thread_Control *executing, + Scheduler_SMP_Node *executing_node, + Thread_Control *other, + Scheduler_SMP_Node_state start_state, + Priority_Control prio, + bool prepend_it, + Scheduler_SMP_Node_state new_state +) +{ + Thread_Control *needs_help; + + switch (start_state) { + case SCHEDULER_SMP_NODE_SCHEDULED: + _Thread_Change_priority(executing, 1, true); + break; + case SCHEDULER_SMP_NODE_READY: + _Thread_Change_priority(executing, 4, true); + break; + default: + rtems_test_assert(0); + break; + } + rtems_test_assert(executing_node->state == start_state); + + needs_help = change_priority_op(executing, prio, prepend_it); + rtems_test_assert(executing_node->state == new_state); + + if (start_state != new_state) { + switch (start_state) { + case SCHEDULER_SMP_NODE_SCHEDULED: + rtems_test_assert(needs_help == executing); + break; + case SCHEDULER_SMP_NODE_READY: + rtems_test_assert(needs_help == other); + break; + default: + rtems_test_assert(0); + break; + } + } else { + rtems_test_assert(needs_help == NULL); + } +} + +static void test_change_priority_op(void) +{ + rtems_status_code sc; + rtems_id task_id; + Thread_Control *executing; + Scheduler_SMP_Node *executing_node; + Thread_Control *other; + size_t i; + size_t j; + size_t k; + + task_id = start_task(3); + + _Thread_Disable_dispatch(); + + executing = _Thread_Executing; + executing_node = _Scheduler_SMP_Thread_get_node(executing); + + other = get_thread_by_id(task_id); + + for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) { + for (j = 0; j < RTEMS_ARRAY_SIZE(priorities); ++j) { + for (k = 0; k < RTEMS_ARRAY_SIZE(prepend_it); ++k) { + test_case_change_priority_op( + executing, + executing_node, + other, + states[i], + priorities[j], + prepend_it[k], + states[j] + ); + } + } + } + + _Thread_Change_priority(executing, 1, true); + rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED); + + _Thread_Enable_dispatch(); + + sc = rtems_task_delete(task_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); +} + +static Thread_Control *yield_op(Thread_Control *thread) +{ + const Scheduler_Control *scheduler = _Scheduler_Get(thread); + Thread_Control *needs_help; + ISR_Level level; + + _ISR_Disable( level ); + needs_help = (*scheduler->Operations.yield)(scheduler, thread); + _ISR_Enable( level ); + + return needs_help; +} + +static void test_case_yield_op( + Thread_Control *executing, + Scheduler_SMP_Node *executing_node, + Thread_Control *other, + Scheduler_SMP_Node_state start_state, + Scheduler_SMP_Node_state new_state +) +{ + Thread_Control *needs_help; + + _Thread_Change_priority(executing, 4, false); + _Thread_Change_priority(other, 4, false); + + switch (start_state) { + case SCHEDULER_SMP_NODE_SCHEDULED: + switch (new_state) { + case SCHEDULER_SMP_NODE_SCHEDULED: + _Thread_Change_priority(executing, 2, false); + _Thread_Change_priority(other, 3, false); + break; + case SCHEDULER_SMP_NODE_READY: + _Thread_Change_priority(executing, 2, false); + _Thread_Change_priority(other, 2, false); + break; + default: + rtems_test_assert(0); + break; + } + break; + case SCHEDULER_SMP_NODE_READY: + switch (new_state) { + case SCHEDULER_SMP_NODE_SCHEDULED: + rtems_test_assert(0); + break; + case SCHEDULER_SMP_NODE_READY: + _Thread_Change_priority(executing, 3, false); + _Thread_Change_priority(other, 2, false); + break; + default: + rtems_test_assert(0); + break; + } + break; + default: + rtems_test_assert(0); + break; + } + rtems_test_assert(executing_node->state == start_state); + + needs_help = yield_op(executing); + rtems_test_assert(executing_node->state == new_state); + + if (start_state != new_state) { + switch (start_state) { + case SCHEDULER_SMP_NODE_SCHEDULED: + rtems_test_assert(needs_help == executing); + break; + case SCHEDULER_SMP_NODE_READY: + rtems_test_assert(needs_help == other); + break; + default: + rtems_test_assert(0); + break; + } + } else { + rtems_test_assert(needs_help == NULL); + } +} + +static void test_yield_op(void) +{ + rtems_status_code sc; + rtems_id task_id; + Thread_Control *executing; + Scheduler_SMP_Node *executing_node; + Thread_Control *other; + size_t i; + size_t j; + + task_id = start_task(2); + + _Thread_Disable_dispatch(); + + executing = _Thread_Executing; + executing_node = _Scheduler_SMP_Thread_get_node(executing); + + other = get_thread_by_id(task_id); + + for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) { + for (j = 0; j < RTEMS_ARRAY_SIZE(states); ++j) { + if ( + states[i] != SCHEDULER_SMP_NODE_READY + || states[j] != SCHEDULER_SMP_NODE_SCHEDULED + ) { + test_case_yield_op( + executing, + executing_node, + other, + states[i], + states[j] + ); + } + } + } + + _Thread_Change_priority(executing, 1, true); + rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED); + + _Thread_Enable_dispatch(); + + sc = rtems_task_delete(task_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); +} + +static void block_op(Thread_Control *thread) +{ + const Scheduler_Control *scheduler = _Scheduler_Get(thread); + ISR_Level level; + + _ISR_Disable( level ); + (*scheduler->Operations.block)(scheduler, thread); + _ISR_Enable( level ); +} + +static Thread_Control *unblock_op(Thread_Control *thread) +{ + const Scheduler_Control *scheduler = _Scheduler_Get(thread); + Thread_Control *needs_help; + ISR_Level level; + + _ISR_Disable( level ); + needs_help = (*scheduler->Operations.unblock)(scheduler, thread); + _ISR_Enable( level ); + + return needs_help; +} + +static void test_case_unblock_op( + Thread_Control *executing, + Scheduler_SMP_Node *executing_node, + Thread_Control *other, + Scheduler_SMP_Node_state new_state +) +{ + Thread_Control *needs_help; + + switch (new_state) { + case SCHEDULER_SMP_NODE_SCHEDULED: + _Thread_Change_priority(executing, 2, false); + rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED); + break; + case SCHEDULER_SMP_NODE_READY: + _Thread_Change_priority(executing, 4, false); + rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_READY); + break; + default: + rtems_test_assert(0); + break; + } + + block_op(executing); + rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_BLOCKED); + + needs_help = unblock_op(executing); + rtems_test_assert(executing_node->state == new_state); + + switch (new_state) { + case SCHEDULER_SMP_NODE_SCHEDULED: + rtems_test_assert(needs_help == other); + break; + case SCHEDULER_SMP_NODE_READY: + rtems_test_assert(needs_help == executing); + break; + default: + rtems_test_assert(0); + break; + } +} + +static void test_unblock_op(void) +{ + rtems_status_code sc; + rtems_id task_id; + Thread_Control *executing; + Scheduler_SMP_Node *executing_node; + Thread_Control *other; + size_t i; + + task_id = start_task(3); + + _Thread_Disable_dispatch(); + + executing = _Thread_Executing; + executing_node = _Scheduler_SMP_Thread_get_node(executing); + + other = get_thread_by_id(task_id); + + for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) { + test_case_unblock_op( + executing, + executing_node, + other, + states[i] + ); + } + + _Thread_Change_priority(executing, 1, true); + rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED); + + _Thread_Enable_dispatch(); + + sc = rtems_task_delete(task_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); +} + +static void tests(void) +{ + test_change_priority(); + test_change_priority_op(); + test_yield_op(); + test_unblock_op(); +} + static void test_task(rtems_task_argument arg) { test_context *ctx = &test_instance; - test_change_priority(); + tests(); ctx->cpu_index[arg] = rtems_get_current_processor(); @@ -202,7 +573,7 @@ static void Init(rtems_task_argument arg) rtems_test_assert(sc == RTEMS_SUCCESSFUL); } - test_change_priority(); + tests(); barrier_wait(ctx); -- cgit v1.2.3