Update #2556. --- cpukit/score/Makefile.am | 1 + cpukit/score/include/rtems/score/schedulerimpl.h | 9 +++ cpukit/score/include/rtems/score/schedulernode.h | 9 ++- cpukit/score/include/rtems/score/threadimpl.h | 2 + cpukit/score/src/threadscheduler.c | 84 ++++++++++++++++++++++++ 5 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 cpukit/score/src/threadscheduler.c
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index a196ff5..ff6ef7d 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -310,6 +310,7 @@ libscore_a_SOURCES += src/threadentryadaptornumeric.c libscore_a_SOURCES += src/threadentryadaptorpointer.c libscore_a_SOURCES += src/threadgetcputimeused.c libscore_a_SOURCES += src/threadglobalconstruction.c +libscore_a_SOURCES += src/threadscheduler.c libscore_a_SOURCES += src/threadtimeout.c libscore_a_SOURCES += src/threadwaitgetid.c libscore_a_SOURCES += src/threadyield.c diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h index 26da986..e33e8d7 100644 --- a/cpukit/score/include/rtems/score/schedulerimpl.h +++ b/cpukit/score/include/rtems/score/schedulerimpl.h @@ -358,6 +358,10 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Unblock( Thread_Control *the_thread ) Thread_Control *needs_help; #endif +#if defined(RTEMS_SMP) + _Thread_Scheduler_process_requests( the_thread ); +#endif + scheduler = _Scheduler_Get( the_thread ); _Scheduler_Acquire_critical( scheduler, &lock_context ); @@ -399,6 +403,10 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Update_priority( Thread_Control *the_thread Thread_Control *needs_help; #endif +#if defined(RTEMS_SMP) + _Thread_Scheduler_process_requests( the_thread ); +#endif + own_scheduler = _Scheduler_Get_own( the_thread ); _Scheduler_Acquire_critical( own_scheduler, &lock_context ); @@ -1449,6 +1457,7 @@ RTEMS_INLINE_ROUTINE Status_Control _Scheduler_Set( } #if defined(RTEMS_SMP) + _Thread_Scheduler_process_requests( the_thread ); new_scheduler_node = _Thread_Scheduler_get_node_by_index( the_thread, _Scheduler_Get_index( new_scheduler ) diff --git a/cpukit/score/include/rtems/score/schedulernode.h b/cpukit/score/include/rtems/score/schedulernode.h index 2e0c2af..620b029 100644 --- a/cpukit/score/include/rtems/score/schedulernode.h +++ b/cpukit/score/include/rtems/score/schedulernode.h @@ -185,13 +185,20 @@ struct Scheduler_Node { /** * @brief Node to add this scheduler node to - * Thread_Control::Scheduler::Scheduler_nodes. + * Thread_Control::Scheduler::Scheduler_nodes or a temporary remove list. */ union { /** * @brief The node for Thread_Control::Scheduler::Scheduler_nodes. */ Chain_Node Chain; + + /** + * @brief The next pointer for a temporary remove list. + * + * @see _Thread_Scheduler_process_requests(). + */ + Scheduler_Node *next; } Scheduler_node; /** diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h index 6f2037f..14a8fdc 100644 --- a/cpukit/score/include/rtems/score/threadimpl.h +++ b/cpukit/score/include/rtems/score/threadimpl.h @@ -1044,6 +1044,8 @@ RTEMS_INLINE_ROUTINE void _Thread_Scheduler_release_critical( _ISR_lock_Release( &the_thread->Scheduler.Lock, lock_context ); } +void _Thread_Scheduler_process_requests( Thread_Control *the_thread ); + RTEMS_INLINE_ROUTINE void _Thread_Scheduler_add_request( Thread_Control *the_thread, Scheduler_Node *scheduler_node, diff --git a/cpukit/score/src/threadscheduler.c b/cpukit/score/src/threadscheduler.c new file mode 100644 index 0000000..b73598e --- /dev/null +++ b/cpukit/score/src/threadscheduler.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rt...@embedded-brains.de> + * + * 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. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/score/threadimpl.h> +#include <rtems/score/schedulerimpl.h> + +#if defined(RTEMS_SMP) +void _Thread_Scheduler_process_requests( Thread_Control *the_thread ) +{ + ISR_lock_Context lock_context; + Scheduler_Node *scheduler_node; + + _Thread_Scheduler_acquire_critical( the_thread, &lock_context ); + + scheduler_node = the_thread->Scheduler.requests; + + if ( scheduler_node != NULL ) { + Scheduler_Node *next; + Scheduler_Node *remove; + + the_thread->Scheduler.requests = NULL; + remove = NULL; + + do { + Scheduler_Node_request request; + + request = scheduler_node->Thread.request; + scheduler_node->Thread.request = SCHEDULER_NODE_REQUEST_NOT_PENDING; + + next = scheduler_node->Thread.next_request; +#if defined(RTEMS_DEBUG) + scheduler_node->Thread.next_request = NULL; +#endif + + if ( request == SCHEDULER_NODE_REQUEST_ADD ) { + _Chain_Append_unprotected( + &the_thread->Scheduler.Scheduler_nodes, + &scheduler_node->Thread.Scheduler_node.Chain + ); + } else if ( request == SCHEDULER_NODE_REQUEST_REMOVE ) { + _Chain_Extract_unprotected( + &scheduler_node->Thread.Scheduler_node.Chain + ); + scheduler_node->Thread.Scheduler_node.next = remove; + remove = scheduler_node; + } else { + _Assert( request == SCHEDULER_NODE_REQUEST_NOTHING ); + } + + scheduler_node = next; + } while ( scheduler_node != NULL ); + + _Thread_Scheduler_release_critical( the_thread, &lock_context ); + + scheduler_node = remove; + + while ( scheduler_node != NULL ) { + next = scheduler_node->Thread.Scheduler_node.next; +#if defined(RTEMS_DEBUG) + scheduler_node->Thread.Scheduler_node.next = NULL; +#endif + + scheduler_node = next; + } + } else { + _Thread_Scheduler_release_critical( the_thread, &lock_context ); + } +} +#endif -- 1.8.4.5 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel