source: rtems/cpukit/score/src/schedulerstrongapa.c @ 0daa8ab

5
Last change on this file since 0daa8ab was 34487537, checked in by Sebastian Huber <sebastian.huber@…>, on 07/04/17 at 07:57:30

score: Add simple affinity support to EDF SMP

Update #3059.

  • Property mode set to 100644
File size: 12.1 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.Chain );
55  _Scheduler_priority_Ready_queue_enqueue_first(
56    &node->Base.Base.Node.Chain,
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.Chain,
74    &node->Ready_queue,
75    &self->Bit_map
76  );
77  _Chain_Insert_ordered_unprotected(
78    &self->Base.Scheduled,
79    &node->Base.Base.Node.Chain,
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.Chain,
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.Chain,
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.Chain,
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 bool _Scheduler_strong_APA_Has_ready( Scheduler_Context *context )
204{
205  Scheduler_strong_APA_Context *self =
206    _Scheduler_strong_APA_Get_self( context );
207
208  return !_Priority_bit_map_Is_empty( &self->Bit_map );
209}
210
211static Scheduler_Node *_Scheduler_strong_APA_Get_highest_ready(
212  Scheduler_Context *context,
213  Scheduler_Node    *node
214)
215{
216  Scheduler_strong_APA_Context *self =
217    _Scheduler_strong_APA_Get_self( context );
218
219  (void) node;
220
221  return (Scheduler_Node *) _Scheduler_priority_Ready_queue_first(
222    &self->Bit_map,
223    &self->Ready[ 0 ]
224  );
225}
226
227void _Scheduler_strong_APA_Block(
228  const Scheduler_Control *scheduler,
229  Thread_Control          *the_thread,
230  Scheduler_Node          *node
231)
232{
233  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
234
235  _Scheduler_SMP_Block(
236    context,
237    the_thread,
238    node,
239    _Scheduler_strong_APA_Extract_from_ready,
240    _Scheduler_strong_APA_Get_highest_ready,
241    _Scheduler_strong_APA_Move_from_ready_to_scheduled,
242    _Scheduler_SMP_Allocate_processor_exact
243  );
244}
245
246static bool _Scheduler_strong_APA_Enqueue_ordered(
247  Scheduler_Context    *context,
248  Scheduler_Node       *node,
249  Chain_Node_order      order,
250  Scheduler_SMP_Insert  insert_ready,
251  Scheduler_SMP_Insert  insert_scheduled
252)
253{
254  return _Scheduler_SMP_Enqueue_ordered(
255    context,
256    node,
257    order,
258    insert_ready,
259    insert_scheduled,
260    _Scheduler_strong_APA_Move_from_scheduled_to_ready,
261    _Scheduler_SMP_Get_lowest_scheduled,
262    _Scheduler_SMP_Allocate_processor_exact
263  );
264}
265
266static bool _Scheduler_strong_APA_Enqueue_lifo(
267  Scheduler_Context *context,
268  Scheduler_Node    *node
269)
270{
271  return _Scheduler_strong_APA_Enqueue_ordered(
272    context,
273    node,
274    _Scheduler_SMP_Insert_priority_lifo_order,
275    _Scheduler_strong_APA_Insert_ready_lifo,
276    _Scheduler_SMP_Insert_scheduled_lifo
277  );
278}
279
280static bool _Scheduler_strong_APA_Enqueue_fifo(
281  Scheduler_Context *context,
282  Scheduler_Node    *node
283)
284{
285  return _Scheduler_strong_APA_Enqueue_ordered(
286    context,
287    node,
288    _Scheduler_SMP_Insert_priority_fifo_order,
289    _Scheduler_strong_APA_Insert_ready_fifo,
290    _Scheduler_SMP_Insert_scheduled_fifo
291  );
292}
293
294static bool _Scheduler_strong_APA_Enqueue_scheduled_ordered(
295  Scheduler_Context    *context,
296  Scheduler_Node       *node,
297  Chain_Node_order      order,
298  Scheduler_SMP_Insert  insert_ready,
299  Scheduler_SMP_Insert  insert_scheduled
300)
301{
302  return _Scheduler_SMP_Enqueue_scheduled_ordered(
303    context,
304    node,
305    order,
306    _Scheduler_strong_APA_Extract_from_ready,
307    _Scheduler_strong_APA_Get_highest_ready,
308    insert_ready,
309    insert_scheduled,
310    _Scheduler_strong_APA_Move_from_ready_to_scheduled,
311    _Scheduler_SMP_Allocate_processor_exact
312  );
313}
314
315static bool _Scheduler_strong_APA_Enqueue_scheduled_lifo(
316  Scheduler_Context *context,
317  Scheduler_Node    *node
318)
319{
320  return _Scheduler_strong_APA_Enqueue_scheduled_ordered(
321    context,
322    node,
323    _Scheduler_SMP_Insert_priority_lifo_order,
324    _Scheduler_strong_APA_Insert_ready_lifo,
325    _Scheduler_SMP_Insert_scheduled_lifo
326  );
327}
328
329static bool _Scheduler_strong_APA_Enqueue_scheduled_fifo(
330  Scheduler_Context *context,
331  Scheduler_Node    *node
332)
333{
334  return _Scheduler_strong_APA_Enqueue_scheduled_ordered(
335    context,
336    node,
337    _Scheduler_SMP_Insert_priority_fifo_order,
338    _Scheduler_strong_APA_Insert_ready_fifo,
339    _Scheduler_SMP_Insert_scheduled_fifo
340  );
341}
342
343void _Scheduler_strong_APA_Unblock(
344  const Scheduler_Control *scheduler,
345  Thread_Control          *the_thread,
346  Scheduler_Node          *node
347)
348{
349  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
350
351  _Scheduler_SMP_Unblock(
352    context,
353    the_thread,
354    node,
355    _Scheduler_strong_APA_Do_update,
356    _Scheduler_strong_APA_Enqueue_fifo
357  );
358}
359
360static bool _Scheduler_strong_APA_Do_ask_for_help(
361  Scheduler_Context *context,
362  Thread_Control    *the_thread,
363  Scheduler_Node    *node
364)
365{
366  return _Scheduler_SMP_Ask_for_help(
367    context,
368    the_thread,
369    node,
370    _Scheduler_SMP_Insert_priority_lifo_order,
371    _Scheduler_strong_APA_Insert_ready_lifo,
372    _Scheduler_SMP_Insert_scheduled_lifo,
373    _Scheduler_strong_APA_Move_from_scheduled_to_ready,
374    _Scheduler_SMP_Get_lowest_scheduled,
375    _Scheduler_SMP_Allocate_processor_lazy
376  );
377}
378
379void _Scheduler_strong_APA_Update_priority(
380  const Scheduler_Control *scheduler,
381  Thread_Control          *the_thread,
382  Scheduler_Node          *node
383)
384{
385  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
386
387  _Scheduler_SMP_Update_priority(
388    context,
389    the_thread,
390    node,
391    _Scheduler_strong_APA_Extract_from_ready,
392    _Scheduler_strong_APA_Do_update,
393    _Scheduler_strong_APA_Enqueue_fifo,
394    _Scheduler_strong_APA_Enqueue_lifo,
395    _Scheduler_strong_APA_Enqueue_scheduled_fifo,
396    _Scheduler_strong_APA_Enqueue_scheduled_lifo,
397    _Scheduler_strong_APA_Do_ask_for_help
398  );
399}
400
401bool _Scheduler_strong_APA_Ask_for_help(
402  const Scheduler_Control *scheduler,
403  Thread_Control          *the_thread,
404  Scheduler_Node          *node
405)
406{
407  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
408
409  return _Scheduler_strong_APA_Do_ask_for_help( context, the_thread, node );
410}
411
412void _Scheduler_strong_APA_Reconsider_help_request(
413  const Scheduler_Control *scheduler,
414  Thread_Control          *the_thread,
415  Scheduler_Node          *node
416)
417{
418  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
419
420  _Scheduler_SMP_Reconsider_help_request(
421    context,
422    the_thread,
423    node,
424    _Scheduler_strong_APA_Extract_from_ready
425  );
426}
427
428void _Scheduler_strong_APA_Withdraw_node(
429  const Scheduler_Control *scheduler,
430  Thread_Control          *the_thread,
431  Scheduler_Node          *node,
432  Thread_Scheduler_state   next_state
433)
434{
435  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
436
437  _Scheduler_SMP_Withdraw_node(
438    context,
439    the_thread,
440    node,
441    next_state,
442    _Scheduler_strong_APA_Extract_from_ready,
443    _Scheduler_strong_APA_Get_highest_ready,
444    _Scheduler_strong_APA_Move_from_ready_to_scheduled,
445    _Scheduler_SMP_Allocate_processor_lazy
446  );
447}
448
449void _Scheduler_strong_APA_Add_processor(
450  const Scheduler_Control *scheduler,
451  Thread_Control          *idle
452)
453{
454  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
455
456  _Scheduler_SMP_Add_processor(
457    context,
458    idle,
459    _Scheduler_strong_APA_Has_ready,
460    _Scheduler_strong_APA_Enqueue_scheduled_fifo,
461    _Scheduler_SMP_Do_nothing_register_idle
462  );
463}
464
465Thread_Control *_Scheduler_strong_APA_Remove_processor(
466  const Scheduler_Control *scheduler,
467  Per_CPU_Control         *cpu
468)
469{
470  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
471
472  return _Scheduler_SMP_Remove_processor(
473    context,
474    cpu,
475    _Scheduler_strong_APA_Extract_from_ready,
476    _Scheduler_strong_APA_Enqueue_fifo
477  );
478}
479
480void _Scheduler_strong_APA_Yield(
481  const Scheduler_Control *scheduler,
482  Thread_Control          *the_thread,
483  Scheduler_Node          *node
484)
485{
486  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
487
488  _Scheduler_SMP_Yield(
489    context,
490    the_thread,
491    node,
492    _Scheduler_strong_APA_Extract_from_ready,
493    _Scheduler_strong_APA_Enqueue_fifo,
494    _Scheduler_strong_APA_Enqueue_scheduled_fifo
495  );
496}
Note: See TracBrowser for help on using the repository browser.