source: rtems/cpukit/score/src/schedulerprioritysmp.c @ 9bfad8c

5
Last change on this file since 9bfad8c was 9bfad8c, checked in by Sebastian Huber <sebastian.huber@…>, on 06/08/16 at 20:22:46

score: Add thread priority to scheduler nodes

The thread priority is manifest in two independent areas. One area is
the user visible thread priority along with a potential thread queue.
The other is the scheduler. Currently, a thread priority update via
_Thread_Change_priority() first updates the user visble thread priority
and the thread queue, then the scheduler is notified if necessary. The
priority is passed to the scheduler via a local variable. A generation
counter ensures that the scheduler discards out-of-date priorities.

This use of a local variable ties the update in these two areas close
together. For later enhancements and the OMIP locking protocol
implementation we need more flexibility. Add a thread priority
information block to Scheduler_Node and synchronize priority value
updates via a sequence lock on SMP configurations.

Update #2556.

  • Property mode set to 100644
File size: 6.7 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ScoreSchedulerPrioritySMP
5 *
6 * @brief Deterministic Priority SMP Scheduler Implementation
7 */
8
9/*
10 * Copyright (c) 2013-2014 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#if HAVE_CONFIG_H
24  #include "config.h"
25#endif
26
27#include <rtems/score/schedulerprioritysmpimpl.h>
28
29static Scheduler_priority_SMP_Context *
30_Scheduler_priority_SMP_Get_context( const Scheduler_Control *scheduler )
31{
32  return (Scheduler_priority_SMP_Context *) _Scheduler_Get_context( scheduler );
33}
34
35void _Scheduler_priority_SMP_Initialize( const Scheduler_Control *scheduler )
36{
37  Scheduler_priority_SMP_Context *self =
38    _Scheduler_priority_SMP_Get_context( scheduler );
39
40  _Scheduler_SMP_Initialize( &self->Base );
41  _Priority_bit_map_Initialize( &self->Bit_map );
42  _Scheduler_priority_Ready_queue_initialize(
43    &self->Ready[ 0 ],
44    scheduler->maximum_priority
45  );
46}
47
48void _Scheduler_priority_SMP_Node_initialize(
49  const Scheduler_Control *scheduler,
50  Thread_Control          *the_thread,
51  Priority_Control         priority
52)
53{
54  Scheduler_Context              *context;
55  Scheduler_priority_SMP_Context *self;
56  Scheduler_priority_SMP_Node    *node;
57
58  context = _Scheduler_Get_context( scheduler );
59  self = _Scheduler_priority_SMP_Get_self( context );
60  node = _Scheduler_priority_SMP_Node_downcast(
61    _Scheduler_Thread_get_own_node( the_thread )
62  );
63
64  _Scheduler_SMP_Node_initialize( &node->Base, the_thread, priority );
65  _Scheduler_priority_Ready_queue_update(
66    &node->Ready_queue,
67    priority,
68    &self->Bit_map,
69    &self->Ready[ 0 ]
70  );
71}
72
73static Scheduler_Node *_Scheduler_priority_SMP_Get_highest_ready(
74  Scheduler_Context *context,
75  Scheduler_Node    *node
76)
77{
78  Scheduler_priority_SMP_Context *self =
79    _Scheduler_priority_SMP_Get_self( context );
80
81  (void) node;
82
83  return (Scheduler_Node *) _Scheduler_priority_Ready_queue_first(
84    &self->Bit_map,
85    &self->Ready[ 0 ]
86  );
87}
88
89void _Scheduler_priority_SMP_Block(
90  const Scheduler_Control *scheduler,
91  Thread_Control *thread
92)
93{
94  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
95
96  _Scheduler_SMP_Block(
97    context,
98    thread,
99    _Scheduler_priority_SMP_Extract_from_ready,
100    _Scheduler_priority_SMP_Get_highest_ready,
101    _Scheduler_priority_SMP_Move_from_ready_to_scheduled,
102    _Scheduler_SMP_Allocate_processor_lazy
103  );
104}
105
106static Thread_Control *_Scheduler_priority_SMP_Enqueue_ordered(
107  Scheduler_Context    *context,
108  Scheduler_Node       *node,
109  Thread_Control       *needs_help,
110  Chain_Node_order      order,
111  Scheduler_SMP_Insert  insert_ready,
112  Scheduler_SMP_Insert  insert_scheduled
113)
114{
115  return _Scheduler_SMP_Enqueue_ordered(
116    context,
117    node,
118    needs_help,
119    order,
120    insert_ready,
121    insert_scheduled,
122    _Scheduler_priority_SMP_Move_from_scheduled_to_ready,
123    _Scheduler_SMP_Get_lowest_scheduled,
124    _Scheduler_SMP_Allocate_processor_lazy
125  );
126}
127
128static Thread_Control *_Scheduler_priority_SMP_Enqueue_lifo(
129  Scheduler_Context *context,
130  Scheduler_Node    *node,
131  Thread_Control    *needs_help
132)
133{
134  return _Scheduler_priority_SMP_Enqueue_ordered(
135    context,
136    node,
137    needs_help,
138    _Scheduler_SMP_Insert_priority_lifo_order,
139    _Scheduler_priority_SMP_Insert_ready_lifo,
140    _Scheduler_SMP_Insert_scheduled_lifo
141  );
142}
143
144static Thread_Control *_Scheduler_priority_SMP_Enqueue_fifo(
145  Scheduler_Context *context,
146  Scheduler_Node    *node,
147  Thread_Control    *needs_help
148)
149{
150  return _Scheduler_priority_SMP_Enqueue_ordered(
151    context,
152    node,
153    needs_help,
154    _Scheduler_SMP_Insert_priority_fifo_order,
155    _Scheduler_priority_SMP_Insert_ready_fifo,
156    _Scheduler_SMP_Insert_scheduled_fifo
157  );
158}
159
160static Thread_Control *_Scheduler_priority_SMP_Enqueue_scheduled_ordered(
161  Scheduler_Context *context,
162  Scheduler_Node *node,
163  Chain_Node_order order,
164  Scheduler_SMP_Insert insert_ready,
165  Scheduler_SMP_Insert insert_scheduled
166)
167{
168  return _Scheduler_SMP_Enqueue_scheduled_ordered(
169    context,
170    node,
171    order,
172    _Scheduler_priority_SMP_Extract_from_ready,
173    _Scheduler_priority_SMP_Get_highest_ready,
174    insert_ready,
175    insert_scheduled,
176    _Scheduler_priority_SMP_Move_from_ready_to_scheduled,
177    _Scheduler_SMP_Allocate_processor_lazy
178  );
179}
180
181static Thread_Control *_Scheduler_priority_SMP_Enqueue_scheduled_lifo(
182  Scheduler_Context *context,
183  Scheduler_Node *node
184)
185{
186  return _Scheduler_priority_SMP_Enqueue_scheduled_ordered(
187    context,
188    node,
189    _Scheduler_SMP_Insert_priority_lifo_order,
190    _Scheduler_priority_SMP_Insert_ready_lifo,
191    _Scheduler_SMP_Insert_scheduled_lifo
192  );
193}
194
195static Thread_Control *_Scheduler_priority_SMP_Enqueue_scheduled_fifo(
196  Scheduler_Context *context,
197  Scheduler_Node *node
198)
199{
200  return _Scheduler_priority_SMP_Enqueue_scheduled_ordered(
201    context,
202    node,
203    _Scheduler_SMP_Insert_priority_fifo_order,
204    _Scheduler_priority_SMP_Insert_ready_fifo,
205    _Scheduler_SMP_Insert_scheduled_fifo
206  );
207}
208
209Thread_Control *_Scheduler_priority_SMP_Unblock(
210  const Scheduler_Control *scheduler,
211  Thread_Control *thread
212)
213{
214  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
215
216  return _Scheduler_SMP_Unblock(
217    context,
218    thread,
219    _Scheduler_priority_SMP_Do_update,
220    _Scheduler_priority_SMP_Enqueue_fifo
221  );
222}
223
224Thread_Control *_Scheduler_priority_SMP_Update_priority(
225  const Scheduler_Control *scheduler,
226  Thread_Control          *thread
227)
228{
229  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
230
231  return _Scheduler_SMP_Update_priority(
232    context,
233    thread,
234    _Scheduler_priority_SMP_Extract_from_ready,
235    _Scheduler_priority_SMP_Do_update,
236    _Scheduler_priority_SMP_Enqueue_fifo,
237    _Scheduler_priority_SMP_Enqueue_lifo,
238    _Scheduler_priority_SMP_Enqueue_scheduled_fifo,
239    _Scheduler_priority_SMP_Enqueue_scheduled_lifo
240  );
241}
242
243Thread_Control *_Scheduler_priority_SMP_Ask_for_help(
244  const Scheduler_Control *scheduler,
245  Thread_Control          *offers_help,
246  Thread_Control          *needs_help
247)
248{
249  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
250
251  return _Scheduler_SMP_Ask_for_help(
252    context,
253    offers_help,
254    needs_help,
255    _Scheduler_priority_SMP_Enqueue_fifo
256  );
257}
258
259Thread_Control *_Scheduler_priority_SMP_Yield(
260  const Scheduler_Control *scheduler,
261  Thread_Control *thread
262)
263{
264  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
265
266  return _Scheduler_SMP_Yield(
267    context,
268    thread,
269    _Scheduler_priority_SMP_Extract_from_ready,
270    _Scheduler_priority_SMP_Enqueue_fifo,
271    _Scheduler_priority_SMP_Enqueue_scheduled_fifo
272  );
273}
Note: See TracBrowser for help on using the repository browser.