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

5
Last change on this file since b8f76fa was b8f76fa, checked in by Sebastian Huber <sebastian.huber@…>, on 06/09/16 at 14:55:50

score: Delete unused _Scheduler_Priority_compare()

By convention, thread priorities must be integers in RTEMS. Smaller
values represent more important threads.

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