source: rtems/cpukit/score/include/rtems/score/schedulernode.h @ 2403473

5
Last change on this file since 2403473 was 2403473, checked in by Sebastian Huber <sebastian.huber@…>, on Sep 23, 2016 at 12:54:04 PM

score: Add _Thread_Scheduler_process_requests()

Update #2556.

  • Property mode set to 100644
File size: 7.9 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#if defined(RTEMS_SMP)
99/**
100 * @brief The scheduler node requests.
101 */
102typedef enum {
103  /**
104   * @brief The scheduler node is not on the list of pending requests.
105   */
106  SCHEDULER_NODE_REQUEST_NOT_PENDING,
107
108  /**
109   * @brief There is a pending scheduler node request to add this scheduler
110   * node to the Thread_Control::Scheduler::Scheduler_nodes chain.
111   */
112  SCHEDULER_NODE_REQUEST_ADD,
113
114  /**
115   * @brief There is a pending scheduler node request to remove this scheduler
116   * node from the Thread_Control::Scheduler::Scheduler_nodes chain.
117   */
118  SCHEDULER_NODE_REQUEST_REMOVE,
119
120  /**
121   * @brief The scheduler node is on the list of pending requests, but nothing
122   * should change.
123   */
124  SCHEDULER_NODE_REQUEST_NOTHING,
125
126} Scheduler_Node_request;
127#endif
128
129typedef struct Scheduler_Node Scheduler_Node;
130
131/**
132 * @brief Scheduler node for per-thread data.
133 */
134struct Scheduler_Node {
135#if defined(RTEMS_SMP)
136  /**
137   * @brief Chain node for usage in various scheduler data structures.
138   *
139   * Strictly this is the wrong place for this field since the data structures
140   * to manage scheduler nodes belong to the particular scheduler
141   * implementation.  Currently all SMP scheduler implementations use chains.
142   * The node is here to simplify things, just like the object node in the
143   * thread control block.  It may be replaced with a union to add a red-black
144   * tree node in the future.
145   */
146  Chain_Node Node;
147
148  /**
149   * @brief The thread using this node.
150   */
151  struct _Thread_Control *user;
152
153  /**
154   * @brief The help state of this node.
155   */
156  Scheduler_Help_state help_state;
157
158  /**
159   * @brief The idle thread claimed by this node in case the help state is
160   * SCHEDULER_HELP_ACTIVE_OWNER.
161   *
162   * Active owners will lend their own node to an idle thread in case they
163   * execute currently using another node or in case they perform a blocking
164   * operation.  This is necessary to ensure the priority ceiling protocols
165   * work across scheduler boundaries.
166   */
167  struct _Thread_Control *idle;
168
169  /**
170   * @brief The thread accepting help by this node in case the help state is
171   * not SCHEDULER_HELP_YOURSELF.
172   */
173  struct _Thread_Control *accepts_help;
174
175  /**
176   * @brief Block to register and manage this scheduler node in the thread
177   * control block of the owner of this scheduler node.
178   */
179  struct {
180    /**
181     * @brief Node to add this scheduler node to
182     * Thread_Control::Scheduler::Wait_nodes.
183     */
184    Chain_Node Wait_node;
185
186    /**
187     * @brief Node to add this scheduler node to
188     * Thread_Control::Scheduler::Scheduler_nodes or a temporary remove list.
189     */
190    union {
191      /**
192       * @brief The node for Thread_Control::Scheduler::Scheduler_nodes.
193       */
194      Chain_Node Chain;
195
196      /**
197       * @brief The next pointer for a temporary remove list.
198       *
199       * @see _Thread_Scheduler_process_requests().
200       */
201      Scheduler_Node *next;
202    } Scheduler_node;
203
204    /**
205     * @brief Link to the next scheduler node in the
206     * Thread_Control::Scheduler::requests list.
207     */
208    Scheduler_Node *next_request;
209
210    /**
211     * @brief The current scheduler node request.
212     */
213    Scheduler_Node_request request;
214  } Thread;
215#endif
216
217  /**
218   * @brief Thread wait support block.
219   */
220  struct {
221    Priority_Aggregation Priority;
222  } Wait;
223
224  /**
225   * @brief The thread owning this node.
226   */
227  struct _Thread_Control *owner;
228
229  /**
230   * @brief The thread priority information used by the scheduler.
231   *
232   * The thread priority is manifest in two independent areas.  One area is the
233   * user visible thread priority along with a potential thread queue.  The
234   * other is the scheduler.  During a thread priority change, the user visible
235   * thread priority and the thread queue are first updated and the thread
236   * priority value here is changed.  Once this is done the scheduler is
237   * notified via the update priority operation, so that it can update its
238   * internal state and honour a new thread priority value.
239   */
240  struct {
241    /**
242     * @brief The thread priority value of this scheduler node.
243     *
244     * The producer of this value is _Thread_Change_priority().  The consumer
245     * is the scheduler via the unblock and update priority operations.
246     */
247    Priority_Control value;
248
249#if defined(RTEMS_SMP)
250    /**
251     * @brief Sequence lock to synchronize priority value updates.
252     */
253    SMP_sequence_lock_Control Lock;
254#endif
255
256    /**
257     * @brief In case a priority update is necessary and this is true, then
258     * enqueue the thread as the first of its priority group, otherwise enqueue
259     * the thread as the last of its priority group.
260     */
261    bool prepend_it;
262  } Priority;
263};
264
265#if defined(RTEMS_SMP)
266/**
267 * @brief The size of a scheduler node.
268 *
269 * This value is provided via <rtems/confdefs.h>.
270 */
271extern const size_t _Scheduler_Node_size;
272#endif
273
274#if defined(RTEMS_SMP)
275#define SCHEDULER_NODE_OF_THREAD_WAIT_NODE( node ) \
276  RTEMS_CONTAINER_OF( node, Scheduler_Node, Thread.Wait_node )
277
278#define SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node ) \
279  RTEMS_CONTAINER_OF( node, Scheduler_Node, Thread.Scheduler_node.Chain )
280#endif
281
282#ifdef __cplusplus
283}
284#endif /* __cplusplus */
285
286#endif /* _RTEMS_SCORE_SCHEDULERNODE_H */
Note: See TracBrowser for help on using the repository browser.