source: rtems/cpukit/score/src/schedulerstrongapa.c @ 8a8b95aa

5
Last change on this file since 8a8b95aa was 4c20da4b, checked in by Sebastian Huber <sebastian.huber@…>, on 04/04/19 at 07:18:11

doxygen: Rename Score* groups in RTEMSScore*

Update #3706

  • Property mode set to 100644
File size: 10.8 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSScoreSchedulerStrongAPA
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_Node    *node;
69  Priority_Control              insert_priority;
70
71  self = _Scheduler_strong_APA_Get_self( context );
72  node = _Scheduler_strong_APA_Node_downcast( ready_to_scheduled );
73
74  _Scheduler_priority_Ready_queue_extract(
75    &node->Base.Base.Node.Chain,
76    &node->Ready_queue,
77    &self->Bit_map
78  );
79  insert_priority = _Scheduler_SMP_Node_priority( &node->Base.Base );
80  insert_priority = SCHEDULER_PRIORITY_APPEND( insert_priority );
81  _Chain_Insert_ordered_unprotected(
82    &self->Base.Scheduled,
83    &node->Base.Base.Node.Chain,
84    &insert_priority,
85    _Scheduler_SMP_Priority_less_equal
86  );
87}
88
89static void _Scheduler_strong_APA_Insert_ready(
90  Scheduler_Context *context,
91  Scheduler_Node    *node_base,
92  Priority_Control   insert_priority
93)
94{
95  Scheduler_strong_APA_Context *self;
96  Scheduler_strong_APA_Node    *node;
97
98  self = _Scheduler_strong_APA_Get_self( context );
99  node = _Scheduler_strong_APA_Node_downcast( node_base );
100
101  if ( SCHEDULER_PRIORITY_IS_APPEND( insert_priority ) ) {
102    _Scheduler_priority_Ready_queue_enqueue(
103      &node->Base.Base.Node.Chain,
104      &node->Ready_queue,
105      &self->Bit_map
106    );
107  } else {
108    _Scheduler_priority_Ready_queue_enqueue_first(
109      &node->Base.Base.Node.Chain,
110      &node->Ready_queue,
111      &self->Bit_map
112    );
113  }
114}
115
116static void _Scheduler_strong_APA_Extract_from_ready(
117  Scheduler_Context *context,
118  Scheduler_Node    *the_thread
119)
120{
121  Scheduler_strong_APA_Context *self =
122    _Scheduler_strong_APA_Get_self( context );
123  Scheduler_strong_APA_Node *node =
124    _Scheduler_strong_APA_Node_downcast( the_thread );
125
126  _Scheduler_priority_Ready_queue_extract(
127    &node->Base.Base.Node.Chain,
128    &node->Ready_queue,
129    &self->Bit_map
130  );
131}
132
133static void _Scheduler_strong_APA_Do_update(
134  Scheduler_Context *context,
135  Scheduler_Node *node_to_update,
136  Priority_Control new_priority
137)
138{
139  Scheduler_strong_APA_Context *self =
140    _Scheduler_strong_APA_Get_self( context );
141  Scheduler_strong_APA_Node *node =
142    _Scheduler_strong_APA_Node_downcast( node_to_update );
143
144  _Scheduler_SMP_Node_update_priority( &node->Base, new_priority );
145  _Scheduler_priority_Ready_queue_update(
146    &node->Ready_queue,
147    SCHEDULER_PRIORITY_UNMAP( new_priority ),
148    &self->Bit_map,
149    &self->Ready[ 0 ]
150  );
151}
152
153static Scheduler_strong_APA_Context *
154_Scheduler_strong_APA_Get_context( const Scheduler_Control *scheduler )
155{
156  return (Scheduler_strong_APA_Context *) _Scheduler_Get_context( scheduler );
157}
158
159void _Scheduler_strong_APA_Initialize( const Scheduler_Control *scheduler )
160{
161  Scheduler_strong_APA_Context *self =
162    _Scheduler_strong_APA_Get_context( scheduler );
163
164  _Scheduler_SMP_Initialize( &self->Base );
165  _Priority_bit_map_Initialize( &self->Bit_map );
166  _Scheduler_priority_Ready_queue_initialize(
167    &self->Ready[ 0 ],
168    scheduler->maximum_priority
169  );
170}
171
172void _Scheduler_strong_APA_Node_initialize(
173  const Scheduler_Control *scheduler,
174  Scheduler_Node          *node,
175  Thread_Control          *the_thread,
176  Priority_Control         priority
177)
178{
179  Scheduler_Context            *context;
180  Scheduler_strong_APA_Context *self;
181  Scheduler_strong_APA_Node    *the_node;
182
183  the_node = _Scheduler_strong_APA_Node_downcast( node );
184  _Scheduler_SMP_Node_initialize(
185    scheduler,
186    &the_node->Base,
187    the_thread,
188    priority
189  );
190
191  context = _Scheduler_Get_context( scheduler );
192  self = _Scheduler_strong_APA_Get_self( context );
193  _Scheduler_priority_Ready_queue_update(
194    &the_node->Ready_queue,
195    SCHEDULER_PRIORITY_UNMAP( priority ),
196    &self->Bit_map,
197    &self->Ready[ 0 ]
198  );
199}
200
201static bool _Scheduler_strong_APA_Has_ready( Scheduler_Context *context )
202{
203  Scheduler_strong_APA_Context *self =
204    _Scheduler_strong_APA_Get_self( context );
205
206  return !_Priority_bit_map_Is_empty( &self->Bit_map );
207}
208
209static Scheduler_Node *_Scheduler_strong_APA_Get_highest_ready(
210  Scheduler_Context *context,
211  Scheduler_Node    *node
212)
213{
214  Scheduler_strong_APA_Context *self =
215    _Scheduler_strong_APA_Get_self( context );
216
217  (void) node;
218
219  return (Scheduler_Node *) _Scheduler_priority_Ready_queue_first(
220    &self->Bit_map,
221    &self->Ready[ 0 ]
222  );
223}
224
225void _Scheduler_strong_APA_Block(
226  const Scheduler_Control *scheduler,
227  Thread_Control          *the_thread,
228  Scheduler_Node          *node
229)
230{
231  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
232
233  _Scheduler_SMP_Block(
234    context,
235    the_thread,
236    node,
237    _Scheduler_SMP_Extract_from_scheduled,
238    _Scheduler_strong_APA_Extract_from_ready,
239    _Scheduler_strong_APA_Get_highest_ready,
240    _Scheduler_strong_APA_Move_from_ready_to_scheduled,
241    _Scheduler_SMP_Allocate_processor_exact
242  );
243}
244
245static bool _Scheduler_strong_APA_Enqueue(
246  Scheduler_Context *context,
247  Scheduler_Node    *node,
248  Priority_Control   insert_priority
249)
250{
251  return _Scheduler_SMP_Enqueue(
252    context,
253    node,
254    insert_priority,
255    _Scheduler_SMP_Priority_less_equal,
256    _Scheduler_strong_APA_Insert_ready,
257    _Scheduler_SMP_Insert_scheduled,
258    _Scheduler_strong_APA_Move_from_scheduled_to_ready,
259    _Scheduler_SMP_Get_lowest_scheduled,
260    _Scheduler_SMP_Allocate_processor_exact
261  );
262}
263
264static bool _Scheduler_strong_APA_Enqueue_scheduled(
265  Scheduler_Context *context,
266  Scheduler_Node    *node,
267  Priority_Control  insert_priority
268)
269{
270  return _Scheduler_SMP_Enqueue_scheduled(
271    context,
272    node,
273    insert_priority,
274    _Scheduler_SMP_Priority_less_equal,
275    _Scheduler_strong_APA_Extract_from_ready,
276    _Scheduler_strong_APA_Get_highest_ready,
277    _Scheduler_strong_APA_Insert_ready,
278    _Scheduler_SMP_Insert_scheduled,
279    _Scheduler_strong_APA_Move_from_ready_to_scheduled,
280    _Scheduler_SMP_Allocate_processor_exact
281  );
282}
283
284void _Scheduler_strong_APA_Unblock(
285  const Scheduler_Control *scheduler,
286  Thread_Control          *the_thread,
287  Scheduler_Node          *node
288)
289{
290  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
291
292  _Scheduler_SMP_Unblock(
293    context,
294    the_thread,
295    node,
296    _Scheduler_strong_APA_Do_update,
297    _Scheduler_strong_APA_Enqueue
298  );
299}
300
301static bool _Scheduler_strong_APA_Do_ask_for_help(
302  Scheduler_Context *context,
303  Thread_Control    *the_thread,
304  Scheduler_Node    *node
305)
306{
307  return _Scheduler_SMP_Ask_for_help(
308    context,
309    the_thread,
310    node,
311    _Scheduler_SMP_Priority_less_equal,
312    _Scheduler_strong_APA_Insert_ready,
313    _Scheduler_SMP_Insert_scheduled,
314    _Scheduler_strong_APA_Move_from_scheduled_to_ready,
315    _Scheduler_SMP_Get_lowest_scheduled,
316    _Scheduler_SMP_Allocate_processor_lazy
317  );
318}
319
320void _Scheduler_strong_APA_Update_priority(
321  const Scheduler_Control *scheduler,
322  Thread_Control          *the_thread,
323  Scheduler_Node          *node
324)
325{
326  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
327
328  _Scheduler_SMP_Update_priority(
329    context,
330    the_thread,
331    node,
332    _Scheduler_strong_APA_Extract_from_ready,
333    _Scheduler_strong_APA_Do_update,
334    _Scheduler_strong_APA_Enqueue,
335    _Scheduler_strong_APA_Enqueue_scheduled,
336    _Scheduler_strong_APA_Do_ask_for_help
337  );
338}
339
340bool _Scheduler_strong_APA_Ask_for_help(
341  const Scheduler_Control *scheduler,
342  Thread_Control          *the_thread,
343  Scheduler_Node          *node
344)
345{
346  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
347
348  return _Scheduler_strong_APA_Do_ask_for_help( context, the_thread, node );
349}
350
351void _Scheduler_strong_APA_Reconsider_help_request(
352  const Scheduler_Control *scheduler,
353  Thread_Control          *the_thread,
354  Scheduler_Node          *node
355)
356{
357  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
358
359  _Scheduler_SMP_Reconsider_help_request(
360    context,
361    the_thread,
362    node,
363    _Scheduler_strong_APA_Extract_from_ready
364  );
365}
366
367void _Scheduler_strong_APA_Withdraw_node(
368  const Scheduler_Control *scheduler,
369  Thread_Control          *the_thread,
370  Scheduler_Node          *node,
371  Thread_Scheduler_state   next_state
372)
373{
374  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
375
376  _Scheduler_SMP_Withdraw_node(
377    context,
378    the_thread,
379    node,
380    next_state,
381    _Scheduler_strong_APA_Extract_from_ready,
382    _Scheduler_strong_APA_Get_highest_ready,
383    _Scheduler_strong_APA_Move_from_ready_to_scheduled,
384    _Scheduler_SMP_Allocate_processor_lazy
385  );
386}
387
388void _Scheduler_strong_APA_Add_processor(
389  const Scheduler_Control *scheduler,
390  Thread_Control          *idle
391)
392{
393  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
394
395  _Scheduler_SMP_Add_processor(
396    context,
397    idle,
398    _Scheduler_strong_APA_Has_ready,
399    _Scheduler_strong_APA_Enqueue_scheduled,
400    _Scheduler_SMP_Do_nothing_register_idle
401  );
402}
403
404Thread_Control *_Scheduler_strong_APA_Remove_processor(
405  const Scheduler_Control *scheduler,
406  Per_CPU_Control         *cpu
407)
408{
409  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
410
411  return _Scheduler_SMP_Remove_processor(
412    context,
413    cpu,
414    _Scheduler_strong_APA_Extract_from_ready,
415    _Scheduler_strong_APA_Enqueue
416  );
417}
418
419void _Scheduler_strong_APA_Yield(
420  const Scheduler_Control *scheduler,
421  Thread_Control          *the_thread,
422  Scheduler_Node          *node
423)
424{
425  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
426
427  _Scheduler_SMP_Yield(
428    context,
429    the_thread,
430    node,
431    _Scheduler_strong_APA_Extract_from_ready,
432    _Scheduler_strong_APA_Enqueue,
433    _Scheduler_strong_APA_Enqueue_scheduled
434  );
435}
Note: See TracBrowser for help on using the repository browser.