source: rtems/cpukit/score/include/rtems/score/schedulerpriorityimpl.h @ 042072b

5
Last change on this file since 042072b was 042072b, checked in by Sebastian Huber <sebastian.huber@…>, on 06/14/16 at 08:12:34

score: _Scheduler_priority_Ready_queue_initialize

Use priority maximum of scheduler instance. This avoids a potential
memory corruption on SMP configurations.

  • Property mode set to 100644
File size: 6.7 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_Get_context( scheduler );
42}
43
44RTEMS_INLINE_ROUTINE Scheduler_priority_Node *_Scheduler_priority_Thread_get_node(
45  Thread_Control *the_thread
46)
47{
48  return (Scheduler_priority_Node *) _Scheduler_Thread_get_node( 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  Priority_Control  maximum_priority
59)
60{
61  size_t index;
62
63  for ( index = 0 ; index <= (size_t) maximum_priority ; ++index ) {
64    _Chain_Initialize_empty( &ready_queues[ index ] );
65  }
66}
67
68/**
69 * @brief Enqueues a node on the specified ready queue.
70 *
71 * The node is placed as the last element of its priority group.
72 *
73 * @param[in] node The node to enqueue.
74 * @param[in] ready_queue The ready queue.
75 * @param[in] bit_map The priority bit map of the scheduler instance.
76 */
77RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue(
78  Chain_Node                     *node,
79  Scheduler_priority_Ready_queue *ready_queue,
80  Priority_bit_map_Control       *bit_map
81)
82{
83  Chain_Control *ready_chain = ready_queue->ready_chain;
84
85  _Chain_Append_unprotected( ready_chain, node );
86  _Priority_bit_map_Add( bit_map, &ready_queue->Priority_map );
87}
88
89/**
90 * @brief Enqueues a node on the specified ready queue as first.
91 *
92 * The node is placed as the first element of its priority group.
93 *
94 * @param[in] node The node to enqueue as first.
95 * @param[in] ready_queue The ready queue.
96 * @param[in] bit_map The priority bit map of the scheduler instance.
97 */
98RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue_first(
99  Chain_Node                     *node,
100  Scheduler_priority_Ready_queue *ready_queue,
101  Priority_bit_map_Control       *bit_map
102)
103{
104  Chain_Control *ready_chain = ready_queue->ready_chain;
105
106  _Chain_Prepend_unprotected( ready_chain, node );
107  _Priority_bit_map_Add( bit_map, &ready_queue->Priority_map );
108}
109
110/**
111 * @brief Extracts a node from the specified ready queue.
112 *
113 * @param[in] node The node to extract.
114 * @param[in] ready_queue The ready queue.
115 * @param[in] bit_map The priority bit map of the scheduler instance.
116 */
117RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_extract(
118  Chain_Node                     *node,
119  Scheduler_priority_Ready_queue *ready_queue,
120  Priority_bit_map_Control       *bit_map
121)
122{
123  Chain_Control *ready_chain = ready_queue->ready_chain;
124
125  if ( _Chain_Has_only_one_node( ready_chain ) ) {
126    _Chain_Initialize_empty( ready_chain );
127    _Priority_bit_map_Remove( bit_map, &ready_queue->Priority_map );
128  } else {
129    _Chain_Extract_unprotected( node );
130  }
131}
132
133RTEMS_INLINE_ROUTINE void _Scheduler_priority_Extract_body(
134  const Scheduler_Control *scheduler,
135  Thread_Control          *the_thread
136)
137{
138  Scheduler_priority_Context *context =
139    _Scheduler_priority_Get_context( scheduler );
140  Scheduler_priority_Node *node = _Scheduler_priority_Thread_get_node( the_thread );
141
142  _Scheduler_priority_Ready_queue_extract(
143    &the_thread->Object.Node,
144    &node->Ready_queue,
145    &context->Bit_map
146  );
147}
148
149/**
150 * @brief Return a pointer to the first node.
151 *
152 * This routines returns a pointer to the first node on @a ready_queues.
153 *
154 * @param[in] bit_map The priority bit map of the scheduler instance.
155 * @param[in] ready_queues The ready queues of the scheduler instance.
156 *
157 * @return This method returns the first node.
158 */
159RTEMS_INLINE_ROUTINE Chain_Node *_Scheduler_priority_Ready_queue_first(
160  Priority_bit_map_Control *bit_map,
161  Chain_Control            *ready_queues
162)
163{
164  Priority_Control index = _Priority_bit_map_Get_highest( bit_map );
165  Chain_Node *first = _Chain_First( &ready_queues[ index ] );
166
167  _Assert( first != _Chain_Tail( &ready_queues[ index ] ) );
168
169  return first;
170}
171
172/**
173 * @brief Scheduling decision logic.
174 *
175 * This kernel routine implements scheduling decision logic
176 * for priority-based scheduling.
177 */
178RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body(
179  const Scheduler_Control *scheduler,
180  Thread_Control          *the_thread,
181  bool                     force_dispatch
182)
183{
184  Scheduler_priority_Context *context =
185    _Scheduler_priority_Get_context( scheduler );
186  Thread_Control *heir = (Thread_Control *)
187    _Scheduler_priority_Ready_queue_first(
188      &context->Bit_map,
189      &context->Ready[ 0 ]
190    );
191
192  ( void ) the_thread;
193
194  _Scheduler_Update_heir( heir, force_dispatch );
195}
196
197/**
198 * @brief Updates the specified ready queue data according to the new priority
199 * value.
200 *
201 * @param[in] ready_queue The ready queue.
202 * @param[in] new_priority The new priority.
203 * @param[in] bit_map The priority bit map of the scheduler instance.
204 * @param[in] ready_queues The ready queues of the scheduler instance.
205 */
206RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_update(
207  Scheduler_priority_Ready_queue *ready_queue,
208  Priority_Control                new_priority,
209  Priority_bit_map_Control       *bit_map,
210  Chain_Control                  *ready_queues
211)
212{
213  ready_queue->ready_chain = &ready_queues[ new_priority ];
214
215  _Priority_bit_map_Initialize_information(
216    bit_map,
217    &ready_queue->Priority_map,
218    new_priority
219  );
220}
221
222/**
223 * @brief Priority comparison.
224 *
225 * This routine implements priority comparison for priority-based
226 * scheduling.
227 *
228 * @return >0 for higher priority, 0 for equal and <0 for lower priority.
229 */
230RTEMS_INLINE_ROUTINE int _Scheduler_priority_Priority_compare_body(
231  Priority_Control      p1,
232  Priority_Control      p2
233)
234{
235  /* High priority in priority scheduler is represented by low numbers. */
236  return ( p2 - p1 );
237}
238
239/** @} */
240
241#ifdef __cplusplus
242}
243#endif
244
245#endif
246/* end of include file */
Note: See TracBrowser for help on using the repository browser.