diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-09-09 11:00:06 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-09-21 08:59:33 +0200 |
commit | f6142c19f192e40ee1aa9ff67eb1c711343c157d (patch) | |
tree | 061086bf693d934063cdd601498e0e138e72eeb7 /cpukit/score/include | |
parent | rtems: Add rtems_task_get_priority() (diff) | |
download | rtems-f6142c19f192e40ee1aa9ff67eb1c711343c157d.tar.bz2 |
score: Scheduler node awareness for thread queues
Maintain the priority of a thread for each scheduler instance via the
thread queue enqueue, extract, priority actions and surrender
operations. This replaces the primitive priority boosting.
Update #2556.
Diffstat (limited to 'cpukit/score/include')
-rw-r--r-- | cpukit/score/include/rtems/score/schedulernode.h | 5 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/threadimpl.h | 45 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/threadq.h | 11 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/threadqimpl.h | 6 |
4 files changed, 51 insertions, 16 deletions
diff --git a/cpukit/score/include/rtems/score/schedulernode.h b/cpukit/score/include/rtems/score/schedulernode.h index 8d00a43d31..2397ba4b79 100644 --- a/cpukit/score/include/rtems/score/schedulernode.h +++ b/cpukit/score/include/rtems/score/schedulernode.h @@ -209,6 +209,11 @@ typedef struct Scheduler_Node { extern const size_t _Scheduler_Node_size; #endif +#if defined(RTEMS_SMP) +#define SCHEDULER_NODE_OF_THREAD_WAIT_NODE( node ) \ + RTEMS_CONTAINER_OF( node, Scheduler_Node, Thread.Wait_node ) +#endif + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h index 09af9c15dd..7b978ea477 100644 --- a/cpukit/score/include/rtems/score/threadimpl.h +++ b/cpukit/score/include/rtems/score/threadimpl.h @@ -997,6 +997,20 @@ RTEMS_INLINE_ROUTINE Scheduler_Node *_Thread_Scheduler_get_own_node( #endif } +RTEMS_INLINE_ROUTINE Scheduler_Node *_Thread_Scheduler_get_home_node( + const Thread_Control *the_thread +) +{ +#if defined(RTEMS_SMP) + _Assert( !_Chain_Is_empty( &the_thread->Scheduler.Wait_nodes ) ); + return SCHEDULER_NODE_OF_THREAD_WAIT_NODE( + _Chain_First( &the_thread->Scheduler.Wait_nodes ) + ); +#else + return the_thread->Scheduler.nodes; +#endif +} + RTEMS_INLINE_ROUTINE Scheduler_Node *_Thread_Scheduler_get_node_by_index( const Thread_Control *the_thread, size_t scheduler_index @@ -1308,21 +1322,22 @@ RTEMS_INLINE_ROUTINE void _Thread_Wait_release( } /** - * @brief Claims the thread wait queue and operations. + * @brief Claims the thread wait queue. * * The caller must not be the owner of the default thread wait lock. The - * caller must be the owner of the corresponding thread queue lock. + * caller must be the owner of the corresponding thread queue lock. The + * registration of the corresponding thread queue operations is deferred and + * done after the deadlock detection. This is crucial to support timeouts on + * SMP configurations. * * @param[in] the_thread The thread. * @param[in] queue The new thread queue. - * @param[in] operations The new thread operations. * - * @see _Thread_Wait_restore_default(). + * @see _Thread_Wait_claim_finalize() and _Thread_Wait_restore_default(). */ RTEMS_INLINE_ROUTINE void _Thread_Wait_claim( - Thread_Control *the_thread, - Thread_queue_Queue *queue, - const Thread_queue_Operations *operations + Thread_Control *the_thread, + Thread_queue_Queue *queue ) { ISR_lock_Context lock_context; @@ -1338,12 +1353,26 @@ RTEMS_INLINE_ROUTINE void _Thread_Wait_claim( #endif the_thread->Wait.queue = queue; - the_thread->Wait.operations = operations; _Thread_Wait_release_default_critical( the_thread, &lock_context ); } /** + * @brief Finalizes the thread wait queue claim via registration of the + * corresponding thread queue operations. + * + * @param[in] the_thread The thread. + * @param[in] operations The corresponding thread queue operations. + */ +RTEMS_INLINE_ROUTINE void _Thread_Wait_claim_finalize( + Thread_Control *the_thread, + const Thread_queue_Operations *operations +) +{ + the_thread->Wait.operations = operations; +} + +/** * @brief Removes a thread wait lock request. * * On SMP configurations, removes a thread wait lock request. diff --git a/cpukit/score/include/rtems/score/threadq.h b/cpukit/score/include/rtems/score/threadq.h index 6f62506c26..084161cc4d 100644 --- a/cpukit/score/include/rtems/score/threadq.h +++ b/cpukit/score/include/rtems/score/threadq.h @@ -216,6 +216,12 @@ typedef struct { * @brief The start of a thread queue path. */ Thread_queue_Link Start; + + /** + * @brief In case of a deadlock, a link for the first thread on the path + * that tries to enqueue on a thread queue. + */ + Thread_queue_Link Deadlock; } Path; #endif @@ -345,11 +351,6 @@ typedef struct _Thread_queue_Heads { #if defined(RTEMS_SMP) /** - * @brief Boost priority. - */ - Priority_Node Boost_priority; - - /** * @brief One priority queue per scheduler instance. */ Thread_queue_Priority_queue Priority[ RTEMS_ZERO_LENGTH_ARRAY ]; diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h index 65b0e8eeab..e24beec1bb 100644 --- a/cpukit/score/include/rtems/score/threadqimpl.h +++ b/cpukit/score/include/rtems/score/threadqimpl.h @@ -280,12 +280,10 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Heads_initialize( #if defined(RTEMS_SMP) size_t i; - _Priority_Node_initialize( &heads->Boost_priority, 0 ); - _Priority_Node_set_inactive( &heads->Boost_priority ); - for ( i = 0; i < _Scheduler_Count; ++i ) { _Chain_Initialize_node( &heads->Priority[ i ].Node ); _Priority_Initialize_empty( &heads->Priority[ i ].Queue ); + heads->Priority[ i ].Queue.scheduler = &_Scheduler_Table[ i ]; } #endif @@ -955,6 +953,7 @@ void _Thread_queue_Unblock_proxy( ); #endif +#if defined(RTEMS_SMP) bool _Thread_queue_Path_acquire_critical( Thread_queue_Queue *queue, Thread_Control *the_thread, @@ -964,6 +963,7 @@ bool _Thread_queue_Path_acquire_critical( void _Thread_queue_Path_release_critical( Thread_queue_Context *queue_context ); +#endif /** * @brief Helper structure to ensure that all objects containing a thread queue |