Manage the help state of threads with respect to scheduling decisions. --- cpukit/score/include/rtems/score/mrspimpl.h | 27 +++++++++------ cpukit/score/include/rtems/score/scheduler.h | 40 ++++++++++++++++++++++ cpukit/score/include/rtems/score/schedulerimpl.h | 30 ++++++++++++++++ cpukit/score/include/rtems/score/threadimpl.h | 10 +++++ 4 files changed, 96 insertions(+), 11 deletions(-)
diff --git a/cpukit/score/include/rtems/score/mrspimpl.h b/cpukit/score/include/rtems/score/mrspimpl.h index 2369d9d..1f33d25 100644 --- a/cpukit/score/include/rtems/score/mrspimpl.h +++ b/cpukit/score/include/rtems/score/mrspimpl.h @@ -193,6 +193,11 @@ RTEMS_INLINE_ROUTINE MRSP_Status _MRSP_Wait_for_ownership( _Chain_Append_unprotected( &mrsp->Rivals, &rival.Node ); _Resource_Add_rival( &mrsp->Resource, &executing->Resource_node ); _Resource_Node_set_dependency( &executing->Resource_node, &mrsp->Resource ); + _Scheduler_Help( + executing, + _Thread_Resource_node_to_thread( owner ), + SCHEDULER_HELP_ACTIVE + ); _MRSP_Set_root( &executing->Resource_node, owner ); if ( timeout > 0 ) { @@ -231,11 +236,10 @@ RTEMS_INLINE_ROUTINE MRSP_Status _MRSP_Wait_for_ownership( mrsp->initial_priority_of_owner = initial_priority; status = MRSP_SUCCESSFUL; } else { - Resource_Node *executing_node = &executing->Resource_node; - - _Resource_Node_extract( executing_node ); - _Resource_Node_set_dependency( executing_node, NULL ); - _MRSP_Set_root( executing_node, executing_node ); + _Resource_Node_extract( &executing->Resource_node ); + _Resource_Node_set_dependency( &executing->Resource_node, NULL ); + _Scheduler_Help( executing, executing, SCHEDULER_HELP_YOURSELF ); + _MRSP_Set_root( &executing->Resource_node, &executing->Resource_node ); _MRSP_Restore_priority( mrsp, executing, initial_priority ); status = MRSP_TIMEOUT; @@ -321,13 +325,14 @@ RTEMS_INLINE_ROUTINE MRSP_Status _MRSP_Release( _Resource_Set_owner( &mrsp->Resource, NULL ); } else { MRSP_Rival *rival = (MRSP_Rival *) _Chain_First( &mrsp->Rivals ); - Resource_Node *new_owner = &rival->thread->Resource_node; + Thread_Control *new_owner = rival->thread; - _Resource_Node_extract( new_owner ); - _Resource_Node_set_dependency( new_owner, NULL ); - _Resource_Node_add_resource( new_owner, &mrsp->Resource ); - _Resource_Set_owner( &mrsp->Resource, new_owner ); - _MRSP_Set_root( new_owner, new_owner ); + _Resource_Node_extract( &new_owner->Resource_node ); + _Resource_Node_set_dependency( &new_owner->Resource_node, NULL ); + _Resource_Node_add_resource( &new_owner->Resource_node, &mrsp->Resource ); + _Resource_Set_owner( &mrsp->Resource, &new_owner->Resource_node ); + _Scheduler_Help( new_owner, new_owner, SCHEDULER_HELP_YOURSELF ); + _MRSP_Set_root( &new_owner->Resource_node, &new_owner->Resource_node ); _MRSP_Add_state( rival, MRSP_RIVAL_STATE_NEW_OWNER ); } diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h index 918c6df..d9d21d3 100644 --- a/cpukit/score/include/rtems/score/scheduler.h +++ b/cpukit/score/include/rtems/score/scheduler.h @@ -161,6 +161,36 @@ struct Scheduler_Control { uint32_t name; }; +#if defined(RTEMS_SMP) +/** + * @brief State to indicate potential help for other threads. + */ +typedef enum { + /** + * @brief This scheduler node is solely used by the owner. + * + * No help will be provided for other threads. + */ + SCHEDULER_HELP_YOURSELF, + + /** + * @brief This scheduler node can be used to help out threads. + * + * The owner thread is ready, but it will give away its processor in case + * there is a thread seeking for help. + */ + SCHEDULER_HELP_ACTIVE, + + /** + * @brief This scheduler node can be used to help out threads. + * + * The owner thread is blocked. This scheduler node can be used by a thread + * seeking for help. + */ + SCHEDULER_HELP_PASSIVE +} Scheduler_Help_state; +#endif + /** * @brief Scheduler node for per-thread data. */ @@ -182,6 +212,16 @@ struct Scheduler_Node { * @brief The thread owning this node. */ Thread_Control *owner; + + /** + * @brief The thread using this node. + */ + Thread_Control *user; + + /** + * @brief The help state of this node. + */ + Scheduler_Help_state help_state; #endif }; diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h index 391a8d7..f3284eb 100644 --- a/cpukit/score/include/rtems/score/schedulerimpl.h +++ b/cpukit/score/include/rtems/score/schedulerimpl.h @@ -659,6 +659,8 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Node_do_initialize( { #if defined(RTEMS_SMP) node->owner = the_thread; + node->help_state = SCHEDULER_HELP_YOURSELF; + node->user = the_thread; #else (void) node; (void) the_thread; @@ -672,6 +674,34 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_owner( { return node->owner; } + +RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_user( + const Scheduler_Node *node +) +{ + return node->user; +} + +/** + * @brief Helps a thread with respect to scheduling decisions. + * + * @param[in] helper The thread providing help. + * @param[in] needs_help The thread needing help. It may be equal the thread + * providing help in case the help state is SCHEDULER_HELP_YOURSELF. + * @param[in] help_state The new help state. + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Help( + Thread_Control *helper, + Thread_Control *needs_help, + Scheduler_Help_state help_state +) +{ + Scheduler_Node *node = _Scheduler_Node_get( helper ); + + node->help_state = help_state; + + (void) needs_help; +} #endif /** @} */ diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h index af24a3a..8ac831a 100644 --- a/cpukit/score/include/rtems/score/threadimpl.h +++ b/cpukit/score/include/rtems/score/threadimpl.h @@ -798,6 +798,16 @@ RTEMS_INLINE_ROUTINE bool _Thread_Owns_resources( return owns_resources; } +#if defined(RTEMS_SMP) +RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Resource_node_to_thread( + Resource_Node *node +) +{ + return (Thread_Control *) + ( (char *) node - offsetof( Thread_Control, Resource_node ) ); +} +#endif + RTEMS_INLINE_ROUTINE void _Thread_Debug_set_real_processor( Thread_Control *the_thread, Per_CPU_Control *cpu -- 1.7.7 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel