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

5
Last change on this file since c597fb1 was c597fb1, checked in by Sebastian Huber <sebastian.huber@…>, on 11/09/17 at 15:21:37

score: Optimize scheduler priority updates

Thread priority changes may append or prepend the thread to its priority
group on the scheduler ready queue. Previously, a separate priority
value and a prepend-it flag in the scheduler node were used to propagate
a priority change to the scheduler.

Now, use an append-it bit in the priority control and reduce the plain
priority value to 63 bits.

This change leads to a significant code size reduction (about 25%) of
the SMP schedulers. The negligible increase of the standard priority
scheduler is due to some additional shift operations
(SCHEDULER_PRIORITY_MAP() and SCHEDULER_PRIORITY_UNMAP()).

Before:

text filename

136 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimpleblock.o
464 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimplechangepriority.o

24 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimple.o

108 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimpleschedule.o
292 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimpleunblock.o
264 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimpleyield.o

text filename

280 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriorityblock.o
488 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerprioritychangepriority.o
200 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriority.o
164 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriorityschedule.o
328 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriorityunblock.o
200 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriorityyield.o

text filename

24112 arm-rtems5/c/imx7/cpukit/score/src/libscore_a-scheduleredfsmp.o

text filename

37204 sparc-rtems5/c/gr740/cpukit/score/src/libscore_a-scheduleredfsmp.o

text filename

42236 powerpc-rtems5/c/qoriq_e6500_32/cpukit/score/src/libscore_a-scheduleredfsmp.o

After:

text filename

136 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimpleblock.o
272 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimplechangepriority.o

24 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimple.o

108 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimpleschedule.o
292 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimpleunblock.o
264 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimpleyield.o

text filename

280 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriorityblock.o
488 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerprioritychangepriority.o
208 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriority.o
164 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriorityschedule.o
332 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriorityunblock.o
200 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriorityyield.o

text filename

18860 arm-rtems5/c/imx7/cpukit/score/src/libscore_a-scheduleredfsmp.o

text filename

28520 sparc-rtems5/c/gr740/cpukit/score/src/libscore_a-scheduleredfsmp.o

text filename

32664 powerpc-rtems5/c/qoriq_e6500_32/cpukit/score/src/libscore_a-scheduleredfsmp.o

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