From 300f6a481aaf9e6d29811faca71bf7104a01492c Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 22 Jun 2016 17:09:23 +0200 Subject: 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. --- cpukit/score/include/rtems/score/priority.h | 175 ++++++++++++++++++++++------ 1 file changed, 142 insertions(+), 33 deletions(-) (limited to 'cpukit/score/include/rtems/score/priority.h') diff --git a/cpukit/score/include/rtems/score/priority.h b/cpukit/score/include/rtems/score/priority.h index 842f01706c..595aa3ebcf 100644 --- a/cpukit/score/include/rtems/score/priority.h +++ b/cpukit/score/include/rtems/score/priority.h @@ -1,17 +1,15 @@ /** - * @file rtems/score/priority.h + * @file * - * @brief Thread Priority Manipulation Routines - * - * This include file contains all thread priority manipulation routines. - * This Handler provides mechanisms which can be used to - * initialize and manipulate thread priorities. + * @brief Priority Handler API */ /* * COPYRIGHT (c) 1989-2011. * On-Line Applications Research Corporation (OAR). * + * Copyright (c) 2016 embedded brains GmbH. + * * 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. @@ -20,58 +18,169 @@ #ifndef _RTEMS_SCORE_PRIORITY_H #define _RTEMS_SCORE_PRIORITY_H -/** - * @defgroup ScorePriority Priority Handler - * - * @ingroup Score - * - * This handler encapsulates functionality which is used to manage - * thread priorities. At the SuperCore level 256 priority levels - * are supported with lower numbers representing logically more important - * threads. The priority level 0 is reserved for internal RTEMS use. - * Typically it is assigned to threads which defer internal RTEMS - * actions from an interrupt to thread level to improve interrupt response. - * Priority level 255 is assigned to the IDLE thread and really should not - * be used by application threads. The default IDLE thread implementation - * is an infinite "branch to self" loop which never yields to other threads - * at the same priority. - */ -/**@{*/ - -/* - * Processor specific information. - */ +#include #include +#include + +struct Scheduler_Control; #ifdef __cplusplus extern "C" { #endif /** - * The following type defines the control block used to manage - * thread priorities. + * @defgroup ScorePriority Priority Handler + * + * @ingroup Score + * + * This handler encapsulates functionality which is used to manage thread + * priorities. The actual priority of a thread is 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. + * + * @{ + */ + +/** + * @brief A plain thread priority value. * - * @note Priority 0 is reserved for internal threads only. + * Lower values represent higher priorities. So, a priority value of zero + * represents the highest priority thread. This value is reserved for internal + * threads and the priority ceiling protocol. */ typedef uint64_t Priority_Control; -/** This defines the highest (most important) thread priority. */ +/** + * @brief The highest (most important) thread priority value. + */ #define PRIORITY_MINIMUM 0 /** - * @brief This defines the priority of pseudo-ISR threads. + * @brief The priority value of pseudo-ISR threads. * * Examples are the MPCI and timer server threads. */ #define PRIORITY_PSEUDO_ISR PRIORITY_MINIMUM -/** This defines the default lowest (least important) thread priority. */ +/** + * @brief The default lowest (least important) thread priority value. + * + * This value is CPU port dependent. + */ #if defined (CPU_PRIORITY_MAXIMUM) #define PRIORITY_DEFAULT_MAXIMUM CPU_PRIORITY_MAXIMUM #else #define PRIORITY_DEFAULT_MAXIMUM 255 #endif +/** + * @brief The priority node to build up a priority aggregation. + */ +typedef struct { + /** + * @brief Node component for a chain or red-black tree. + */ + union { + Chain_Node Chain; + RBTree_Node RBTree; + } Node; + + /** + * @brief The priority value of this node. + */ + Priority_Control priority; +} Priority_Node; + +/** + * @brief The priority action type. + */ +typedef enum { + PRIORITY_ACTION_ADD, + PRIORITY_ACTION_CHANGE, + PRIORITY_ACTION_REMOVE, + PRIORITY_ACTION_INVALID +} Priority_Action_type; + +typedef struct Priority_Aggregation Priority_Aggregation; + +/** + * @brief The priority aggregation. + * + * This structure serves two purposes. Firstly, it provides a place to + * register priority nodes and reflects the overall priority of its + * contributors. Secondly, it provides an action block to signal addition, + * change and removal of a priority node. + */ +struct Priority_Aggregation { + /** + * @brief This priority node reflects the overall priority of the aggregation. + * + * The overall priority of the aggregation is the minimum priority of the + * priority nodes in the contributors tree. + * + * This priority node may be used to add this aggregation to another + * aggregation to build up a recursive priority scheme. + * + * In case priority nodes of the contributors tree are added, changed or + * removed the priority of this node may change. To signal such changes to a + * priority aggregation the action block may be used. + */ + Priority_Node Node; + + /** + * @brief A red-black tree to contain priority nodes contributing to the + * overall priority of this priority aggregation. + */ + RBTree_Control Contributors; + +#if defined(RTEMS_SMP) + /** + * @brief The scheduler instance of this priority aggregation. + */ + const struct Scheduler_Control *scheduler; +#endif + + /** + * @brief A priority action block to manage priority node additions, changes + * and removals. + */ + struct { +#if defined(RTEMS_SMP) + /** + * @brief The next priority aggregation in the action list. + */ + Priority_Aggregation *next; +#endif + + /** + * @brief The priority node of the action. + */ + Priority_Node *node; + + /** + * @brief The type of the action. + */ + Priority_Action_type type; + } Action; +}; + +/** + * @brief A list of priority actions. + * + * Actions are only added to the list. The action lists reside on the stack + * and have a short life-time. They are moved, processed or destroyed as a + * whole. + */ +typedef struct { + /** + * @brief The first action of a priority action list. + */ + Priority_Aggregation *actions; +} Priority_Actions; + #ifdef __cplusplus } #endif -- cgit v1.2.3