source: rtems/cpukit/score/src/schedulerstrongapa.c @ 300f6a48

5
Last change on this file since 300f6a48 was 300f6a48, checked in by Sebastian Huber <sebastian.huber@…>, on 06/22/16 at 15:09:23

score: Rework thread priority management

Add priority nodes which contribute to the overall thread priority.

The actual priority of a thread is now an aggregation of priority nodes.
The thread priority aggregation for the home scheduler instance of a
thread consists of at least one priority node, which is normally the
real priority of the thread. The locking protocols (e.g. priority
ceiling and priority inheritance), rate-monotonic period objects and the
POSIX sporadic server add, change and remove priority nodes.

A thread changes its priority now immediately, e.g. priority changes are
not deferred until the thread releases its last resource.

Replace the _Thread_Change_priority() function with

  • _Thread_Priority_perform_actions(),
  • _Thread_Priority_add(),
  • _Thread_Priority_remove(),
  • _Thread_Priority_change(), and
  • _Thread_Priority_update().

Update #2412.
Update #2556.

  • Property mode set to 100644
File size: 9.9 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ScoreSchedulerStrongAPA
5 *
6 * @brief Strong APA Scheduler Implementation
7 */
8
9/*
10 * Copyright (c) 2013, 2016 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/schedulerstrongapa.h>
28#include <rtems/score/schedulerpriorityimpl.h>
29#include <rtems/score/schedulersmpimpl.h>
30
31static Scheduler_strong_APA_Context *_Scheduler_strong_APA_Get_self(
32  Scheduler_Context *context
33)
34{
35  return (Scheduler_strong_APA_Context *) context;
36}
37
38static Scheduler_strong_APA_Node *
39_Scheduler_strong_APA_Node_downcast( Scheduler_Node *node )
40{
41  return (Scheduler_strong_APA_Node *) node;
42}
43
44static void _Scheduler_strong_APA_Move_from_scheduled_to_ready(
45  Scheduler_Context *context,
46  Scheduler_Node    *scheduled_to_ready
47)
48{
49  Scheduler_strong_APA_Context *self =
50    _Scheduler_strong_APA_Get_self( context );
51  Scheduler_strong_APA_Node *node =
52    _Scheduler_strong_APA_Node_downcast( scheduled_to_ready );
53
54  _Chain_Extract_unprotected( &node->Base.Base.Node );
55  _Scheduler_priority_Ready_queue_enqueue_first(
56    &node->Base.Base.Node,
57    &node->Ready_queue,
58    &self->Bit_map
59  );
60}
61
62static void _Scheduler_strong_APA_Move_from_ready_to_scheduled(
63  Scheduler_Context *context,
64  Scheduler_Node    *ready_to_scheduled
65)
66{
67  Scheduler_strong_APA_Context *self =
68    _Scheduler_strong_APA_Get_self( context );
69  Scheduler_strong_APA_Node *node =
70    _Scheduler_strong_APA_Node_downcast( ready_to_scheduled );
71
72  _Scheduler_priority_Ready_queue_extract(
73    &node->Base.Base.Node,
74    &node->Ready_queue,
75    &self->Bit_map
76  );
77  _Chain_Insert_ordered_unprotected(
78    &self->Base.Scheduled,
79    &node->Base.Base.Node,
80    _Scheduler_SMP_Insert_priority_fifo_order
81  );
82}
83
84static void _Scheduler_strong_APA_Insert_ready_lifo(
85  Scheduler_Context *context,
86  Scheduler_Node    *the_thread
87)
88{
89  Scheduler_strong_APA_Context *self =
90    _Scheduler_strong_APA_Get_self( context );
91  Scheduler_strong_APA_Node *node =
92    _Scheduler_strong_APA_Node_downcast( the_thread );
93
94  _Scheduler_priority_Ready_queue_enqueue(
95    &node->Base.Base.Node,
96    &node->Ready_queue,
97    &self->Bit_map
98  );
99}
100
101static void _Scheduler_strong_APA_Insert_ready_fifo(
102  Scheduler_Context *context,
103  Scheduler_Node    *the_thread
104)
105{
106  Scheduler_strong_APA_Context *self =
107    _Scheduler_strong_APA_Get_self( context );
108  Scheduler_strong_APA_Node *node =
109    _Scheduler_strong_APA_Node_downcast( the_thread );
110
111  _Scheduler_priority_Ready_queue_enqueue_first(
112    &node->Base.Base.Node,
113    &node->Ready_queue,
114    &self->Bit_map
115  );
116}
117
118static void _Scheduler_strong_APA_Extract_from_ready(
119  Scheduler_Context *context,
120  Scheduler_Node    *the_thread
121)
122{
123  Scheduler_strong_APA_Context *self =
124    _Scheduler_strong_APA_Get_self( context );
125  Scheduler_strong_APA_Node *node =
126    _Scheduler_strong_APA_Node_downcast( the_thread );
127
128  _Scheduler_priority_Ready_queue_extract(
129    &node->Base.Base.Node,
130    &node->Ready_queue,
131    &self->Bit_map
132  );
133}
134
135static void _Scheduler_strong_APA_Do_update(
136  Scheduler_Context *context,
137  Scheduler_Node *node_to_update,
138  Priority_Control new_priority
139)
140{
141  Scheduler_strong_APA_Context *self =
142    _Scheduler_strong_APA_Get_self( context );
143  Scheduler_strong_APA_Node *node =
144    _Scheduler_strong_APA_Node_downcast( node_to_update );
145
146  _Scheduler_SMP_Node_update_priority( &node->Base, new_priority );
147  _Scheduler_priority_Ready_queue_update(
148    &node->Ready_queue,
149    new_priority,
150    &self->Bit_map,
151    &self->Ready[ 0 ]
152  );
153}
154
155static Scheduler_strong_APA_Context *
156_Scheduler_strong_APA_Get_context( const Scheduler_Control *scheduler )
157{
158  return (Scheduler_strong_APA_Context *) _Scheduler_Get_context( scheduler );
159}
160
161void _Scheduler_strong_APA_Initialize( const Scheduler_Control *scheduler )
162{
163  Scheduler_strong_APA_Context *self =
164    _Scheduler_strong_APA_Get_context( scheduler );
165
166  _Scheduler_SMP_Initialize( &self->Base );
167  _Priority_bit_map_Initialize( &self->Bit_map );
168  _Scheduler_priority_Ready_queue_initialize(
169    &self->Ready[ 0 ],
170    scheduler->maximum_priority
171  );
172}
173
174void _Scheduler_strong_APA_Node_initialize(
175  const Scheduler_Control *scheduler,
176  Scheduler_Node          *node,
177  Thread_Control          *the_thread,
178  Priority_Control         priority
179)
180{
181  Scheduler_Context            *context;
182  Scheduler_strong_APA_Context *self;
183  Scheduler_strong_APA_Node    *the_node;
184
185  the_node = _Scheduler_strong_APA_Node_downcast( node );
186  _Scheduler_SMP_Node_initialize(
187    scheduler,
188    &the_node->Base,
189    the_thread,
190    priority
191  );
192
193  context = _Scheduler_Get_context( scheduler );
194  self = _Scheduler_strong_APA_Get_self( context );
195  _Scheduler_priority_Ready_queue_update(
196    &the_node->Ready_queue,
197    priority,
198    &self->Bit_map,
199    &self->Ready[ 0 ]
200  );
201}
202
203static Scheduler_Node *_Scheduler_strong_APA_Get_highest_ready(
204  Scheduler_Context *context,
205  Scheduler_Node    *node
206)
207{
208  Scheduler_strong_APA_Context *self =
209    _Scheduler_strong_APA_Get_self( context );
210
211  (void) node;
212
213  return (Scheduler_Node *) _Scheduler_priority_Ready_queue_first(
214    &self->Bit_map,
215    &self->Ready[ 0 ]
216  );
217}
218
219void _Scheduler_strong_APA_Block(
220  const Scheduler_Control *scheduler,
221  Thread_Control          *the_thread
222)
223{
224  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
225
226  _Scheduler_SMP_Block(
227    context,
228    the_thread,
229    _Scheduler_strong_APA_Extract_from_ready,
230    _Scheduler_strong_APA_Get_highest_ready,
231    _Scheduler_strong_APA_Move_from_ready_to_scheduled,
232    _Scheduler_SMP_Allocate_processor_exact
233  );
234}
235
236static Thread_Control *_Scheduler_strong_APA_Enqueue_ordered(
237  Scheduler_Context    *context,
238  Scheduler_Node       *node,
239  Thread_Control       *needs_help,
240  Chain_Node_order      order,
241  Scheduler_SMP_Insert  insert_ready,
242  Scheduler_SMP_Insert  insert_scheduled
243)
244{
245  return _Scheduler_SMP_Enqueue_ordered(
246    context,
247    node,
248    needs_help,
249    order,
250    insert_ready,
251    insert_scheduled,
252    _Scheduler_strong_APA_Move_from_scheduled_to_ready,
253    _Scheduler_SMP_Get_lowest_scheduled,
254    _Scheduler_SMP_Allocate_processor_exact
255  );
256}
257
258static Thread_Control *_Scheduler_strong_APA_Enqueue_lifo(
259  Scheduler_Context *context,
260  Scheduler_Node    *node,
261  Thread_Control    *needs_help
262)
263{
264  return _Scheduler_strong_APA_Enqueue_ordered(
265    context,
266    node,
267    needs_help,
268    _Scheduler_SMP_Insert_priority_lifo_order,
269    _Scheduler_strong_APA_Insert_ready_lifo,
270    _Scheduler_SMP_Insert_scheduled_lifo
271  );
272}
273
274static Thread_Control *_Scheduler_strong_APA_Enqueue_fifo(
275  Scheduler_Context *context,
276  Scheduler_Node    *node,
277  Thread_Control    *needs_help
278)
279{
280  return _Scheduler_strong_APA_Enqueue_ordered(
281    context,
282    node,
283    needs_help,
284    _Scheduler_SMP_Insert_priority_fifo_order,
285    _Scheduler_strong_APA_Insert_ready_fifo,
286    _Scheduler_SMP_Insert_scheduled_fifo
287  );
288}
289
290static Thread_Control *_Scheduler_strong_APA_Enqueue_scheduled_ordered(
291  Scheduler_Context    *context,
292  Scheduler_Node       *node,
293  Chain_Node_order      order,
294  Scheduler_SMP_Insert  insert_ready,
295  Scheduler_SMP_Insert  insert_scheduled
296)
297{
298  return _Scheduler_SMP_Enqueue_scheduled_ordered(
299    context,
300    node,
301    order,
302    _Scheduler_strong_APA_Extract_from_ready,
303    _Scheduler_strong_APA_Get_highest_ready,
304    insert_ready,
305    insert_scheduled,
306    _Scheduler_strong_APA_Move_from_ready_to_scheduled,
307    _Scheduler_SMP_Allocate_processor_exact
308  );
309}
310
311static Thread_Control *_Scheduler_strong_APA_Enqueue_scheduled_lifo(
312  Scheduler_Context *context,
313  Scheduler_Node    *node
314)
315{
316  return _Scheduler_strong_APA_Enqueue_scheduled_ordered(
317    context,
318    node,
319    _Scheduler_SMP_Insert_priority_lifo_order,
320    _Scheduler_strong_APA_Insert_ready_lifo,
321    _Scheduler_SMP_Insert_scheduled_lifo
322  );
323}
324
325static Thread_Control *_Scheduler_strong_APA_Enqueue_scheduled_fifo(
326  Scheduler_Context *context,
327  Scheduler_Node    *node
328)
329{
330  return _Scheduler_strong_APA_Enqueue_scheduled_ordered(
331    context,
332    node,
333    _Scheduler_SMP_Insert_priority_fifo_order,
334    _Scheduler_strong_APA_Insert_ready_fifo,
335    _Scheduler_SMP_Insert_scheduled_fifo
336  );
337}
338
339Thread_Control *_Scheduler_strong_APA_Unblock(
340  const Scheduler_Control *scheduler,
341  Thread_Control          *the_thread
342)
343{
344  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
345
346  return _Scheduler_SMP_Unblock(
347    context,
348    the_thread,
349    _Scheduler_strong_APA_Do_update,
350    _Scheduler_strong_APA_Enqueue_fifo
351  );
352}
353
354Thread_Control *_Scheduler_strong_APA_Update_priority(
355  const Scheduler_Control *scheduler,
356  Thread_Control          *the_thread
357)
358{
359  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
360
361  return _Scheduler_SMP_Update_priority(
362    context,
363    the_thread,
364    _Scheduler_strong_APA_Extract_from_ready,
365    _Scheduler_strong_APA_Do_update,
366    _Scheduler_strong_APA_Enqueue_fifo,
367    _Scheduler_strong_APA_Enqueue_lifo,
368    _Scheduler_strong_APA_Enqueue_scheduled_fifo,
369    _Scheduler_strong_APA_Enqueue_scheduled_lifo
370  );
371}
372
373Thread_Control *_Scheduler_strong_APA_Ask_for_help(
374  const Scheduler_Control *scheduler,
375  Thread_Control          *offers_help,
376  Thread_Control          *needs_help
377)
378{
379  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
380
381  return _Scheduler_SMP_Ask_for_help(
382    context,
383    offers_help,
384    needs_help,
385    _Scheduler_strong_APA_Enqueue_fifo
386  );
387}
388
389Thread_Control *_Scheduler_strong_APA_Yield(
390  const Scheduler_Control *scheduler,
391  Thread_Control          *the_thread
392)
393{
394  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
395
396  return _Scheduler_SMP_Yield(
397    context,
398    the_thread,
399    _Scheduler_strong_APA_Extract_from_ready,
400    _Scheduler_strong_APA_Enqueue_fifo,
401    _Scheduler_strong_APA_Enqueue_scheduled_fifo
402  );
403}
Note: See TracBrowser for help on using the repository browser.