source: rtems/cpukit/score/include/rtems/score/scheduler.h @ 8568341

4.115
Last change on this file since 8568341 was 8568341, checked in by Sebastian Huber <sebastian.huber@…>, on 06/11/14 at 12:31:03

score: Need for help indicator for scheduler ops

Return a thread in need for help for the following scheduler operations

  • unblock,
  • change priority, and
  • yield.

A thread in need for help is a thread that encounters a scheduler state
change from scheduled to ready or a thread that cannot be scheduled in
an unblock operation. Such a thread can ask threads which depend on
resources owned by this thread for help.

  • Property mode set to 100644
File size: 12.9 KB
Line 
1/**
2 *  @file  rtems/score/scheduler.h
3 *
4 *  @brief Constants and Structures Associated with the Scheduler
5 *
6 *  This include file contains all the constants and structures associated
7 *  with the scheduler.
8 */
9
10/*
11 *  Copyright (C) 2010 Gedare Bloom.
12 *  Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.org/license/LICENSE.
17 */
18
19#ifndef _RTEMS_SCORE_SCHEDULER_H
20#define _RTEMS_SCORE_SCHEDULER_H
21
22#include <rtems/score/percpu.h>
23#include <rtems/score/priority.h>
24#include <rtems/score/thread.h>
25#if defined(__RTEMS_HAVE_SYS_CPUSET_H__) && defined(RTEMS_SMP)
26  #include <sys/cpuset.h>
27#endif
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33/**
34 *  @defgroup ScoreScheduler Scheduler Handler
35 *
36 *  @ingroup Score
37 *
38 *  This handler encapsulates functionality related to managing sets of threads
39 *  that are ready for execution.
40 */
41/**@{*/
42
43typedef struct Scheduler_Control Scheduler_Control;
44
45typedef struct Scheduler_Node Scheduler_Node;
46
47#if defined(RTEMS_SMP)
48  typedef Thread_Control * Scheduler_Void_or_thread;
49
50  #define SCHEDULER_RETURN_VOID_OR_NULL return NULL
51#else
52  typedef void Scheduler_Void_or_thread;
53
54  #define SCHEDULER_RETURN_VOID_OR_NULL return
55#endif
56
57/**
58 * @brief The scheduler operations.
59 */
60typedef struct {
61  /** @see _Scheduler_Handler_initialization() */
62  void ( *initialize )( const Scheduler_Control * );
63
64  /** @see _Scheduler_Schedule() */
65  void ( *schedule )( const Scheduler_Control *, Thread_Control *);
66
67  /** @see _Scheduler_Yield() */
68  Scheduler_Void_or_thread ( *yield )(
69    const Scheduler_Control *,
70    Thread_Control *
71  );
72
73  /** @see _Scheduler_Block() */
74  void ( *block )(
75    const Scheduler_Control *,
76    Thread_Control *
77  );
78
79  /** @see _Scheduler_Unblock() */
80  Scheduler_Void_or_thread ( *unblock )(
81    const Scheduler_Control *,
82    Thread_Control *
83  );
84
85  /** @see _Scheduler_Change_priority() */
86  Scheduler_Void_or_thread ( *change_priority )(
87    const Scheduler_Control *,
88    Thread_Control *,
89    Priority_Control,
90    bool
91  );
92
93  /** @see _Scheduler_Node_initialize() */
94  void ( *node_initialize )( const Scheduler_Control *, Thread_Control * );
95
96  /** @see _Scheduler_Node_destroy() */
97  void ( *node_destroy )( const Scheduler_Control *, Thread_Control * );
98
99  /** @see _Scheduler_Update_priority() */
100  void ( *update_priority )(
101    const Scheduler_Control *,
102    Thread_Control *,
103    Priority_Control
104  );
105
106  /** @see _Scheduler_Priority_compare() */
107  int ( *priority_compare )(
108    Priority_Control,
109    Priority_Control
110  );
111
112  /** @see _Scheduler_Release_job() */
113  void ( *release_job ) (
114    const Scheduler_Control *,
115    Thread_Control *,
116    uint32_t
117  );
118
119  /** @see _Scheduler_Tick() */
120  void ( *tick )( const Scheduler_Control *, Thread_Control * );
121
122  /** @see _Scheduler_Start_idle() */
123  void ( *start_idle )(
124    const Scheduler_Control *,
125    Thread_Control *,
126    Per_CPU_Control *
127  );
128
129#if defined(__RTEMS_HAVE_SYS_CPUSET_H__) && defined(RTEMS_SMP)
130  /** @see _Scheduler_Get_affinity() */
131  bool ( *get_affinity )(
132    const Scheduler_Control *,
133    Thread_Control *,
134    size_t,
135    cpu_set_t *
136  );
137 
138  /** @see _Scheduler_Set_affinity() */
139  bool ( *set_affinity )(
140    const Scheduler_Control *,
141    Thread_Control *,
142    size_t,
143    const cpu_set_t *
144  );
145#endif
146} Scheduler_Operations;
147
148/**
149 * @brief Scheduler context.
150 *
151 * The scheduler context of a particular scheduler implementation must place
152 * this structure at the begin of its context structure.
153 */
154typedef struct Scheduler_Context {
155#if defined(RTEMS_SMP)
156  /**
157   * @brief Count of processors owned by this scheduler instance.
158   */
159  uint32_t processor_count;
160#endif
161} Scheduler_Context;
162
163/**
164 * @brief Scheduler control.
165 */
166struct Scheduler_Control {
167  /**
168   * @brief Reference to a statically allocated scheduler context.
169   */
170  Scheduler_Context *context;
171
172  /**
173   * @brief The scheduler operations.
174   */
175  Scheduler_Operations Operations;
176
177  /**
178   * @brief The scheduler name.
179   */
180  uint32_t name;
181};
182
183#if defined(RTEMS_SMP)
184/**
185 * @brief State to indicate potential help for other threads.
186 *
187 * @dot
188 * digraph state {
189 *   y [label="HELP YOURSELF"];
190 *   ao [label="HELP ACTIVE OWNER"];
191 *   ar [label="HELP ACTIVE RIVAL"];
192 *
193 *   y -> ao [label="obtain"];
194 *   y -> ar [label="wait for obtain"];
195 *   ao -> y [label="last release"];
196 *   ao -> r [label="wait for obtain"];
197 *   ar -> r [label="timeout"];
198 *   ar -> ao [label="timeout"];
199 * }
200 * @enddot
201 */
202typedef enum {
203  /**
204   * @brief This scheduler node is solely used by the owner thread.
205   *
206   * This thread owns no resources using a helping protocol and thus does not
207   * take part in the scheduler helping protocol.  No help will be provided for
208   * other thread.
209   */
210  SCHEDULER_HELP_YOURSELF,
211
212  /**
213   * @brief This scheduler node is owned by a thread actively owning a resource.
214   *
215   * This scheduler node can be used to help out threads.
216   *
217   * In case this scheduler node changes its state from ready to scheduled and
218   * the thread executes using another node, then an idle thread will be
219   * provided as a user of this node to temporarily execute on behalf of the
220   * owner thread.  Thus lower priority threads are denied access to the
221   * processors of this scheduler instance.
222   *
223   * In case a thread actively owning a resource performs a blocking operation,
224   * then an idle thread will be used also in case this node is in the
225   * scheduled state.
226   */
227  SCHEDULER_HELP_ACTIVE_OWNER,
228
229  /**
230   * @brief This scheduler node is owned by a thread actively obtaining a
231   * resource currently owned by another thread.
232   *
233   * This scheduler node can be used to help out threads.
234   *
235   * The thread owning this node is ready and will give away its processor in
236   * case the thread owning the resource asks for help.
237   */
238  SCHEDULER_HELP_ACTIVE_RIVAL,
239
240  /**
241   * @brief This scheduler node is owned by a thread obtaining a
242   * resource currently owned by another thread.
243   *
244   * This scheduler node can be used to help out threads.
245   *
246   * The thread owning this node is blocked.
247   */
248  SCHEDULER_HELP_PASSIVE
249} Scheduler_Help_state;
250#endif
251
252/**
253 * @brief Scheduler node for per-thread data.
254 */
255struct Scheduler_Node {
256#if defined(RTEMS_SMP)
257  /**
258   * @brief Chain node for usage in various scheduler data structures.
259   *
260   * Strictly this is the wrong place for this field since the data structures
261   * to manage scheduler nodes belong to the particular scheduler
262   * implementation.  Currently all SMP scheduler implementations use chains.
263   * The node is here to simplify things, just like the object node in the
264   * thread control block.  It may be replaced with a union to add a red-black
265   * tree node in the future.
266   */
267  Chain_Node Node;
268
269  /**
270   * @brief The thread using this node.
271   */
272  Thread_Control *user;
273
274  /**
275   * @brief The help state of this node.
276   */
277  Scheduler_Help_state help_state;
278
279  /**
280   * @brief The thread owning this node.
281   */
282  Thread_Control *owner;
283
284  /**
285   * @brief The idle thread claimed by this node in case the help state is
286   * SCHEDULER_HELP_ACTIVE_OWNER.
287   *
288   * Active owners will lend their own node to an idle thread in case they
289   * execute currently using another node or in case they perform a blocking
290   * operation.  This is necessary to ensure the priority ceiling protocols
291   * work across scheduler boundaries.
292   */
293  Thread_Control *idle;
294
295  /**
296   * @brief The thread accepting help by this node in case the help state is
297   * not SCHEDULER_HELP_YOURSELF.
298   */
299  Thread_Control *accepts_help;
300#endif
301};
302
303/**
304 * @brief Registered schedulers.
305 *
306 * Application provided via <rtems/confdefs.h>.
307 *
308 * @see _Scheduler_Count.
309 */
310extern const Scheduler_Control _Scheduler_Table[];
311
312/**
313 * @brief Count of registered schedulers.
314 *
315 * Application provided via <rtems/confdefs.h> on SMP configurations.
316 *
317 * It is very important that this is a compile-time constant on uni-processor
318 * configurations (in this case RTEMS_SMP is not defined) so that the compiler
319 * can optimize the some loops away
320 *
321 * @see _Scheduler_Table.
322 */
323#if defined(RTEMS_SMP)
324  extern const size_t _Scheduler_Count;
325#else
326  #define _Scheduler_Count ( (size_t) 1 )
327#endif
328
329#if defined(RTEMS_SMP)
330  /**
331   * @brief The scheduler assignment default attributes.
332   */
333  #define SCHEDULER_ASSIGN_DEFAULT UINT32_C(0x0)
334
335  /**
336   * @brief The presence of this processor is optional.
337   */
338  #define SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL SCHEDULER_ASSIGN_DEFAULT
339
340  /**
341   * @brief The presence of this processor is mandatory.
342   */
343  #define SCHEDULER_ASSIGN_PROCESSOR_MANDATORY UINT32_C(0x1)
344
345  /**
346   * @brief Scheduler assignment.
347   */
348  typedef struct {
349    /**
350     * @brief The scheduler for this processor.
351     */
352    const Scheduler_Control *scheduler;
353
354    /**
355     * @brief The scheduler assignment attributes.
356     *
357     * Use @ref SCHEDULER_ASSIGN_DEFAULT to select default attributes.
358     *
359     * The presence of a processor can be
360     * - @ref SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL, or
361     * - @ref SCHEDULER_ASSIGN_PROCESSOR_MANDATORY.
362     */
363    uint32_t attributes;
364  } Scheduler_Assignment;
365
366  /**
367   * @brief The scheduler assignments.
368   *
369   * The length of this array must be equal to the maximum processors.
370   *
371   * Application provided via <rtems/confdefs.h>.
372   *
373   * @see _Scheduler_Table and rtems_configuration_get_maximum_processors().
374   */
375  extern const Scheduler_Assignment _Scheduler_Assignments[];
376#endif
377
378/**
379 * @brief Does nothing.
380 *
381 * @param[in] scheduler Unused.
382 * @param[in] the_thread Unused.
383 */
384void _Scheduler_default_Schedule(
385  const Scheduler_Control *scheduler,
386  Thread_Control          *the_thread
387);
388
389/**
390 * @brief Does nothing.
391 *
392 * @param[in] scheduler Unused.
393 * @param[in] the_thread Unused.
394 */
395void _Scheduler_default_Node_initialize(
396  const Scheduler_Control *scheduler,
397  Thread_Control          *the_thread
398);
399
400/**
401 * @brief Does nothing.
402 *
403 * @param[in] scheduler Unused.
404 * @param[in] the_thread Unused.
405 */
406void _Scheduler_default_Node_destroy(
407  const Scheduler_Control *scheduler,
408  Thread_Control          *the_thread
409);
410
411/**
412 * @brief Does nothing.
413 *
414 * @param[in] scheduler Unused.
415 * @param[in] the_thread Unused.
416 * @param[in] new_priority Unused.
417 */
418void _Scheduler_default_Update_priority(
419  const Scheduler_Control *scheduler,
420  Thread_Control          *the_thread,
421  Priority_Control         new_priority
422);
423
424/**
425 * @brief Does nothing.
426 *
427 * @param[in] scheduler Unused.
428 * @param[in] the_thread Unused.
429 * @param[in] deadline Unused.
430 */
431void _Scheduler_default_Release_job(
432  const Scheduler_Control *scheduler,
433  Thread_Control          *the_thread,
434  uint32_t                 deadline
435);
436
437/**
438 * @brief Performs tick operations depending on the CPU budget algorithm for
439 * each executing thread.
440 *
441 * This routine is invoked as part of processing each clock tick.
442 *
443 * @param[in] scheduler The scheduler.
444 * @param[in] execution An executing thread.
445 */
446void _Scheduler_default_Tick(
447  const Scheduler_Control *scheduler,
448  Thread_Control          *executing
449);
450
451/**
452 * @brief Starts an idle thread.
453 *
454 * @param[in] scheduler The scheduler.
455 * @param[in] the_thread An idle thread.
456 * @param[in] cpu This parameter is unused.
457 */
458void _Scheduler_default_Start_idle(
459  const Scheduler_Control *scheduler,
460  Thread_Control          *the_thread,
461  Per_CPU_Control         *cpu
462);
463
464#if defined(__RTEMS_HAVE_SYS_CPUSET_H__) && defined(RTEMS_SMP)
465  /**
466   * @brief Get affinity for the default scheduler.
467   *
468   * @param[in] thread The associated thread.
469   * @param[in] cpusetsize The size of the cpuset.
470   * @param[out] cpuset Affinity set containing all CPUs.
471   *
472   * @retval 0 Successfully got cpuset
473   * @retval -1 The cpusetsize is invalid for the system
474   */
475  bool _Scheduler_default_Get_affinity(
476    const Scheduler_Control *scheduler,
477    Thread_Control          *thread,
478    size_t                   cpusetsize,
479    cpu_set_t               *cpuset
480  );
481
482  /**
483   * @brief Set affinity for the default scheduler.
484   *
485   * @param[in] thread The associated thread.
486   * @param[in] cpusetsize The size of the cpuset.
487   * @param[in] cpuset Affinity new affinity set.
488   *
489   * @retval 0 Successful
490   *
491   *  This method always returns successful and does not save
492   *  the cpuset.
493   */
494  bool _Scheduler_default_Set_affinity(
495    const Scheduler_Control *scheduler,
496    Thread_Control          *thread,
497    size_t                   cpusetsize,
498    const cpu_set_t         *cpuset
499  );
500
501  #define SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY \
502    , _Scheduler_default_Get_affinity \
503    , _Scheduler_default_Set_affinity
504#else
505  #define SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY
506#endif
507
508/**
509 * @brief Indicates if thread priority queues are broken with the configured
510 * scheduler or not.
511 *
512 * See also PR2174: Memory corruption with EDF scheduler and thread priority
513 * queues.
514 */
515extern const bool _Scheduler_FIXME_thread_priority_queues_are_broken;
516
517/**@}*/
518
519#ifdef __cplusplus
520}
521#endif
522
523#endif
524/* end of include file */
Note: See TracBrowser for help on using the repository browser.