source: rtems/cpukit/score/src/schedulersimplesmp.c @ 63e2ca1b

5
Last change on this file since 63e2ca1b was 63e2ca1b, checked in by Sebastian Huber <sebastian.huber@…>, on Oct 31, 2016 at 8:13:35 AM

score: Simplify yield and unblock scheduler ops

Update #2556.

  • Property mode set to 100644
File size: 9.6 KB
Line 
1/**
2 * @file
3 *
4 * @brief Simple SMP Scheduler Implementation
5 *
6 * @ingroup ScoreSchedulerSMPSimple
7 */
8
9/*
10 * Copyright (c) 2013, 2016 embedded brains GmbH.
11 *
12 * The license and distribution terms for this file may be
13 * found in the file LICENSE in this distribution or at
14 * http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18  #include "config.h"
19#endif
20
21#include <rtems/score/schedulersimplesmp.h>
22#include <rtems/score/schedulersmpimpl.h>
23
24static Scheduler_simple_SMP_Context *
25_Scheduler_simple_SMP_Get_context( const Scheduler_Control *scheduler )
26{
27  return (Scheduler_simple_SMP_Context *) _Scheduler_Get_context( scheduler );
28}
29
30static Scheduler_simple_SMP_Context *
31_Scheduler_simple_SMP_Get_self( Scheduler_Context *context )
32{
33  return (Scheduler_simple_SMP_Context *) context;
34}
35
36void _Scheduler_simple_SMP_Initialize( const Scheduler_Control *scheduler )
37{
38  Scheduler_simple_SMP_Context *self =
39    _Scheduler_simple_SMP_Get_context( scheduler );
40
41  _Scheduler_SMP_Initialize( &self->Base );
42  _Chain_Initialize_empty( &self->Ready );
43}
44
45void _Scheduler_simple_SMP_Node_initialize(
46  const Scheduler_Control *scheduler,
47  Scheduler_Node          *node,
48  Thread_Control          *the_thread,
49  Priority_Control         priority
50)
51{
52  Scheduler_SMP_Node *smp_node;
53
54  smp_node = _Scheduler_SMP_Node_downcast( node );
55  _Scheduler_SMP_Node_initialize( scheduler, smp_node, the_thread, priority );
56}
57
58static void _Scheduler_simple_SMP_Do_update(
59  Scheduler_Context *context,
60  Scheduler_Node    *node,
61  Priority_Control   new_priority
62)
63{
64  Scheduler_SMP_Node *smp_node;
65
66  (void) context;
67
68  smp_node = _Scheduler_SMP_Node_downcast( node );
69  _Scheduler_SMP_Node_update_priority( smp_node, new_priority );
70}
71
72static Scheduler_Node *_Scheduler_simple_SMP_Get_highest_ready(
73  Scheduler_Context *context,
74  Scheduler_Node    *node
75)
76{
77  Scheduler_simple_SMP_Context *self =
78    _Scheduler_simple_SMP_Get_self( context );
79  Scheduler_Node *first = (Scheduler_Node *) _Chain_First( &self->Ready );
80
81  (void) node;
82
83  _Assert( &first->Node != _Chain_Tail( &self->Ready ) );
84
85  return first;
86}
87
88static void _Scheduler_simple_SMP_Move_from_scheduled_to_ready(
89  Scheduler_Context *context,
90  Scheduler_Node    *scheduled_to_ready
91)
92{
93  Scheduler_simple_SMP_Context *self =
94    _Scheduler_simple_SMP_Get_self( context );
95
96  _Chain_Extract_unprotected( &scheduled_to_ready->Node );
97  _Chain_Insert_ordered_unprotected(
98    &self->Ready,
99    &scheduled_to_ready->Node,
100    _Scheduler_SMP_Insert_priority_lifo_order
101  );
102}
103
104static void _Scheduler_simple_SMP_Move_from_ready_to_scheduled(
105  Scheduler_Context *context,
106  Scheduler_Node    *ready_to_scheduled
107)
108{
109  Scheduler_simple_SMP_Context *self =
110    _Scheduler_simple_SMP_Get_self( context );
111
112  _Chain_Extract_unprotected( &ready_to_scheduled->Node );
113  _Chain_Insert_ordered_unprotected(
114    &self->Base.Scheduled,
115    &ready_to_scheduled->Node,
116    _Scheduler_SMP_Insert_priority_fifo_order
117  );
118}
119
120static void _Scheduler_simple_SMP_Insert_ready_lifo(
121  Scheduler_Context *context,
122  Scheduler_Node    *node_to_insert
123)
124{
125  Scheduler_simple_SMP_Context *self =
126    _Scheduler_simple_SMP_Get_self( context );
127
128  _Chain_Insert_ordered_unprotected(
129    &self->Ready,
130    &node_to_insert->Node,
131    _Scheduler_SMP_Insert_priority_lifo_order
132  );
133}
134
135static void _Scheduler_simple_SMP_Insert_ready_fifo(
136  Scheduler_Context *context,
137  Scheduler_Node    *node_to_insert
138)
139{
140  Scheduler_simple_SMP_Context *self =
141    _Scheduler_simple_SMP_Get_self( context );
142
143  _Chain_Insert_ordered_unprotected(
144    &self->Ready,
145    &node_to_insert->Node,
146    _Scheduler_SMP_Insert_priority_fifo_order
147  );
148}
149
150static void _Scheduler_simple_SMP_Extract_from_ready(
151  Scheduler_Context *context,
152  Scheduler_Node    *node_to_extract
153)
154{
155  (void) context;
156
157  _Chain_Extract_unprotected( &node_to_extract->Node );
158}
159
160void _Scheduler_simple_SMP_Block(
161  const Scheduler_Control *scheduler,
162  Thread_Control          *thread,
163  Scheduler_Node          *node
164)
165{
166  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
167
168  _Scheduler_SMP_Block(
169    context,
170    thread,
171    node,
172    _Scheduler_simple_SMP_Extract_from_ready,
173    _Scheduler_simple_SMP_Get_highest_ready,
174    _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
175    _Scheduler_SMP_Allocate_processor_lazy
176  );
177}
178
179static bool _Scheduler_simple_SMP_Enqueue_ordered(
180  Scheduler_Context    *context,
181  Scheduler_Node       *node,
182  Chain_Node_order      order,
183  Scheduler_SMP_Insert  insert_ready,
184  Scheduler_SMP_Insert  insert_scheduled
185)
186{
187  return _Scheduler_SMP_Enqueue_ordered(
188    context,
189    node,
190    order,
191    insert_ready,
192    insert_scheduled,
193    _Scheduler_simple_SMP_Move_from_scheduled_to_ready,
194    _Scheduler_SMP_Get_lowest_scheduled,
195    _Scheduler_SMP_Allocate_processor_lazy
196  );
197}
198
199static bool _Scheduler_simple_SMP_Enqueue_lifo(
200  Scheduler_Context *context,
201  Scheduler_Node    *node
202)
203{
204  return _Scheduler_simple_SMP_Enqueue_ordered(
205    context,
206    node,
207    _Scheduler_SMP_Insert_priority_lifo_order,
208    _Scheduler_simple_SMP_Insert_ready_lifo,
209    _Scheduler_SMP_Insert_scheduled_lifo
210  );
211}
212
213static bool _Scheduler_simple_SMP_Enqueue_fifo(
214  Scheduler_Context *context,
215  Scheduler_Node    *node
216)
217{
218  return _Scheduler_simple_SMP_Enqueue_ordered(
219    context,
220    node,
221    _Scheduler_SMP_Insert_priority_fifo_order,
222    _Scheduler_simple_SMP_Insert_ready_fifo,
223    _Scheduler_SMP_Insert_scheduled_fifo
224  );
225}
226
227static bool _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
228  Scheduler_Context *context,
229  Scheduler_Node *node,
230  Chain_Node_order order,
231  Scheduler_SMP_Insert insert_ready,
232  Scheduler_SMP_Insert insert_scheduled
233)
234{
235  return _Scheduler_SMP_Enqueue_scheduled_ordered(
236    context,
237    node,
238    order,
239    _Scheduler_simple_SMP_Extract_from_ready,
240    _Scheduler_simple_SMP_Get_highest_ready,
241    insert_ready,
242    insert_scheduled,
243    _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
244    _Scheduler_SMP_Allocate_processor_lazy
245  );
246}
247
248static bool _Scheduler_simple_SMP_Enqueue_scheduled_lifo(
249  Scheduler_Context *context,
250  Scheduler_Node *node
251)
252{
253  return _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
254    context,
255    node,
256    _Scheduler_SMP_Insert_priority_lifo_order,
257    _Scheduler_simple_SMP_Insert_ready_lifo,
258    _Scheduler_SMP_Insert_scheduled_lifo
259  );
260}
261
262static bool _Scheduler_simple_SMP_Enqueue_scheduled_fifo(
263  Scheduler_Context *context,
264  Scheduler_Node *node
265)
266{
267  return _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
268    context,
269    node,
270    _Scheduler_SMP_Insert_priority_fifo_order,
271    _Scheduler_simple_SMP_Insert_ready_fifo,
272    _Scheduler_SMP_Insert_scheduled_fifo
273  );
274}
275
276bool _Scheduler_simple_SMP_Unblock(
277  const Scheduler_Control *scheduler,
278  Thread_Control          *thread,
279  Scheduler_Node          *node
280)
281{
282  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
283
284  return _Scheduler_SMP_Unblock(
285    context,
286    thread,
287    node,
288    _Scheduler_simple_SMP_Do_update,
289    _Scheduler_simple_SMP_Enqueue_fifo
290  );
291}
292
293static bool _Scheduler_simple_SMP_Do_ask_for_help(
294  Scheduler_Context *context,
295  Thread_Control    *the_thread,
296  Scheduler_Node    *node
297)
298{
299  return _Scheduler_SMP_Ask_for_help(
300    context,
301    the_thread,
302    node,
303    _Scheduler_SMP_Insert_priority_lifo_order,
304    _Scheduler_simple_SMP_Insert_ready_lifo,
305    _Scheduler_SMP_Insert_scheduled_lifo,
306    _Scheduler_simple_SMP_Move_from_scheduled_to_ready,
307    _Scheduler_SMP_Get_lowest_scheduled,
308    _Scheduler_SMP_Allocate_processor_lazy
309  );
310}
311
312void _Scheduler_simple_SMP_Update_priority(
313  const Scheduler_Control *scheduler,
314  Thread_Control          *thread,
315  Scheduler_Node          *node
316)
317{
318  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
319
320  _Scheduler_SMP_Update_priority(
321    context,
322    thread,
323    node,
324    _Scheduler_simple_SMP_Extract_from_ready,
325    _Scheduler_simple_SMP_Do_update,
326    _Scheduler_simple_SMP_Enqueue_fifo,
327    _Scheduler_simple_SMP_Enqueue_lifo,
328    _Scheduler_simple_SMP_Enqueue_scheduled_fifo,
329    _Scheduler_simple_SMP_Enqueue_scheduled_lifo,
330    _Scheduler_simple_SMP_Do_ask_for_help
331  );
332}
333
334bool _Scheduler_simple_SMP_Ask_for_help(
335  const Scheduler_Control *scheduler,
336  Thread_Control          *the_thread,
337  Scheduler_Node          *node
338)
339{
340  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
341
342  return _Scheduler_simple_SMP_Do_ask_for_help( context, the_thread, node );
343}
344
345void _Scheduler_simple_SMP_Reconsider_help_request(
346  const Scheduler_Control *scheduler,
347  Thread_Control          *the_thread,
348  Scheduler_Node          *node
349)
350{
351  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
352
353  _Scheduler_SMP_Reconsider_help_request(
354    context,
355    the_thread,
356    node,
357    _Scheduler_simple_SMP_Extract_from_ready
358  );
359}
360
361void _Scheduler_simple_SMP_Withdraw_node(
362  const Scheduler_Control *scheduler,
363  Thread_Control          *the_thread,
364  Scheduler_Node          *node,
365  Thread_Scheduler_state   next_state
366)
367{
368  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
369
370  _Scheduler_SMP_Withdraw_node(
371    context,
372    the_thread,
373    node,
374    next_state,
375    _Scheduler_simple_SMP_Extract_from_ready,
376    _Scheduler_simple_SMP_Get_highest_ready,
377    _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
378    _Scheduler_SMP_Allocate_processor_lazy
379  );
380}
381
382bool _Scheduler_simple_SMP_Yield(
383  const Scheduler_Control *scheduler,
384  Thread_Control          *thread,
385  Scheduler_Node          *node
386)
387{
388  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
389
390  return _Scheduler_SMP_Yield(
391    context,
392    thread,
393    node,
394    _Scheduler_simple_SMP_Extract_from_ready,
395    _Scheduler_simple_SMP_Enqueue_fifo,
396    _Scheduler_simple_SMP_Enqueue_scheduled_fifo
397  );
398}
Note: See TracBrowser for help on using the repository browser.