source: rtems/cpukit/score/src/schedulersimplesmp.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: 10.5 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 bool _Scheduler_simple_SMP_Has_ready( Scheduler_Context *context )
73{
74  Scheduler_simple_SMP_Context *self =
75    _Scheduler_simple_SMP_Get_self( context );
76
77  return !_Chain_Is_empty( &self->Ready );
78}
79
80static Scheduler_Node *_Scheduler_simple_SMP_Get_highest_ready(
81  Scheduler_Context *context,
82  Scheduler_Node    *node
83)
84{
85  Scheduler_simple_SMP_Context *self =
86    _Scheduler_simple_SMP_Get_self( context );
87  Scheduler_Node *first = (Scheduler_Node *) _Chain_First( &self->Ready );
88
89  (void) node;
90
91  _Assert( &first->Node.Chain != _Chain_Tail( &self->Ready ) );
92
93  return first;
94}
95
96static void _Scheduler_simple_SMP_Move_from_scheduled_to_ready(
97  Scheduler_Context *context,
98  Scheduler_Node    *scheduled_to_ready
99)
100{
101  Scheduler_simple_SMP_Context *self =
102    _Scheduler_simple_SMP_Get_self( context );
103
104  _Chain_Extract_unprotected( &scheduled_to_ready->Node.Chain );
105  _Chain_Insert_ordered_unprotected(
106    &self->Ready,
107    &scheduled_to_ready->Node.Chain,
108    _Scheduler_SMP_Insert_priority_lifo_order
109  );
110}
111
112static void _Scheduler_simple_SMP_Move_from_ready_to_scheduled(
113  Scheduler_Context *context,
114  Scheduler_Node    *ready_to_scheduled
115)
116{
117  Scheduler_simple_SMP_Context *self =
118    _Scheduler_simple_SMP_Get_self( context );
119
120  _Chain_Extract_unprotected( &ready_to_scheduled->Node.Chain );
121  _Chain_Insert_ordered_unprotected(
122    &self->Base.Scheduled,
123    &ready_to_scheduled->Node.Chain,
124    _Scheduler_SMP_Insert_priority_fifo_order
125  );
126}
127
128static void _Scheduler_simple_SMP_Insert_ready_lifo(
129  Scheduler_Context *context,
130  Scheduler_Node    *node_to_insert
131)
132{
133  Scheduler_simple_SMP_Context *self =
134    _Scheduler_simple_SMP_Get_self( context );
135
136  _Chain_Insert_ordered_unprotected(
137    &self->Ready,
138    &node_to_insert->Node.Chain,
139    _Scheduler_SMP_Insert_priority_lifo_order
140  );
141}
142
143static void _Scheduler_simple_SMP_Insert_ready_fifo(
144  Scheduler_Context *context,
145  Scheduler_Node    *node_to_insert
146)
147{
148  Scheduler_simple_SMP_Context *self =
149    _Scheduler_simple_SMP_Get_self( context );
150
151  _Chain_Insert_ordered_unprotected(
152    &self->Ready,
153    &node_to_insert->Node.Chain,
154    _Scheduler_SMP_Insert_priority_fifo_order
155  );
156}
157
158static void _Scheduler_simple_SMP_Extract_from_ready(
159  Scheduler_Context *context,
160  Scheduler_Node    *node_to_extract
161)
162{
163  (void) context;
164
165  _Chain_Extract_unprotected( &node_to_extract->Node.Chain );
166}
167
168void _Scheduler_simple_SMP_Block(
169  const Scheduler_Control *scheduler,
170  Thread_Control          *thread,
171  Scheduler_Node          *node
172)
173{
174  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
175
176  _Scheduler_SMP_Block(
177    context,
178    thread,
179    node,
180    _Scheduler_simple_SMP_Extract_from_ready,
181    _Scheduler_simple_SMP_Get_highest_ready,
182    _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
183    _Scheduler_SMP_Allocate_processor_lazy
184  );
185}
186
187static bool _Scheduler_simple_SMP_Enqueue_ordered(
188  Scheduler_Context    *context,
189  Scheduler_Node       *node,
190  Chain_Node_order      order,
191  Scheduler_SMP_Insert  insert_ready,
192  Scheduler_SMP_Insert  insert_scheduled
193)
194{
195  return _Scheduler_SMP_Enqueue_ordered(
196    context,
197    node,
198    order,
199    insert_ready,
200    insert_scheduled,
201    _Scheduler_simple_SMP_Move_from_scheduled_to_ready,
202    _Scheduler_SMP_Get_lowest_scheduled,
203    _Scheduler_SMP_Allocate_processor_lazy
204  );
205}
206
207static bool _Scheduler_simple_SMP_Enqueue_lifo(
208  Scheduler_Context *context,
209  Scheduler_Node    *node
210)
211{
212  return _Scheduler_simple_SMP_Enqueue_ordered(
213    context,
214    node,
215    _Scheduler_SMP_Insert_priority_lifo_order,
216    _Scheduler_simple_SMP_Insert_ready_lifo,
217    _Scheduler_SMP_Insert_scheduled_lifo
218  );
219}
220
221static bool _Scheduler_simple_SMP_Enqueue_fifo(
222  Scheduler_Context *context,
223  Scheduler_Node    *node
224)
225{
226  return _Scheduler_simple_SMP_Enqueue_ordered(
227    context,
228    node,
229    _Scheduler_SMP_Insert_priority_fifo_order,
230    _Scheduler_simple_SMP_Insert_ready_fifo,
231    _Scheduler_SMP_Insert_scheduled_fifo
232  );
233}
234
235static bool _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
236  Scheduler_Context *context,
237  Scheduler_Node *node,
238  Chain_Node_order order,
239  Scheduler_SMP_Insert insert_ready,
240  Scheduler_SMP_Insert insert_scheduled
241)
242{
243  return _Scheduler_SMP_Enqueue_scheduled_ordered(
244    context,
245    node,
246    order,
247    _Scheduler_simple_SMP_Extract_from_ready,
248    _Scheduler_simple_SMP_Get_highest_ready,
249    insert_ready,
250    insert_scheduled,
251    _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
252    _Scheduler_SMP_Allocate_processor_lazy
253  );
254}
255
256static bool _Scheduler_simple_SMP_Enqueue_scheduled_lifo(
257  Scheduler_Context *context,
258  Scheduler_Node *node
259)
260{
261  return _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
262    context,
263    node,
264    _Scheduler_SMP_Insert_priority_lifo_order,
265    _Scheduler_simple_SMP_Insert_ready_lifo,
266    _Scheduler_SMP_Insert_scheduled_lifo
267  );
268}
269
270static bool _Scheduler_simple_SMP_Enqueue_scheduled_fifo(
271  Scheduler_Context *context,
272  Scheduler_Node *node
273)
274{
275  return _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
276    context,
277    node,
278    _Scheduler_SMP_Insert_priority_fifo_order,
279    _Scheduler_simple_SMP_Insert_ready_fifo,
280    _Scheduler_SMP_Insert_scheduled_fifo
281  );
282}
283
284void _Scheduler_simple_SMP_Unblock(
285  const Scheduler_Control *scheduler,
286  Thread_Control          *thread,
287  Scheduler_Node          *node
288)
289{
290  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
291
292  _Scheduler_SMP_Unblock(
293    context,
294    thread,
295    node,
296    _Scheduler_simple_SMP_Do_update,
297    _Scheduler_simple_SMP_Enqueue_fifo
298  );
299}
300
301static bool _Scheduler_simple_SMP_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_Insert_priority_lifo_order,
312    _Scheduler_simple_SMP_Insert_ready_lifo,
313    _Scheduler_SMP_Insert_scheduled_lifo,
314    _Scheduler_simple_SMP_Move_from_scheduled_to_ready,
315    _Scheduler_SMP_Get_lowest_scheduled,
316    _Scheduler_SMP_Allocate_processor_lazy
317  );
318}
319
320void _Scheduler_simple_SMP_Update_priority(
321  const Scheduler_Control *scheduler,
322  Thread_Control          *thread,
323  Scheduler_Node          *node
324)
325{
326  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
327
328  _Scheduler_SMP_Update_priority(
329    context,
330    thread,
331    node,
332    _Scheduler_simple_SMP_Extract_from_ready,
333    _Scheduler_simple_SMP_Do_update,
334    _Scheduler_simple_SMP_Enqueue_fifo,
335    _Scheduler_simple_SMP_Enqueue_lifo,
336    _Scheduler_simple_SMP_Enqueue_scheduled_fifo,
337    _Scheduler_simple_SMP_Enqueue_scheduled_lifo,
338    _Scheduler_simple_SMP_Do_ask_for_help
339  );
340}
341
342bool _Scheduler_simple_SMP_Ask_for_help(
343  const Scheduler_Control *scheduler,
344  Thread_Control          *the_thread,
345  Scheduler_Node          *node
346)
347{
348  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
349
350  return _Scheduler_simple_SMP_Do_ask_for_help( context, the_thread, node );
351}
352
353void _Scheduler_simple_SMP_Reconsider_help_request(
354  const Scheduler_Control *scheduler,
355  Thread_Control          *the_thread,
356  Scheduler_Node          *node
357)
358{
359  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
360
361  _Scheduler_SMP_Reconsider_help_request(
362    context,
363    the_thread,
364    node,
365    _Scheduler_simple_SMP_Extract_from_ready
366  );
367}
368
369void _Scheduler_simple_SMP_Withdraw_node(
370  const Scheduler_Control *scheduler,
371  Thread_Control          *the_thread,
372  Scheduler_Node          *node,
373  Thread_Scheduler_state   next_state
374)
375{
376  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
377
378  _Scheduler_SMP_Withdraw_node(
379    context,
380    the_thread,
381    node,
382    next_state,
383    _Scheduler_simple_SMP_Extract_from_ready,
384    _Scheduler_simple_SMP_Get_highest_ready,
385    _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
386    _Scheduler_SMP_Allocate_processor_lazy
387  );
388}
389
390void _Scheduler_simple_SMP_Add_processor(
391  const Scheduler_Control *scheduler,
392  Thread_Control          *idle
393)
394{
395  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
396
397  _Scheduler_SMP_Add_processor(
398    context,
399    idle,
400    _Scheduler_simple_SMP_Has_ready,
401    _Scheduler_simple_SMP_Enqueue_scheduled_fifo,
402    _Scheduler_SMP_Do_nothing_register_idle
403  );
404}
405
406Thread_Control *_Scheduler_simple_SMP_Remove_processor(
407  const Scheduler_Control *scheduler,
408  Per_CPU_Control         *cpu
409)
410{
411  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
412
413  return _Scheduler_SMP_Remove_processor(
414    context,
415    cpu,
416    _Scheduler_simple_SMP_Extract_from_ready,
417    _Scheduler_simple_SMP_Enqueue_fifo
418  );
419}
420
421void _Scheduler_simple_SMP_Yield(
422  const Scheduler_Control *scheduler,
423  Thread_Control          *thread,
424  Scheduler_Node          *node
425)
426{
427  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
428
429  _Scheduler_SMP_Yield(
430    context,
431    thread,
432    node,
433    _Scheduler_simple_SMP_Extract_from_ready,
434    _Scheduler_simple_SMP_Enqueue_fifo,
435    _Scheduler_simple_SMP_Enqueue_scheduled_fifo
436  );
437}
Note: See TracBrowser for help on using the repository browser.