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

5
Last change on this file since ca1e546e was ca1e546e, checked in by Sebastian Huber <sebastian.huber@…>, on 02/02/17 at 15:24:05

score: Improve scheduler helping protocol

Only register ask for help requests in the scheduler unblock and yield
operations. The actual ask for help operation is carried out during
_Thread_Do_dispatch() on a processor related to the thread. This yields
a better separation of scheduler instances. A thread of one scheduler
instance should not be forced to carry out too much work for threads on
other scheduler instances.

Update #2556.

  • Property mode set to 100644
File size: 13.7 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/thread.h>
23#if defined(RTEMS_SMP)
24  #include <sys/cpuset.h>
25#endif
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31struct Per_CPU_Control;
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
45/**
46 * @brief The scheduler operations.
47 */
48typedef struct {
49  /** @see _Scheduler_Handler_initialization() */
50  void ( *initialize )( const Scheduler_Control * );
51
52  /** @see _Scheduler_Schedule() */
53  void ( *schedule )( const Scheduler_Control *, Thread_Control *);
54
55  /** @see _Scheduler_Yield() */
56  void ( *yield )(
57    const Scheduler_Control *,
58    Thread_Control *,
59    Scheduler_Node *
60  );
61
62  /** @see _Scheduler_Block() */
63  void ( *block )(
64    const Scheduler_Control *,
65    Thread_Control *,
66    Scheduler_Node *
67  );
68
69  /** @see _Scheduler_Unblock() */
70  void ( *unblock )(
71    const Scheduler_Control *,
72    Thread_Control *,
73    Scheduler_Node *
74  );
75
76  /** @see _Scheduler_Update_priority() */
77  void ( *update_priority )(
78    const Scheduler_Control *,
79    Thread_Control *,
80    Scheduler_Node *
81  );
82
83  /** @see _Scheduler_Map_priority() */
84  Priority_Control ( *map_priority )(
85    const Scheduler_Control *,
86    Priority_Control
87  );
88
89  /** @see _Scheduler_Unmap_priority() */
90  Priority_Control ( *unmap_priority )(
91    const Scheduler_Control *,
92    Priority_Control
93  );
94
95#if defined(RTEMS_SMP)
96  /**
97   * @brief Ask for help operation.
98   *
99   * @param[in] scheduler The scheduler instance to ask for help.
100   * @param[in] the_thread The thread needing help.
101   * @param[in] node The scheduler node.
102   *
103   * @retval true Ask for help was successful.
104   * @retval false Otherwise.
105   */
106  bool ( *ask_for_help )(
107    const Scheduler_Control *scheduler,
108    Thread_Control          *the_thread,
109    Scheduler_Node          *node
110  );
111
112  /**
113   * @brief Reconsider help operation.
114   *
115   * @param[in] scheduler The scheduler instance to reconsider the help
116   *   request.
117   * @param[in] the_thread The thread reconsidering a help request.
118   * @param[in] node The scheduler node.
119   */
120  void ( *reconsider_help_request )(
121    const Scheduler_Control *scheduler,
122    Thread_Control          *the_thread,
123    Scheduler_Node          *node
124  );
125
126  /**
127   * @brief Withdraw node operation.
128   *
129   * @param[in] scheduler The scheduler instance to withdraw the node.
130   * @param[in] the_thread The thread using the node.
131   * @param[in] node The scheduler node to withdraw.
132   * @param[in] next_state The next thread scheduler state in case the node is
133   *   scheduled.
134   */
135  void ( *withdraw_node )(
136    const Scheduler_Control *scheduler,
137    Thread_Control          *the_thread,
138    Scheduler_Node          *node,
139    Thread_Scheduler_state   next_state
140  );
141
142  /**
143   * @brief Add processor operation.
144   *
145   * @param[in] scheduler The scheduler instance to add the processor.
146   * @param[in] idle The idle thread of the processor to add.
147   */
148  void ( *add_processor )(
149    const Scheduler_Control *scheduler,
150    Thread_Control          *idle
151  );
152
153  /**
154   * @brief Remove processor operation.
155   *
156   * @param[in] scheduler The scheduler instance to remove the processor.
157   * @param[in] cpu The processor to remove.
158   *
159   * @return The idle thread of the removed processor.
160   */
161  Thread_Control *( *remove_processor )(
162    const Scheduler_Control *scheduler,
163    struct Per_CPU_Control  *cpu
164  );
165#endif
166
167  /** @see _Scheduler_Node_initialize() */
168  void ( *node_initialize )(
169    const Scheduler_Control *,
170    Scheduler_Node *,
171    Thread_Control *,
172    Priority_Control
173  );
174
175  /** @see _Scheduler_Node_destroy() */
176  void ( *node_destroy )( const Scheduler_Control *, Scheduler_Node * );
177
178  /** @see _Scheduler_Release_job() */
179  void ( *release_job ) (
180    const Scheduler_Control *,
181    Thread_Control *,
182    Priority_Node *,
183    uint64_t,
184    Thread_queue_Context *
185  );
186
187  /** @see _Scheduler_Cancel_job() */
188  void ( *cancel_job ) (
189    const Scheduler_Control *,
190    Thread_Control *,
191    Priority_Node *,
192    Thread_queue_Context *
193  );
194
195  /** @see _Scheduler_Tick() */
196  void ( *tick )( const Scheduler_Control *, Thread_Control * );
197
198  /** @see _Scheduler_Start_idle() */
199  void ( *start_idle )(
200    const Scheduler_Control *,
201    Thread_Control *,
202    struct Per_CPU_Control *
203  );
204
205#if defined(RTEMS_SMP)
206  /** @see _Scheduler_Get_affinity() */
207  bool ( *get_affinity )(
208    const Scheduler_Control *,
209    Thread_Control *,
210    size_t,
211    cpu_set_t *
212  );
213 
214  /** @see _Scheduler_Set_affinity() */
215  bool ( *set_affinity )(
216    const Scheduler_Control *,
217    Thread_Control *,
218    size_t,
219    const cpu_set_t *
220  );
221#endif
222} Scheduler_Operations;
223
224/**
225 * @brief Scheduler context.
226 *
227 * The scheduler context of a particular scheduler implementation must place
228 * this structure at the begin of its context structure.
229 */
230typedef struct Scheduler_Context {
231  /**
232   * @brief Lock to protect this scheduler instance.
233   */
234  ISR_LOCK_MEMBER( Lock )
235
236#if defined(RTEMS_SMP)
237  /**
238   * @brief Count of processors owned by this scheduler instance.
239   */
240  uint32_t processor_count;
241#endif
242} Scheduler_Context;
243
244/**
245 * @brief Scheduler control.
246 */
247struct Scheduler_Control {
248  /**
249   * @brief Reference to a statically allocated scheduler context.
250   */
251  Scheduler_Context *context;
252
253  /**
254   * @brief The scheduler operations.
255   */
256  Scheduler_Operations Operations;
257
258  /**
259   * @brief The maximum priority value of this scheduler.
260   *
261   * It defines the lowest (least important) thread priority for this
262   * scheduler.  For example the idle threads have this priority.
263   */
264  Priority_Control maximum_priority;
265
266  /**
267   * @brief The scheduler name.
268   */
269  uint32_t name;
270};
271
272/**
273 * @brief Registered schedulers.
274 *
275 * Application provided via <rtems/confdefs.h>.
276 *
277 * @see _Scheduler_Count.
278 */
279extern const Scheduler_Control _Scheduler_Table[];
280
281/**
282 * @brief Count of registered schedulers.
283 *
284 * Application provided via <rtems/confdefs.h> on SMP configurations.
285 *
286 * It is very important that this is a compile-time constant on uni-processor
287 * configurations (in this case RTEMS_SMP is not defined) so that the compiler
288 * can optimize the some loops away
289 *
290 * @see _Scheduler_Table.
291 */
292#if defined(RTEMS_SMP)
293  extern const size_t _Scheduler_Count;
294#else
295  #define _Scheduler_Count ( (size_t) 1 )
296#endif
297
298#if defined(RTEMS_SMP)
299  /**
300   * @brief The scheduler assignment default attributes.
301   */
302  #define SCHEDULER_ASSIGN_DEFAULT UINT32_C(0x0)
303
304  /**
305   * @brief The presence of this processor is optional.
306   */
307  #define SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL SCHEDULER_ASSIGN_DEFAULT
308
309  /**
310   * @brief The presence of this processor is mandatory.
311   */
312  #define SCHEDULER_ASSIGN_PROCESSOR_MANDATORY UINT32_C(0x1)
313
314  /**
315   * @brief Scheduler assignment.
316   */
317  typedef struct {
318    /**
319     * @brief The scheduler for this processor.
320     */
321    const Scheduler_Control *scheduler;
322
323    /**
324     * @brief The scheduler assignment attributes.
325     *
326     * Use @ref SCHEDULER_ASSIGN_DEFAULT to select default attributes.
327     *
328     * The presence of a processor can be
329     * - @ref SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL, or
330     * - @ref SCHEDULER_ASSIGN_PROCESSOR_MANDATORY.
331     */
332    uint32_t attributes;
333  } Scheduler_Assignment;
334
335  /**
336   * @brief The scheduler assignments.
337   *
338   * The length of this array must be equal to the maximum processors.
339   *
340   * Application provided via <rtems/confdefs.h>.
341   *
342   * @see _Scheduler_Table and rtems_configuration_get_maximum_processors().
343   */
344  extern const Scheduler_Assignment _Scheduler_Initial_assignments[];
345#endif
346
347/**
348 * @brief Returns the thread priority.
349 *
350 * @param[in] scheduler Unused.
351 * @param[in] priority The thread priority.
352 *
353 * @return priority The thread priority.
354 */
355Priority_Control _Scheduler_default_Map_priority(
356  const Scheduler_Control *scheduler,
357  Priority_Control         priority
358);
359
360#define _Scheduler_default_Unmap_priority _Scheduler_default_Map_priority
361
362#if defined(RTEMS_SMP)
363  /**
364   * @brief Does nothing.
365   *
366   * @param[in] scheduler Unused.
367   * @param[in] the_thread Unused.
368   * @param[in] node Unused.
369   *
370   * @retval false Always.
371   */
372  bool _Scheduler_default_Ask_for_help(
373    const Scheduler_Control *scheduler,
374    Thread_Control          *the_thread,
375    Scheduler_Node          *node
376  );
377
378  /**
379   * @brief Does nothing.
380   *
381   * @param[in] scheduler Unused.
382   * @param[in] the_thread Unused.
383   * @param[in] node Unused.
384   */
385  void _Scheduler_default_Reconsider_help_request(
386    const Scheduler_Control *scheduler,
387    Thread_Control          *the_thread,
388    Scheduler_Node          *node
389  );
390
391  /**
392   * @brief Does nothing.
393   *
394   * @param[in] scheduler Unused.
395   * @param[in] the_thread Unused.
396   * @param[in] node Unused.
397   * @param[in] next_state Unused.
398   */
399  void _Scheduler_default_Withdraw_node(
400    const Scheduler_Control *scheduler,
401    Thread_Control          *the_thread,
402    Scheduler_Node          *node,
403    Thread_Scheduler_state   next_state
404  );
405
406  #define SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
407    _Scheduler_default_Ask_for_help, \
408    _Scheduler_default_Reconsider_help_request, \
409    _Scheduler_default_Withdraw_node, \
410    NULL, \
411    NULL,
412#else
413  #define SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP
414#endif
415
416/**
417 * @brief Does nothing.
418 *
419 * @param[in] scheduler Unused.
420 * @param[in] the_thread Unused.
421 */
422void _Scheduler_default_Schedule(
423  const Scheduler_Control *scheduler,
424  Thread_Control          *the_thread
425);
426
427/**
428 * @brief Performs the scheduler base node initialization.
429 *
430 * @param[in] scheduler Unused.
431 * @param[in] node The node to initialize.
432 * @param[in] the_thread Unused.
433 * @param[in] priority The thread priority.
434 */
435void _Scheduler_default_Node_initialize(
436  const Scheduler_Control *scheduler,
437  Scheduler_Node          *node,
438  Thread_Control          *the_thread,
439  Priority_Control         priority
440);
441
442/**
443 * @brief Does nothing.
444 *
445 * @param[in] scheduler Unused.
446 * @param[in] node Unused.
447 */
448void _Scheduler_default_Node_destroy(
449  const Scheduler_Control *scheduler,
450  Scheduler_Node          *node
451);
452
453/**
454 * @brief Does nothing.
455 *
456 * @param[in] scheduler Unused.
457 * @param[in] the_thread Unused.
458 * @param[in] priority_node Unused.
459 * @param[in] deadline Unused.
460 * @param[in] queue_context Unused.
461 *
462 * @retval NULL Always.
463 */
464void _Scheduler_default_Release_job(
465  const Scheduler_Control *scheduler,
466  Thread_Control          *the_thread,
467  Priority_Node           *priority_node,
468  uint64_t                 deadline,
469  Thread_queue_Context    *queue_context
470);
471
472/**
473 * @brief Does nothing.
474 *
475 * @param[in] scheduler Unused.
476 * @param[in] the_thread Unused.
477 * @param[in] priority_node Unused.
478 * @param[in] queue_context Unused.
479 *
480 * @retval NULL Always.
481 */
482void _Scheduler_default_Cancel_job(
483  const Scheduler_Control *scheduler,
484  Thread_Control          *the_thread,
485  Priority_Node           *priority_node,
486  Thread_queue_Context    *queue_context
487);
488
489/**
490 * @brief Performs tick operations depending on the CPU budget algorithm for
491 * each executing thread.
492 *
493 * This routine is invoked as part of processing each clock tick.
494 *
495 * @param[in] scheduler The scheduler.
496 * @param[in] executing An executing thread.
497 */
498void _Scheduler_default_Tick(
499  const Scheduler_Control *scheduler,
500  Thread_Control          *executing
501);
502
503/**
504 * @brief Starts an idle thread.
505 *
506 * @param[in] scheduler The scheduler.
507 * @param[in] the_thread An idle thread.
508 * @param[in] cpu This parameter is unused.
509 */
510void _Scheduler_default_Start_idle(
511  const Scheduler_Control *scheduler,
512  Thread_Control          *the_thread,
513  struct Per_CPU_Control  *cpu
514);
515
516#if defined(RTEMS_SMP)
517  /**
518   * @brief Get affinity for the default scheduler.
519   *
520   * @param[in] scheduler The scheduler instance.
521   * @param[in] thread The associated thread.
522   * @param[in] cpusetsize The size of the cpuset.
523   * @param[out] cpuset Affinity set containing all CPUs.
524   *
525   * @retval 0 Successfully got cpuset
526   * @retval -1 The cpusetsize is invalid for the system
527   */
528  bool _Scheduler_default_Get_affinity(
529    const Scheduler_Control *scheduler,
530    Thread_Control          *thread,
531    size_t                   cpusetsize,
532    cpu_set_t               *cpuset
533  );
534
535  /**
536   * @brief Set affinity for the default scheduler.
537   *
538   * @param[in] scheduler The scheduler instance.
539   * @param[in] thread The associated thread.
540   * @param[in] cpusetsize The size of the cpuset.
541   * @param[in] cpuset Affinity new affinity set.
542   *
543   * @retval 0 Successful
544   *
545   *  This method always returns successful and does not save
546   *  the cpuset.
547   */
548  bool _Scheduler_default_Set_affinity(
549    const Scheduler_Control *scheduler,
550    Thread_Control          *thread,
551    size_t                   cpusetsize,
552    const cpu_set_t         *cpuset
553  );
554
555  #define SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY \
556    , _Scheduler_default_Get_affinity \
557    , _Scheduler_default_Set_affinity
558#else
559  #define SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY
560#endif
561
562/**
563 * @brief This defines the lowest (least important) thread priority of the
564 * first scheduler instance.
565 */
566#define PRIORITY_MAXIMUM ( _Scheduler_Table[ 0 ].maximum_priority )
567
568/**@}*/
569
570#ifdef __cplusplus
571}
572#endif
573
574#endif
575/* end of include file */
Note: See TracBrowser for help on using the repository browser.