source: rtems/cpukit/include/rtems/score/scheduler.h @ 878487b0

5
Last change on this file since 878487b0 was 7097962, checked in by Sebastian Huber <sebastian.huber@…>, on 08/29/18 at 07:43:44

score: Add thread pin/unpin support

Add support to temporarily pin a thread to its current processor. This
may be used to access per-processor data structures in critical sections
with enabled thread dispatching, e.g. a pinned thread is allowed to
block.

Update #3508.

  • Property mode set to 100644
File size: 14.8 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 Pin thread operation.
141   *
142   * @param[in] scheduler The scheduler instance of the specified processor.
143   * @param[in] the_thread The thread to pin.
144   * @param[in] node The scheduler node of the thread.
145   * @param[in] cpu The processor to pin the thread.
146   */
147  void ( *pin )(
148    const Scheduler_Control *scheduler,
149    Thread_Control          *the_thread,
150    Scheduler_Node          *node,
151    struct Per_CPU_Control  *cpu
152  );
153
154  /**
155   * @brief Unpin thread operation.
156   *
157   * @param[in] scheduler The scheduler instance of the specified processor.
158   * @param[in] the_thread The thread to unpin.
159   * @param[in] node The scheduler node of the thread.
160   * @param[in] cpu The processor to unpin the thread.
161   */
162  void ( *unpin )(
163    const Scheduler_Control *scheduler,
164    Thread_Control          *the_thread,
165    Scheduler_Node          *node,
166    struct Per_CPU_Control  *cpu
167  );
168
169  /**
170   * @brief Add processor operation.
171   *
172   * @param[in] scheduler The scheduler instance to add the processor.
173   * @param[in] idle The idle thread of the processor to add.
174   */
175  void ( *add_processor )(
176    const Scheduler_Control *scheduler,
177    Thread_Control          *idle
178  );
179
180  /**
181   * @brief Remove processor operation.
182   *
183   * @param[in] scheduler The scheduler instance to remove the processor.
184   * @param[in] cpu The processor to remove.
185   *
186   * @return The idle thread of the removed processor.
187   */
188  Thread_Control *( *remove_processor )(
189    const Scheduler_Control *scheduler,
190    struct Per_CPU_Control  *cpu
191  );
192#endif
193
194  /** @see _Scheduler_Node_initialize() */
195  void ( *node_initialize )(
196    const Scheduler_Control *,
197    Scheduler_Node *,
198    Thread_Control *,
199    Priority_Control
200  );
201
202  /** @see _Scheduler_Node_destroy() */
203  void ( *node_destroy )( const Scheduler_Control *, Scheduler_Node * );
204
205  /** @see _Scheduler_Release_job() */
206  void ( *release_job ) (
207    const Scheduler_Control *,
208    Thread_Control *,
209    Priority_Node *,
210    uint64_t,
211    Thread_queue_Context *
212  );
213
214  /** @see _Scheduler_Cancel_job() */
215  void ( *cancel_job ) (
216    const Scheduler_Control *,
217    Thread_Control *,
218    Priority_Node *,
219    Thread_queue_Context *
220  );
221
222  /** @see _Scheduler_Tick() */
223  void ( *tick )( const Scheduler_Control *, Thread_Control * );
224
225  /** @see _Scheduler_Start_idle() */
226  void ( *start_idle )(
227    const Scheduler_Control *,
228    Thread_Control *,
229    struct Per_CPU_Control *
230  );
231
232#if defined(RTEMS_SMP)
233  /** @see _Scheduler_Set_affinity() */
234  bool ( *set_affinity )(
235    const Scheduler_Control *,
236    Thread_Control *,
237    Scheduler_Node *,
238    const Processor_mask *
239  );
240#endif
241} Scheduler_Operations;
242
243/**
244 * @brief Scheduler context.
245 *
246 * The scheduler context of a particular scheduler implementation must place
247 * this structure at the begin of its context structure.
248 */
249typedef struct Scheduler_Context {
250  /**
251   * @brief Lock to protect this scheduler instance.
252   */
253  ISR_LOCK_MEMBER( Lock )
254
255#if defined(RTEMS_SMP)
256  /**
257   * @brief The set of processors owned by this scheduler instance.
258   */
259  Processor_mask Processors;
260#endif
261} Scheduler_Context;
262
263/**
264 * @brief Scheduler control.
265 */
266struct _Scheduler_Control {
267  /**
268   * @brief Reference to a statically allocated scheduler context.
269   */
270  Scheduler_Context *context;
271
272  /**
273   * @brief The scheduler operations.
274   */
275  Scheduler_Operations Operations;
276
277  /**
278   * @brief The maximum priority value of this scheduler.
279   *
280   * It defines the lowest (least important) thread priority for this
281   * scheduler.  For example the idle threads have this priority.
282   */
283  Priority_Control maximum_priority;
284
285  /**
286   * @brief The scheduler name.
287   */
288  uint32_t name;
289};
290
291/**
292 * @brief Registered schedulers.
293 *
294 * Application provided via <rtems/confdefs.h>.
295 *
296 * @see _Scheduler_Count.
297 */
298extern const Scheduler_Control _Scheduler_Table[];
299
300/**
301 * @brief Count of registered schedulers.
302 *
303 * Application provided via <rtems/confdefs.h> on SMP configurations.
304 *
305 * It is very important that this is a compile-time constant on uni-processor
306 * configurations (in this case RTEMS_SMP is not defined) so that the compiler
307 * can optimize the some loops away
308 *
309 * @see _Scheduler_Table.
310 */
311#if defined(RTEMS_SMP)
312  extern const size_t _Scheduler_Count;
313#else
314  #define _Scheduler_Count ( (size_t) 1 )
315#endif
316
317#if defined(RTEMS_SMP)
318  /**
319   * @brief The scheduler assignment default attributes.
320   */
321  #define SCHEDULER_ASSIGN_DEFAULT UINT32_C(0x0)
322
323  /**
324   * @brief The presence of this processor is optional.
325   */
326  #define SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL SCHEDULER_ASSIGN_DEFAULT
327
328  /**
329   * @brief The presence of this processor is mandatory.
330   */
331  #define SCHEDULER_ASSIGN_PROCESSOR_MANDATORY UINT32_C(0x1)
332
333  /**
334   * @brief Scheduler assignment.
335   */
336  typedef struct {
337    /**
338     * @brief The scheduler for this processor.
339     */
340    const Scheduler_Control *scheduler;
341
342    /**
343     * @brief The scheduler assignment attributes.
344     *
345     * Use @ref SCHEDULER_ASSIGN_DEFAULT to select default attributes.
346     *
347     * The presence of a processor can be
348     * - @ref SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL, or
349     * - @ref SCHEDULER_ASSIGN_PROCESSOR_MANDATORY.
350     */
351    uint32_t attributes;
352  } Scheduler_Assignment;
353
354  /**
355   * @brief The scheduler assignments.
356   *
357   * The length of this array must be equal to the maximum processors.
358   *
359   * Application provided via <rtems/confdefs.h>.
360   *
361   * @see _Scheduler_Table and rtems_configuration_get_maximum_processors().
362   */
363  extern const Scheduler_Assignment _Scheduler_Initial_assignments[];
364#endif
365
366/**
367 * @brief Returns the scheduler internal thread priority mapped by
368 * SCHEDULER_PRIORITY_MAP().
369 *
370 * @param[in] scheduler Unused.
371 * @param[in] priority The user visible thread priority.
372 *
373 * @return priority The scheduler internal thread priority.
374 */
375Priority_Control _Scheduler_default_Map_priority(
376  const Scheduler_Control *scheduler,
377  Priority_Control         priority
378);
379
380/**
381 * @brief Returns the user visible thread priority unmapped by
382 * SCHEDULER_PRIORITY_UNMAP().
383 *
384 * @param[in] scheduler Unused.
385 * @param[in] priority The scheduler internal thread priority.
386 *
387 * @return priority The user visible thread priority.
388 */
389Priority_Control _Scheduler_default_Unmap_priority(
390  const Scheduler_Control *scheduler,
391  Priority_Control         priority
392);
393
394#if defined(RTEMS_SMP)
395  /**
396   * @brief Does nothing.
397   *
398   * @param[in] scheduler Unused.
399   * @param[in] the_thread Unused.
400   * @param[in] node Unused.
401   *
402   * @retval false Always.
403   */
404  bool _Scheduler_default_Ask_for_help(
405    const Scheduler_Control *scheduler,
406    Thread_Control          *the_thread,
407    Scheduler_Node          *node
408  );
409
410  /**
411   * @brief Does nothing.
412   *
413   * @param[in] scheduler Unused.
414   * @param[in] the_thread Unused.
415   * @param[in] node Unused.
416   */
417  void _Scheduler_default_Reconsider_help_request(
418    const Scheduler_Control *scheduler,
419    Thread_Control          *the_thread,
420    Scheduler_Node          *node
421  );
422
423  /**
424   * @brief Does nothing.
425   *
426   * @param[in] scheduler Unused.
427   * @param[in] the_thread Unused.
428   * @param[in] node Unused.
429   * @param[in] next_state Unused.
430   */
431  void _Scheduler_default_Withdraw_node(
432    const Scheduler_Control *scheduler,
433    Thread_Control          *the_thread,
434    Scheduler_Node          *node,
435    Thread_Scheduler_state   next_state
436  );
437
438  /**
439   * @brief Does nothing in a single processor system, otherwise a fatal error
440   * is issued.
441   *
442   * @param[in] scheduler Unused.
443   * @param[in] the_thread Unused.
444   * @param[in] node Unused.
445   * @param[in] cpu Unused.
446   */
447  void _Scheduler_default_Pin_or_unpin(
448    const Scheduler_Control *scheduler,
449    Thread_Control          *the_thread,
450    Scheduler_Node          *node,
451    struct Per_CPU_Control  *cpu
452  );
453
454  #define SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
455    _Scheduler_default_Ask_for_help, \
456    _Scheduler_default_Reconsider_help_request, \
457    _Scheduler_default_Withdraw_node, \
458    _Scheduler_default_Pin_or_unpin, \
459    _Scheduler_default_Pin_or_unpin, \
460    NULL, \
461    NULL,
462#else
463  #define SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP
464#endif
465
466/**
467 * @brief Does nothing.
468 *
469 * @param[in] scheduler Unused.
470 * @param[in] the_thread Unused.
471 */
472void _Scheduler_default_Schedule(
473  const Scheduler_Control *scheduler,
474  Thread_Control          *the_thread
475);
476
477/**
478 * @brief Performs the scheduler base node initialization.
479 *
480 * @param[in] scheduler Unused.
481 * @param[in] node The node to initialize.
482 * @param[in] the_thread Unused.
483 * @param[in] priority The thread priority.
484 */
485void _Scheduler_default_Node_initialize(
486  const Scheduler_Control *scheduler,
487  Scheduler_Node          *node,
488  Thread_Control          *the_thread,
489  Priority_Control         priority
490);
491
492/**
493 * @brief Does nothing.
494 *
495 * @param[in] scheduler Unused.
496 * @param[in] node Unused.
497 */
498void _Scheduler_default_Node_destroy(
499  const Scheduler_Control *scheduler,
500  Scheduler_Node          *node
501);
502
503/**
504 * @brief Does nothing.
505 *
506 * @param[in] scheduler Unused.
507 * @param[in] the_thread Unused.
508 * @param[in] priority_node Unused.
509 * @param[in] deadline Unused.
510 * @param[in] queue_context Unused.
511 *
512 * @retval NULL Always.
513 */
514void _Scheduler_default_Release_job(
515  const Scheduler_Control *scheduler,
516  Thread_Control          *the_thread,
517  Priority_Node           *priority_node,
518  uint64_t                 deadline,
519  Thread_queue_Context    *queue_context
520);
521
522/**
523 * @brief Does nothing.
524 *
525 * @param[in] scheduler Unused.
526 * @param[in] the_thread Unused.
527 * @param[in] priority_node Unused.
528 * @param[in] queue_context Unused.
529 *
530 * @retval NULL Always.
531 */
532void _Scheduler_default_Cancel_job(
533  const Scheduler_Control *scheduler,
534  Thread_Control          *the_thread,
535  Priority_Node           *priority_node,
536  Thread_queue_Context    *queue_context
537);
538
539/**
540 * @brief Performs tick operations depending on the CPU budget algorithm for
541 * each executing thread.
542 *
543 * This routine is invoked as part of processing each clock tick.
544 *
545 * @param[in] scheduler The scheduler.
546 * @param[in] executing An executing thread.
547 */
548void _Scheduler_default_Tick(
549  const Scheduler_Control *scheduler,
550  Thread_Control          *executing
551);
552
553/**
554 * @brief Starts an idle thread.
555 *
556 * @param[in] scheduler The scheduler.
557 * @param[in] the_thread An idle thread.
558 * @param[in] cpu This parameter is unused.
559 */
560void _Scheduler_default_Start_idle(
561  const Scheduler_Control *scheduler,
562  Thread_Control          *the_thread,
563  struct Per_CPU_Control  *cpu
564);
565
566#if defined(RTEMS_SMP)
567  /**
568   * @brief Default implementation of the set affinity scheduler operation.
569   *
570   * @param[in] scheduler The scheduler instance.
571   * @param[in] thread The associated thread.
572   * @param[in] node The home scheduler node of the associated thread.
573   * @param[in] affinity The new processor affinity set for the thread.
574   *
575   * @retval true The processor set of the scheduler is a subset of the affinity set.
576   * @retval false Otherwise.
577   */
578  bool _Scheduler_default_Set_affinity(
579    const Scheduler_Control *scheduler,
580    Thread_Control          *thread,
581    Scheduler_Node          *node,
582    const Processor_mask    *affinity
583  );
584
585  #define SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY \
586    , _Scheduler_default_Set_affinity
587#else
588  #define SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY
589#endif
590
591/**
592 * @brief This defines the lowest (least important) thread priority of the
593 * first scheduler instance.
594 */
595#define PRIORITY_MAXIMUM ( _Scheduler_Table[ 0 ].maximum_priority )
596
597/**@}*/
598
599#ifdef __cplusplus
600}
601#endif
602
603#endif
604/* end of include file */
Note: See TracBrowser for help on using the repository browser.