source: rtems/cpukit/score/include/rtems/score/schedulernode.h @ 300f6a48

5
Last change on this file since 300f6a48 was 300f6a48, checked in by Sebastian Huber <sebastian.huber@…>, on 06/22/16 at 15:09:23

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.

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/*
2 * Copyright (c) 2014, 2016 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#ifndef _RTEMS_SCORE_SCHEDULERNODE_H
16#define _RTEMS_SCORE_SCHEDULERNODE_H
17
18#include <rtems/score/basedefs.h>
19#include <rtems/score/chain.h>
20#include <rtems/score/priority.h>
21#include <rtems/score/smplockseq.h>
22
23struct _Thread_Control;
24
25#ifdef __cplusplus
26extern "C" {
27#endif /* __cplusplus */
28
29#if defined(RTEMS_SMP)
30/**
31 * @brief State to indicate potential help for other threads.
32 *
33 * @dot
34 * digraph state {
35 *   y [label="HELP YOURSELF"];
36 *   ao [label="HELP ACTIVE OWNER"];
37 *   ar [label="HELP ACTIVE RIVAL"];
38 *
39 *   y -> ao [label="obtain"];
40 *   y -> ar [label="wait for obtain"];
41 *   ao -> y [label="last release"];
42 *   ao -> r [label="wait for obtain"];
43 *   ar -> r [label="timeout"];
44 *   ar -> ao [label="timeout"];
45 * }
46 * @enddot
47 */
48typedef enum {
49  /**
50   * @brief This scheduler node is solely used by the owner thread.
51   *
52   * This thread owns no resources using a helping protocol and thus does not
53   * take part in the scheduler helping protocol.  No help will be provided for
54   * other thread.
55   */
56  SCHEDULER_HELP_YOURSELF,
57
58  /**
59   * @brief This scheduler node is owned by a thread actively owning a resource.
60   *
61   * This scheduler node can be used to help out threads.
62   *
63   * In case this scheduler node changes its state from ready to scheduled and
64   * the thread executes using another node, then an idle thread will be
65   * provided as a user of this node to temporarily execute on behalf of the
66   * owner thread.  Thus lower priority threads are denied access to the
67   * processors of this scheduler instance.
68   *
69   * In case a thread actively owning a resource performs a blocking operation,
70   * then an idle thread will be used also in case this node is in the
71   * scheduled state.
72   */
73  SCHEDULER_HELP_ACTIVE_OWNER,
74
75  /**
76   * @brief This scheduler node is owned by a thread actively obtaining a
77   * resource currently owned by another thread.
78   *
79   * This scheduler node can be used to help out threads.
80   *
81   * The thread owning this node is ready and will give away its processor in
82   * case the thread owning the resource asks for help.
83   */
84  SCHEDULER_HELP_ACTIVE_RIVAL,
85
86  /**
87   * @brief This scheduler node is owned by a thread obtaining a
88   * resource currently owned by another thread.
89   *
90   * This scheduler node can be used to help out threads.
91   *
92   * The thread owning this node is blocked.
93   */
94  SCHEDULER_HELP_PASSIVE
95} Scheduler_Help_state;
96#endif
97
98/**
99 * @brief Scheduler node for per-thread data.
100 */
101typedef struct Scheduler_Node {
102#if defined(RTEMS_SMP)
103  /**
104   * @brief Chain node for usage in various scheduler data structures.
105   *
106   * Strictly this is the wrong place for this field since the data structures
107   * to manage scheduler nodes belong to the particular scheduler
108   * implementation.  Currently all SMP scheduler implementations use chains.
109   * The node is here to simplify things, just like the object node in the
110   * thread control block.  It may be replaced with a union to add a red-black
111   * tree node in the future.
112   */
113  Chain_Node Node;
114
115  /**
116   * @brief The thread using this node.
117   */
118  struct _Thread_Control *user;
119
120  /**
121   * @brief The help state of this node.
122   */
123  Scheduler_Help_state help_state;
124
125  /**
126   * @brief The idle thread claimed by this node in case the help state is
127   * SCHEDULER_HELP_ACTIVE_OWNER.
128   *
129   * Active owners will lend their own node to an idle thread in case they
130   * execute currently using another node or in case they perform a blocking
131   * operation.  This is necessary to ensure the priority ceiling protocols
132   * work across scheduler boundaries.
133   */
134  struct _Thread_Control *idle;
135
136  /**
137   * @brief The thread accepting help by this node in case the help state is
138   * not SCHEDULER_HELP_YOURSELF.
139   */
140  struct _Thread_Control *accepts_help;
141#endif
142
143  /**
144   * @brief Thread wait support block.
145   */
146  struct {
147    Priority_Aggregation Priority;
148  } Wait;
149
150  /**
151   * @brief The thread owning this node.
152   */
153  struct _Thread_Control *owner;
154
155  /**
156   * @brief The thread priority information used by the scheduler.
157   *
158   * The thread priority is manifest in two independent areas.  One area is the
159   * user visible thread priority along with a potential thread queue.  The
160   * other is the scheduler.  During a thread priority change, the user visible
161   * thread priority and the thread queue are first updated and the thread
162   * priority value here is changed.  Once this is done the scheduler is
163   * notified via the update priority operation, so that it can update its
164   * internal state and honour a new thread priority value.
165   */
166  struct {
167    /**
168     * @brief The thread priority value of this scheduler node.
169     *
170     * The producer of this value is _Thread_Change_priority().  The consumer
171     * is the scheduler via the unblock and update priority operations.
172     */
173    Priority_Control value;
174
175#if defined(RTEMS_SMP)
176    /**
177     * @brief Sequence lock to synchronize priority value updates.
178     */
179    SMP_sequence_lock_Control Lock;
180#endif
181
182    /**
183     * @brief In case a priority update is necessary and this is true, then
184     * enqueue the thread as the first of its priority group, otherwise enqueue
185     * the thread as the last of its priority group.
186     */
187    bool prepend_it;
188  } Priority;
189} Scheduler_Node;
190
191#ifdef __cplusplus
192}
193#endif /* __cplusplus */
194
195#endif /* _RTEMS_SCORE_SCHEDULERNODE_H */
Note: See TracBrowser for help on using the repository browser.