source: rtems/cpukit/score/include/rtems/score/scheduler.h @ 96316d1b

4.115
Last change on this file since 96316d1b was 96316d1b, checked in by Sebastian Huber <sebastian.huber@…>, on 06/26/15 at 07:15:36

score: Simplify <rtems/score/scheduler.h>

Drop the <rtems/score/percpu.h> include since this file exposes a lot of
implementation details.

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