source: rtems/cpukit/score/include/rtems/score/schedulerpriorityimpl.h @ beab7329

4.115
Last change on this file since beab7329 was beab7329, checked in by Sebastian Huber <sebastian.huber@…>, on 05/13/14 at 14:03:05

score: Introduce scheduler nodes

Rename scheduler per-thread information into scheduler nodes using
Scheduler_Node as the base type. Use inheritance for specialized
schedulers.

Move the scheduler specific states from the thread control block into
the scheduler node structure.

Validate the SMP scheduler node state transitions in case RTEMS_DEBUG is
defined.

  • Property mode set to 100644
File size: 7.5 KB
Line 
1/**
2 * @file
3 *
4 * @brief Inlined Routines Associated with the Manipulation of the
5 * Priority-Based Scheduling Structures
6 *
7 * This inline file contains all of the inlined routines associated with
8 * the manipulation of the priority-based scheduling structures.
9 */
10
11/*
12 *  Copyright (C) 2010 Gedare Bloom.
13 *  Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
14 *
15 *  The license and distribution terms for this file may be
16 *  found in the file LICENSE in this distribution or at
17 *  http://www.rtems.org/license/LICENSE.
18 */
19
20#ifndef _RTEMS_SCORE_SCHEDULERPRIORITYIMPL_H
21#define _RTEMS_SCORE_SCHEDULERPRIORITYIMPL_H
22
23#include <rtems/score/schedulerpriority.h>
24#include <rtems/score/chainimpl.h>
25#include <rtems/score/prioritybitmapimpl.h>
26#include <rtems/score/schedulerimpl.h>
27#include <rtems/score/thread.h>
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33/**
34 * @addtogroup ScoreSchedulerDPS
35 */
36/**@{**/
37
38RTEMS_INLINE_ROUTINE Scheduler_priority_Context *
39  _Scheduler_priority_Get_context( const Scheduler_Control *scheduler )
40{
41  return (Scheduler_priority_Context *) scheduler->context;
42}
43
44RTEMS_INLINE_ROUTINE Scheduler_priority_Node *_Scheduler_priority_Node_get(
45  Thread_Control *the_thread
46)
47{
48  return (Scheduler_priority_Node *) _Scheduler_Node_get( the_thread );
49}
50
51/**
52 * @brief Ready queue initialization.
53 *
54 * This routine initializes @a ready_queues for priority-based scheduling.
55 */
56RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_initialize(
57  Chain_Control *ready_queues
58)
59{
60  size_t index;
61
62  /* initialize ready queue structures */
63  for( index=0; index <= PRIORITY_MAXIMUM; index++)
64    _Chain_Initialize_empty( &ready_queues[index] );
65}
66
67RTEMS_INLINE_ROUTINE Scheduler_priority_Node *
68_Scheduler_priority_Get_scheduler_info( Thread_Control *thread )
69{
70  return ( Scheduler_priority_Node * ) thread->scheduler_node;
71}
72
73/**
74 * @brief Enqueues a thread on the specified ready queue.
75 *
76 * The thread is placed as the last element of its priority group.
77 *
78 * @param[in] the_thread The thread to enqueue.
79 * @param[in] ready_queue The ready queue.
80 * @param[in] bit_map The priority bit map of the scheduler instance.
81 */
82RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue(
83  Thread_Control                 *the_thread,
84  Scheduler_priority_Ready_queue *ready_queue,
85  Priority_bit_map_Control       *bit_map
86)
87{
88  Chain_Control *ready_chain = ready_queue->ready_chain;
89
90  _Chain_Append_unprotected( ready_chain, &the_thread->Object.Node );
91  _Priority_bit_map_Add( bit_map, &ready_queue->Priority_map );
92}
93
94/**
95 * @brief Enqueues a thread on the specified ready queue as first.
96 *
97 * The thread is placed as the first element of its priority group.
98 *
99 * @param[in] the_thread The thread to enqueue as first.
100 * @param[in] ready_queue The ready queue.
101 * @param[in] bit_map The priority bit map of the scheduler instance.
102 */
103RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue_first(
104  Thread_Control                 *the_thread,
105  Scheduler_priority_Ready_queue *ready_queue,
106  Priority_bit_map_Control       *bit_map
107)
108{
109  Chain_Control *ready_chain = ready_queue->ready_chain;
110
111  _Chain_Prepend_unprotected( ready_chain, &the_thread->Object.Node );
112  _Priority_bit_map_Add( bit_map, &ready_queue->Priority_map );
113}
114
115/**
116 * @brief Extracts a thread from the specified ready queue.
117 *
118 * @param[in] the_thread The thread to extract.
119 * @param[in] ready_queue The ready queue.
120 * @param[in] bit_map The priority bit map of the scheduler instance.
121 */
122RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_extract(
123  Thread_Control                 *the_thread,
124  Scheduler_priority_Ready_queue *ready_queue,
125  Priority_bit_map_Control       *bit_map
126)
127{
128  Chain_Control *ready_chain = ready_queue->ready_chain;
129
130  if ( _Chain_Has_only_one_node( ready_chain ) ) {
131    _Chain_Initialize_empty( ready_chain );
132    _Priority_bit_map_Remove( bit_map, &ready_queue->Priority_map );
133  } else {
134    _Chain_Extract_unprotected( &the_thread->Object.Node );
135  }
136}
137
138RTEMS_INLINE_ROUTINE void _Scheduler_priority_Extract_body(
139  const Scheduler_Control *scheduler,
140  Thread_Control          *the_thread
141)
142{
143  Scheduler_priority_Context *context =
144    _Scheduler_priority_Get_context( scheduler );
145  Scheduler_priority_Node *node = _Scheduler_priority_Node_get( the_thread );
146
147  _Scheduler_priority_Ready_queue_extract(
148    the_thread,
149    &node->Ready_queue,
150    &context->Bit_map
151  );
152}
153
154/**
155 * @brief Return a pointer to the first thread.
156 *
157 * This routines returns a pointer to the first thread on @a ready_queues.
158 *
159 * @param[in] bit_map The priority bit map of the scheduler instance.
160 * @param[in] ready_queues The ready queues of the scheduler instance.
161 *
162 * @return This method returns the first thread or NULL
163 */
164RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_priority_Ready_queue_first(
165  Priority_bit_map_Control *bit_map,
166  Chain_Control            *ready_queues
167)
168{
169  Priority_Control index = _Priority_bit_map_Get_highest( bit_map );
170
171  return (Thread_Control *) _Chain_First( &ready_queues[ index ] );
172}
173
174/**
175 * @brief Requeues a thread on the specified ready queue.
176 *
177 * This routine is invoked when a thread changes priority and should be
178 * moved to a different position on the ready queue.
179 *
180 * @param[in] the_thread The thread to requeue.
181 * @param[in] ready_queue The ready queue.
182 */
183RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_requeue(
184  Thread_Control                 *the_thread,
185  Scheduler_priority_Ready_queue *ready_queue
186)
187{
188  Chain_Control *ready_chain = ready_queue->ready_chain;
189
190  if ( !_Chain_Has_only_one_node( ready_chain ) ) {
191    _Chain_Extract_unprotected( &the_thread->Object.Node );
192    _Chain_Append_unprotected( ready_chain, &the_thread->Object.Node );
193  }
194}
195
196/**
197 * @brief Scheduling decision logic.
198 *
199 * This kernel routine implements scheduling decision logic
200 * for priority-based scheduling.
201 */
202RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body(
203  const Scheduler_Control *scheduler,
204  Thread_Control          *the_thread,
205  bool                     force_dispatch
206)
207{
208  Scheduler_priority_Context *context =
209    _Scheduler_priority_Get_context( scheduler );
210  Thread_Control *heir = _Scheduler_priority_Ready_queue_first(
211    &context->Bit_map,
212    &context->Ready[ 0 ]
213  );
214
215  ( void ) the_thread;
216
217  _Scheduler_Update_heir( heir, force_dispatch );
218}
219
220/**
221 * @brief Updates the specified ready queue data according to the current
222 * priority of the thread.
223 *
224 * @param[in] the_thread The thread.
225 * @param[in] ready_queue The ready queue.
226 * @param[in] bit_map The priority bit map of the scheduler instance.
227 * @param[in] ready_queues The ready queues of the scheduler instance.
228 */
229RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_update(
230  Thread_Control                 *the_thread,
231  Scheduler_priority_Ready_queue *ready_queue,
232  Priority_bit_map_Control       *bit_map,
233  Chain_Control                  *ready_queues
234)
235{
236  Priority_Control priority = the_thread->current_priority;
237  ready_queue->ready_chain = &ready_queues[ priority ];
238
239  _Priority_bit_map_Initialize_information(
240    bit_map,
241    &ready_queue->Priority_map,
242    priority
243  );
244}
245
246/**
247 * @brief Priority comparison.
248 *
249 * This routine implements priority comparison for priority-based
250 * scheduling.
251 *
252 * @return >0 for higher priority, 0 for equal and <0 for lower priority.
253 */
254RTEMS_INLINE_ROUTINE int _Scheduler_priority_Priority_compare_body(
255  Priority_Control      p1,
256  Priority_Control      p2
257)
258{
259  /* High priority in priority scheduler is represented by low numbers. */
260  return ( p2 - p1 );
261}
262
263/** @} */
264
265#ifdef __cplusplus
266}
267#endif
268
269#endif
270/* end of include file */
Note: See TracBrowser for help on using the repository browser.