source: rtems/cpukit/score/include/rtems/score/schedulernode.h @ 266d383

5
Last change on this file since 266d383 was 266d383, checked in by Sebastian Huber <sebastian.huber@…>, on 09/08/16 at 12:07:12

score: Manage scheduler nodes via thread queues

Update #2556.

  • Property mode set to 100644
File size: 6.1 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
142  /**
143   * @brief Block to register and manage this scheduler node in the thread
144   * control block of the owner of this scheduler node.
145   */
146  struct {
147    /**
148     * @brief Node to add this scheduler node to
149     * Thread_Control::Scheduler::Wait_nodes.
150     */
151    Chain_Node Wait_node;
152  } Thread;
153#endif
154
155  /**
156   * @brief Thread wait support block.
157   */
158  struct {
159    Priority_Aggregation Priority;
160  } Wait;
161
162  /**
163   * @brief The thread owning this node.
164   */
165  struct _Thread_Control *owner;
166
167  /**
168   * @brief The thread priority information used by the scheduler.
169   *
170   * The thread priority is manifest in two independent areas.  One area is the
171   * user visible thread priority along with a potential thread queue.  The
172   * other is the scheduler.  During a thread priority change, the user visible
173   * thread priority and the thread queue are first updated and the thread
174   * priority value here is changed.  Once this is done the scheduler is
175   * notified via the update priority operation, so that it can update its
176   * internal state and honour a new thread priority value.
177   */
178  struct {
179    /**
180     * @brief The thread priority value of this scheduler node.
181     *
182     * The producer of this value is _Thread_Change_priority().  The consumer
183     * is the scheduler via the unblock and update priority operations.
184     */
185    Priority_Control value;
186
187#if defined(RTEMS_SMP)
188    /**
189     * @brief Sequence lock to synchronize priority value updates.
190     */
191    SMP_sequence_lock_Control Lock;
192#endif
193
194    /**
195     * @brief In case a priority update is necessary and this is true, then
196     * enqueue the thread as the first of its priority group, otherwise enqueue
197     * the thread as the last of its priority group.
198     */
199    bool prepend_it;
200  } Priority;
201} Scheduler_Node;
202
203#if defined(RTEMS_SMP)
204/**
205 * @brief The size of a scheduler node.
206 *
207 * This value is provided via <rtems/confdefs.h>.
208 */
209extern const size_t _Scheduler_Node_size;
210#endif
211
212#ifdef __cplusplus
213}
214#endif /* __cplusplus */
215
216#endif /* _RTEMS_SCORE_SCHEDULERNODE_H */
Note: See TracBrowser for help on using the repository browser.