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

4.115
Last change on this file since ac532f3 was ac532f3, checked in by Sebastian Huber <sebastian.huber@…>, on 07/04/14 at 11:40:10

score: Add _Scheduler_Help()

Manage the help state of threads with respect to scheduling decisions.

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