diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-06-22 17:09:23 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-09-21 08:59:26 +0200 |
commit | 300f6a481aaf9e6d29811faca71bf7104a01492c (patch) | |
tree | ba8f18cedb93e3781a2f17aa989c5c805dd18d6a /cpukit/score/include/rtems/score/threadimpl.h | |
parent | classic networking: do not reference BSP_irq_enabled_at_i8259s which is no mo... (diff) | |
download | rtems-300f6a481aaf9e6d29811faca71bf7104a01492c.tar.bz2 |
score: Rework thread priority management
Add priority nodes which contribute to the overall thread priority.
The actual priority of a thread is now an aggregation of priority nodes.
The thread priority aggregation for the home scheduler instance of a
thread consists of at least one priority node, which is normally the
real priority of the thread. The locking protocols (e.g. priority
ceiling and priority inheritance), rate-monotonic period objects and the
POSIX sporadic server add, change and remove priority nodes.
A thread changes its priority now immediately, e.g. priority changes are
not deferred until the thread releases its last resource.
Replace the _Thread_Change_priority() function with
* _Thread_Priority_perform_actions(),
* _Thread_Priority_add(),
* _Thread_Priority_remove(),
* _Thread_Priority_change(), and
* _Thread_Priority_update().
Update #2412.
Update #2556.
Diffstat (limited to '')
-rw-r--r-- | cpukit/score/include/rtems/score/threadimpl.h | 261 |
1 files changed, 167 insertions, 94 deletions
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h index 1fce842533..7f9dccf5e2 100644 --- a/cpukit/score/include/rtems/score/threadimpl.h +++ b/cpukit/score/include/rtems/score/threadimpl.h @@ -415,128 +415,185 @@ RTEMS_INLINE_ROUTINE bool _Thread_State_is_owner( #endif /** - * @brief Returns true if the left thread priority is less than the right - * thread priority in the intuitive sense of priority and false otherwise. + * @brief Performs the priority actions specified by the thread queue context + * along the thread queue path. + * + * The caller must be the owner of the thread wait lock. + * + * @param start_of_path The start thread of the thread queue path. + * @param queue_context The thread queue context specifying the thread queue + * path and initial thread priority actions. + * + * @see _Thread_queue_Path_acquire_critical(). */ -RTEMS_INLINE_ROUTINE bool _Thread_Priority_less_than( - Priority_Control left, - Priority_Control right -) -{ - return left > right; -} +void _Thread_Priority_perform_actions( + Thread_Control *start_of_path, + Thread_queue_Context *queue_context +); /** - * @brief Returns the highest priority of the left and right thread priorities - * in the intuitive sense of priority. + * @brief Adds the specified thread priority node to the corresponding thread + * priority aggregation. + * + * The caller must be the owner of the thread wait lock. + * + * @param the_thread The thread. + * @param priority_node The thread priority node to add. + * @param queue_context The thread queue context to return an updated set of + * threads for _Thread_Priority_update(). The thread queue context must be + * initialized via _Thread_queue_Context_clear_priority_updates() before a + * call of this function. + * + * @see _Thread_Wait_acquire(). */ -RTEMS_INLINE_ROUTINE Priority_Control _Thread_Priority_highest( - Priority_Control left, - Priority_Control right -) -{ - return _Thread_Priority_less_than( left, right ) ? right : left; -} +void _Thread_Priority_add( + Thread_Control *the_thread, + Priority_Node *priority_node, + Thread_queue_Context *queue_context +); /** - * @brief Filters a thread priority change. + * @brief Removes the specified thread priority node from the corresponding + * thread priority aggregation. * - * Called by _Thread_Change_priority() under the protection of the thread lock. + * The caller must be the owner of the thread wait lock. * - * @param[in] the_thread The thread. - * @param[in, out] new_priority The new priority of the thread. The filter may - * alter this value. - * @param[in] arg The argument passed to _Thread_Change_priority(). + * @param the_thread The thread. + * @param priority_node The thread priority node to remove. + * @param queue_context The thread queue context to return an updated set of + * threads for _Thread_Priority_update(). The thread queue context must be + * initialized via _Thread_queue_Context_clear_priority_updates() before a + * call of this function. * - * @retval true Change the current priority. - * @retval false Otherwise. + * @see _Thread_Wait_acquire(). */ -typedef bool ( *Thread_Change_priority_filter )( - Thread_Control *the_thread, - Priority_Control *new_priority, - void *arg -); - -Thread_Control *_Thread_Apply_priority( - Thread_Control *the_thread, - Priority_Control new_priority, - void *arg, - Thread_Change_priority_filter filter, - bool prepend_it +void _Thread_Priority_remove( + Thread_Control *the_thread, + Priority_Node *priority_node, + Thread_queue_Context *queue_context ); -void _Thread_Update_priority( Thread_Control *the_thread ); - /** - * @brief Changes the priority of a thread if allowed by the filter function. + * @brief Propagates a thread priority value change in the specified thread + * priority node to the corresponding thread priority aggregation. * - * It changes current priority of the thread to the new priority in case the - * filter function returns true. In this case the scheduler is notified of the - * priority change as well. + * The caller must be the owner of the thread wait lock. * - * @param[in] the_thread The thread. - * @param[in] new_priority The new priority of the thread. - * @param[in] arg The argument for the filter function. - * @param[in] filter The filter function to determine if a priority change is - * allowed and optionally perform other actions under the protection of the - * thread lock simultaneously with the update of the current priority. - * @param[in] prepend_it In case this is true, then the thread is prepended to - * its priority group in its scheduler instance, otherwise it is appended. - */ -void _Thread_Change_priority( - Thread_Control *the_thread, - Priority_Control new_priority, - void *arg, - Thread_Change_priority_filter filter, - bool prepend_it + * @param the_thread The thread. + * @param priority_node The thread priority node to change. + * @param prepend_it In case this is true, then the thread is prepended to + * its priority group in its home scheduler instance, otherwise it is + * appended. + * @param queue_context The thread queue context to return an updated set of + * threads for _Thread_Priority_update(). The thread queue context must be + * initialized via _Thread_queue_Context_clear_priority_updates() before a + * call of this function. + * + * @see _Thread_Wait_acquire(). + */ +void _Thread_Priority_changed( + Thread_Control *the_thread, + Priority_Node *priority_node, + bool prepend_it, + Thread_queue_Context *queue_context ); /** - * @brief Raises the priority of a thread. + * @brief Changes the thread priority value of the specified thread priority + * node in the corresponding thread priority aggregation. * - * It changes the current priority of the thread to the new priority if the new - * priority is higher than the current priority. In this case the thread is - * appended to its new priority group in its scheduler instance. + * The caller must be the owner of the thread wait lock. * - * @param[in] the_thread The thread. - * @param[in] new_priority The new priority of the thread. + * @param the_thread The thread. + * @param priority_node The thread priority node to change. + * @param new_priority The new thread priority value of the thread priority + * node to change. + * @param prepend_it In case this is true, then the thread is prepended to + * its priority group in its home scheduler instance, otherwise it is + * appended. + * @param queue_context The thread queue context to return an updated set of + * threads for _Thread_Priority_update(). The thread queue context must be + * initialized via _Thread_queue_Context_clear_priority_updates() before a + * call of this function. * - * @see _Thread_Change_priority(). + * @see _Thread_Wait_acquire(). */ -void _Thread_Raise_priority( - Thread_Control *the_thread, - Priority_Control new_priority -); +RTEMS_INLINE_ROUTINE void _Thread_Priority_change( + Thread_Control *the_thread, + Priority_Node *priority_node, + Priority_Control new_priority, + bool prepend_it, + Thread_queue_Context *queue_context +) +{ + _Priority_Node_set_priority( priority_node, new_priority ); + _Thread_Priority_changed( + the_thread, + priority_node, + prepend_it, + queue_context + ); +} /** - * @brief Sets the current to the real priority of a thread. + * @brief Replaces the victim priority node with the replacement priority node + * in the corresponding thread priority aggregation. + * + * The caller must be the owner of the thread wait lock. * - * Sets the priority restore hint to false. + * @param the_thread The thread. + * @param victim_node The victim thread priority node. + * @param replacement_node The replacement thread priority node. + * + * @see _Thread_Wait_acquire(). */ -void _Thread_Restore_priority( Thread_Control *the_thread ); +void _Thread_Priority_replace( + Thread_Control *the_thread, + Priority_Node *victim_node, + Priority_Node *replacement_node +); /** - * @brief Sets the priority of a thread. + * @brief Adds a priority node to the corresponding thread priority + * aggregation. * - * It sets the real priority of the thread. In addition it changes the current - * priority of the thread if the new priority is higher than the current - * priority or the thread owns no resources. + * The caller must be the owner of the thread wait lock. * - * @param[in] the_thread The thread. - * @param[in] new_priority The new priority of the thread. - * @param[out] old_priority The old real priority of the thread. This pointer - * must not be @c NULL. - * @param[in] prepend_it In case this is true, then the thread is prepended to - * its priority group in its scheduler instance, otherwise it is appended. + * @param the_thread The thread. + * @param priority_node The thread priority node to add. + * @param queue_context The thread queue context to return an updated set of + * threads for _Thread_Priority_update(). The thread queue context must be + * initialized via _Thread_queue_Context_clear_priority_updates() before a + * call of this function. * - * @see _Thread_Change_priority(). + * @see _Thread_Priority_add(), _Thread_Priority_change(), + * _Thread_Priority_changed() and _Thread_Priority_remove(). */ -void _Thread_Set_priority( - Thread_Control *the_thread, - Priority_Control new_priority, - Priority_Control *old_priority, - bool prepend_it -); +void _Thread_Priority_update( Thread_queue_Context *queue_context ); + +/** + * @brief Returns true if the left thread priority is less than the right + * thread priority in the intuitive sense of priority and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Thread_Priority_less_than( + Priority_Control left, + Priority_Control right +) +{ + return left > right; +} + +/** + * @brief Returns the highest priority of the left and right thread priorities + * in the intuitive sense of priority. + */ +RTEMS_INLINE_ROUTINE Priority_Control _Thread_Priority_highest( + Priority_Control left, + Priority_Control right +) +{ + return _Thread_Priority_less_than( left, right ) ? right : left; +} RTEMS_INLINE_ROUTINE Objects_Information *_Thread_Get_objects_information( Objects_Id id @@ -929,6 +986,17 @@ RTEMS_INLINE_ROUTINE bool _Thread_Owns_resources( return owns_resources; } +RTEMS_INLINE_ROUTINE Scheduler_Node *_Thread_Scheduler_get_own_node( + const Thread_Control *the_thread +) +{ +#if defined(RTEMS_SMP) + return the_thread->Scheduler.own_node; +#else + return the_thread->Scheduler.node; +#endif +} + /** * @brief Returns the priority of the thread. * @@ -937,14 +1005,15 @@ RTEMS_INLINE_ROUTINE bool _Thread_Owns_resources( * protocols, a job release or the POSIX sporadic server for example. * * @return The priority of the thread. - * - * @see _Scheduler_Node_get_priority(). */ RTEMS_INLINE_ROUTINE Priority_Control _Thread_Get_priority( const Thread_Control *the_thread ) { - return the_thread->current_priority; + Scheduler_Node *scheduler_node; + + scheduler_node = _Thread_Scheduler_get_own_node( the_thread ); + return _Priority_Get_priority( &scheduler_node->Wait.Priority ); } /** @@ -1389,7 +1458,11 @@ RTEMS_INLINE_ROUTINE void _Thread_Wait_cancel( _Assert( queue_context->Lock_context.Wait.queue == queue ); #endif - ( *the_thread->Wait.operations->extract )( queue, the_thread ); + ( *the_thread->Wait.operations->extract )( + queue, + the_thread, + queue_context + ); _Thread_Wait_restore_default( the_thread ); #if defined(RTEMS_SMP) |