source: rtems/cpukit/score/src/schedulerprioritysmp.c @ 2afb22b

5
Last change on this file since 2afb22b was c597fb1, checked in by Sebastian Huber <sebastian.huber@…>, on 11/09/17 at 15:21:37

score: Optimize scheduler priority updates

Thread priority changes may append or prepend the thread to its priority
group on the scheduler ready queue. Previously, a separate priority
value and a prepend-it flag in the scheduler node were used to propagate
a priority change to the scheduler.

Now, use an append-it bit in the priority control and reduce the plain
priority value to 63 bits.

This change leads to a significant code size reduction (about 25%) of
the SMP schedulers. The negligible increase of the standard priority
scheduler is due to some additional shift operations
(SCHEDULER_PRIORITY_MAP() and SCHEDULER_PRIORITY_UNMAP()).

Before:

text filename

136 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimpleblock.o
464 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimplechangepriority.o

24 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimple.o

108 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimpleschedule.o
292 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimpleunblock.o
264 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimpleyield.o

text filename

280 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriorityblock.o
488 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerprioritychangepriority.o
200 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriority.o
164 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriorityschedule.o
328 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriorityunblock.o
200 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriorityyield.o

text filename

24112 arm-rtems5/c/imx7/cpukit/score/src/libscore_a-scheduleredfsmp.o

text filename

37204 sparc-rtems5/c/gr740/cpukit/score/src/libscore_a-scheduleredfsmp.o

text filename

42236 powerpc-rtems5/c/qoriq_e6500_32/cpukit/score/src/libscore_a-scheduleredfsmp.o

After:

text filename

136 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimpleblock.o
272 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimplechangepriority.o

24 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimple.o

108 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimpleschedule.o
292 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimpleunblock.o
264 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulersimpleyield.o

text filename

280 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriorityblock.o
488 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerprioritychangepriority.o
208 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriority.o
164 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriorityschedule.o
332 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriorityunblock.o
200 sparc-rtems5/c/erc32/cpukit/score/src/libscore_a-schedulerpriorityyield.o

text filename

18860 arm-rtems5/c/imx7/cpukit/score/src/libscore_a-scheduleredfsmp.o

text filename

28520 sparc-rtems5/c/gr740/cpukit/score/src/libscore_a-scheduleredfsmp.o

text filename

32664 powerpc-rtems5/c/qoriq_e6500_32/cpukit/score/src/libscore_a-scheduleredfsmp.o

  • Property mode set to 100644
File size: 7.4 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  Scheduler_Node          *node,
51  Thread_Control          *the_thread,
52  Priority_Control         priority
53)
54{
55  Scheduler_Context              *context;
56  Scheduler_priority_SMP_Context *self;
57  Scheduler_priority_SMP_Node    *the_node;
58
59  the_node = _Scheduler_priority_SMP_Node_downcast( node );
60  _Scheduler_SMP_Node_initialize(
61    scheduler,
62    &the_node->Base,
63    the_thread,
64    priority
65  );
66
67  context = _Scheduler_Get_context( scheduler );
68  self = _Scheduler_priority_SMP_Get_self( context );
69  _Scheduler_priority_Ready_queue_update(
70    &the_node->Ready_queue,
71    SCHEDULER_PRIORITY_UNMAP( priority ),
72    &self->Bit_map,
73    &self->Ready[ 0 ]
74  );
75}
76
77static Scheduler_Node *_Scheduler_priority_SMP_Get_highest_ready(
78  Scheduler_Context *context,
79  Scheduler_Node    *node
80)
81{
82  Scheduler_priority_SMP_Context *self =
83    _Scheduler_priority_SMP_Get_self( context );
84
85  (void) node;
86
87  return (Scheduler_Node *) _Scheduler_priority_Ready_queue_first(
88    &self->Bit_map,
89    &self->Ready[ 0 ]
90  );
91}
92
93void _Scheduler_priority_SMP_Block(
94  const Scheduler_Control *scheduler,
95  Thread_Control          *thread,
96  Scheduler_Node          *node
97)
98{
99  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
100
101  _Scheduler_SMP_Block(
102    context,
103    thread,
104    node,
105    _Scheduler_priority_SMP_Extract_from_ready,
106    _Scheduler_priority_SMP_Get_highest_ready,
107    _Scheduler_priority_SMP_Move_from_ready_to_scheduled,
108    _Scheduler_SMP_Allocate_processor_lazy
109  );
110}
111
112static bool _Scheduler_priority_SMP_Enqueue(
113  Scheduler_Context *context,
114  Scheduler_Node    *node,
115  Priority_Control   insert_priority
116)
117{
118  return _Scheduler_SMP_Enqueue(
119    context,
120    node,
121    insert_priority,
122    _Scheduler_SMP_Priority_less_equal,
123    _Scheduler_priority_SMP_Insert_ready,
124    _Scheduler_SMP_Insert_scheduled,
125    _Scheduler_priority_SMP_Move_from_scheduled_to_ready,
126    _Scheduler_SMP_Get_lowest_scheduled,
127    _Scheduler_SMP_Allocate_processor_lazy
128  );
129}
130
131static bool _Scheduler_priority_SMP_Enqueue_scheduled(
132  Scheduler_Context *context,
133  Scheduler_Node    *node,
134  Priority_Control   insert_priority
135)
136{
137  return _Scheduler_SMP_Enqueue_scheduled(
138    context,
139    node,
140    insert_priority,
141    _Scheduler_SMP_Priority_less_equal,
142    _Scheduler_priority_SMP_Extract_from_ready,
143    _Scheduler_priority_SMP_Get_highest_ready,
144    _Scheduler_priority_SMP_Insert_ready,
145    _Scheduler_SMP_Insert_scheduled,
146    _Scheduler_priority_SMP_Move_from_ready_to_scheduled,
147    _Scheduler_SMP_Allocate_processor_lazy
148  );
149}
150
151void _Scheduler_priority_SMP_Unblock(
152  const Scheduler_Control *scheduler,
153  Thread_Control          *thread,
154  Scheduler_Node          *node
155)
156{
157  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
158
159  _Scheduler_SMP_Unblock(
160    context,
161    thread,
162    node,
163    _Scheduler_priority_SMP_Do_update,
164    _Scheduler_priority_SMP_Enqueue
165  );
166}
167
168static bool _Scheduler_priority_SMP_Do_ask_for_help(
169  Scheduler_Context *context,
170  Thread_Control    *the_thread,
171  Scheduler_Node    *node
172)
173{
174  return _Scheduler_SMP_Ask_for_help(
175    context,
176    the_thread,
177    node,
178    _Scheduler_SMP_Priority_less_equal,
179    _Scheduler_priority_SMP_Insert_ready,
180    _Scheduler_SMP_Insert_scheduled,
181    _Scheduler_priority_SMP_Move_from_scheduled_to_ready,
182    _Scheduler_SMP_Get_lowest_scheduled,
183    _Scheduler_SMP_Allocate_processor_lazy
184  );
185}
186
187void _Scheduler_priority_SMP_Update_priority(
188  const Scheduler_Control *scheduler,
189  Thread_Control          *thread,
190  Scheduler_Node          *node
191)
192{
193  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
194
195  _Scheduler_SMP_Update_priority(
196    context,
197    thread,
198    node,
199    _Scheduler_priority_SMP_Extract_from_ready,
200    _Scheduler_priority_SMP_Do_update,
201    _Scheduler_priority_SMP_Enqueue,
202    _Scheduler_priority_SMP_Enqueue_scheduled,
203    _Scheduler_priority_SMP_Do_ask_for_help
204  );
205}
206
207bool _Scheduler_priority_SMP_Ask_for_help(
208  const Scheduler_Control *scheduler,
209  Thread_Control          *the_thread,
210  Scheduler_Node          *node
211)
212{
213  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
214
215  return _Scheduler_priority_SMP_Do_ask_for_help( context, the_thread, node );
216}
217
218void _Scheduler_priority_SMP_Reconsider_help_request(
219  const Scheduler_Control *scheduler,
220  Thread_Control          *the_thread,
221  Scheduler_Node          *node
222)
223{
224  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
225
226  _Scheduler_SMP_Reconsider_help_request(
227    context,
228    the_thread,
229    node,
230    _Scheduler_priority_SMP_Extract_from_ready
231  );
232}
233
234void _Scheduler_priority_SMP_Withdraw_node(
235  const Scheduler_Control *scheduler,
236  Thread_Control          *the_thread,
237  Scheduler_Node          *node,
238  Thread_Scheduler_state   next_state
239)
240{
241  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
242
243  _Scheduler_SMP_Withdraw_node(
244    context,
245    the_thread,
246    node,
247    next_state,
248    _Scheduler_priority_SMP_Extract_from_ready,
249    _Scheduler_priority_SMP_Get_highest_ready,
250    _Scheduler_priority_SMP_Move_from_ready_to_scheduled,
251    _Scheduler_SMP_Allocate_processor_lazy
252  );
253}
254
255void _Scheduler_priority_SMP_Add_processor(
256  const Scheduler_Control *scheduler,
257  Thread_Control          *idle
258)
259{
260  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
261
262  _Scheduler_SMP_Add_processor(
263    context,
264    idle,
265    _Scheduler_priority_SMP_Has_ready,
266    _Scheduler_priority_SMP_Enqueue_scheduled,
267    _Scheduler_SMP_Do_nothing_register_idle
268  );
269}
270
271Thread_Control *_Scheduler_priority_SMP_Remove_processor(
272  const Scheduler_Control *scheduler,
273  Per_CPU_Control         *cpu
274)
275{
276  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
277
278  return _Scheduler_SMP_Remove_processor(
279    context,
280    cpu,
281    _Scheduler_priority_SMP_Extract_from_ready,
282    _Scheduler_priority_SMP_Enqueue
283  );
284}
285
286void _Scheduler_priority_SMP_Yield(
287  const Scheduler_Control *scheduler,
288  Thread_Control          *thread,
289  Scheduler_Node          *node
290)
291{
292  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
293
294  _Scheduler_SMP_Yield(
295    context,
296    thread,
297    node,
298    _Scheduler_priority_SMP_Extract_from_ready,
299    _Scheduler_priority_SMP_Enqueue,
300    _Scheduler_priority_SMP_Enqueue_scheduled
301  );
302}
Note: See TracBrowser for help on using the repository browser.