source: rtems/cpukit/score/src/schedulersimplesmp.c @ 0a97ba5b

5
Last change on this file since 0a97ba5b was 27783f6, checked in by Sebastian Huber <sebastian.huber@…>, on 07/10/14 at 12:27:42

score: Fix scheduler helping implementation

Do not extract the idle threads from the ready set so that there is
always a thread available for comparison.

  • Property mode set to 100644
File size: 8.6 KB
Line 
1/**
2 * @file
3 *
4 * @brief Simple SMP Scheduler Implementation
5 *
6 * @ingroup ScoreSchedulerSMPSimple
7 */
8
9/*
10 * Copyright (c) 2013-2014 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  Thread_Control          *the_thread
48)
49{
50  Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_own_node( the_thread );
51
52  _Scheduler_SMP_Node_initialize( node, the_thread );
53}
54
55static void _Scheduler_simple_SMP_Do_update(
56  Scheduler_Context *context,
57  Scheduler_Node    *node_to_update,
58  Priority_Control   new_priority
59)
60{
61  Scheduler_SMP_Node *node = _Scheduler_SMP_Node_downcast( node_to_update );
62
63  (void) context;
64
65  _Scheduler_SMP_Node_update_priority( node, new_priority );
66}
67
68void _Scheduler_simple_SMP_Update_priority(
69  const Scheduler_Control *scheduler,
70  Thread_Control          *thread,
71  Priority_Control         new_priority
72)
73{
74  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
75  Scheduler_Node *node = _Scheduler_Thread_get_node( thread );
76
77  _Scheduler_simple_SMP_Do_update( context, node, new_priority );
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_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 );
105  _Chain_Insert_ordered_unprotected(
106    &self->Ready,
107    &scheduled_to_ready->Node,
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 );
121  _Chain_Insert_ordered_unprotected(
122    &self->Base.Scheduled,
123    &ready_to_scheduled->Node,
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,
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,
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 );
166}
167
168void _Scheduler_simple_SMP_Block(
169  const Scheduler_Control *scheduler,
170  Thread_Control *thread
171)
172{
173  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
174
175  _Scheduler_SMP_Block(
176    context,
177    thread,
178    _Scheduler_simple_SMP_Extract_from_ready,
179    _Scheduler_simple_SMP_Get_highest_ready,
180    _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
181    _Scheduler_SMP_Allocate_processor_lazy
182  );
183}
184
185static Thread_Control *_Scheduler_simple_SMP_Enqueue_ordered(
186  Scheduler_Context    *context,
187  Scheduler_Node       *node,
188  Thread_Control       *needs_help,
189  Chain_Node_order      order,
190  Scheduler_SMP_Insert  insert_ready,
191  Scheduler_SMP_Insert  insert_scheduled
192)
193{
194  return _Scheduler_SMP_Enqueue_ordered(
195    context,
196    node,
197    needs_help,
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 Thread_Control *_Scheduler_simple_SMP_Enqueue_lifo(
208  Scheduler_Context *context,
209  Scheduler_Node    *node,
210  Thread_Control    *needs_help
211)
212{
213  return _Scheduler_simple_SMP_Enqueue_ordered(
214    context,
215    node,
216    needs_help,
217    _Scheduler_SMP_Insert_priority_lifo_order,
218    _Scheduler_simple_SMP_Insert_ready_lifo,
219    _Scheduler_SMP_Insert_scheduled_lifo
220  );
221}
222
223static Thread_Control *_Scheduler_simple_SMP_Enqueue_fifo(
224  Scheduler_Context *context,
225  Scheduler_Node    *node,
226  Thread_Control    *needs_help
227)
228{
229  return _Scheduler_simple_SMP_Enqueue_ordered(
230    context,
231    node,
232    needs_help,
233    _Scheduler_SMP_Insert_priority_fifo_order,
234    _Scheduler_simple_SMP_Insert_ready_fifo,
235    _Scheduler_SMP_Insert_scheduled_fifo
236  );
237}
238
239static Thread_Control *_Scheduler_simple_SMP_Enqueue_scheduled_ordered(
240  Scheduler_Context *context,
241  Scheduler_Node *node,
242  Chain_Node_order order,
243  Scheduler_SMP_Insert insert_ready,
244  Scheduler_SMP_Insert insert_scheduled
245)
246{
247  return _Scheduler_SMP_Enqueue_scheduled_ordered(
248    context,
249    node,
250    order,
251    _Scheduler_simple_SMP_Extract_from_ready,
252    _Scheduler_simple_SMP_Get_highest_ready,
253    insert_ready,
254    insert_scheduled,
255    _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
256    _Scheduler_SMP_Allocate_processor_lazy
257  );
258}
259
260static Thread_Control *_Scheduler_simple_SMP_Enqueue_scheduled_lifo(
261  Scheduler_Context *context,
262  Scheduler_Node *node
263)
264{
265  return _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
266    context,
267    node,
268    _Scheduler_SMP_Insert_priority_lifo_order,
269    _Scheduler_simple_SMP_Insert_ready_lifo,
270    _Scheduler_SMP_Insert_scheduled_lifo
271  );
272}
273
274static Thread_Control *_Scheduler_simple_SMP_Enqueue_scheduled_fifo(
275  Scheduler_Context *context,
276  Scheduler_Node *node
277)
278{
279  return _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
280    context,
281    node,
282    _Scheduler_SMP_Insert_priority_fifo_order,
283    _Scheduler_simple_SMP_Insert_ready_fifo,
284    _Scheduler_SMP_Insert_scheduled_fifo
285  );
286}
287
288Thread_Control *_Scheduler_simple_SMP_Unblock(
289  const Scheduler_Control *scheduler,
290  Thread_Control *thread
291)
292{
293  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
294
295  return _Scheduler_SMP_Unblock(
296    context,
297    thread,
298    _Scheduler_simple_SMP_Enqueue_fifo
299  );
300}
301
302Thread_Control *_Scheduler_simple_SMP_Change_priority(
303  const Scheduler_Control *scheduler,
304  Thread_Control          *thread,
305  Priority_Control         new_priority,
306  bool                     prepend_it
307)
308{
309  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
310
311  return _Scheduler_SMP_Change_priority(
312    context,
313    thread,
314    new_priority,
315    prepend_it,
316    _Scheduler_simple_SMP_Extract_from_ready,
317    _Scheduler_simple_SMP_Do_update,
318    _Scheduler_simple_SMP_Enqueue_fifo,
319    _Scheduler_simple_SMP_Enqueue_lifo,
320    _Scheduler_simple_SMP_Enqueue_scheduled_fifo,
321    _Scheduler_simple_SMP_Enqueue_scheduled_lifo
322  );
323}
324
325Thread_Control *_Scheduler_simple_SMP_Ask_for_help(
326  const Scheduler_Control *scheduler,
327  Thread_Control          *offers_help,
328  Thread_Control          *needs_help
329)
330{
331  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
332
333  return _Scheduler_SMP_Ask_for_help(
334    context,
335    offers_help,
336    needs_help,
337    _Scheduler_simple_SMP_Enqueue_fifo
338  );
339}
340
341Thread_Control *_Scheduler_simple_SMP_Yield(
342  const Scheduler_Control *scheduler,
343  Thread_Control *thread
344)
345{
346  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
347
348  return _Scheduler_SMP_Yield(
349    context,
350    thread,
351    _Scheduler_simple_SMP_Extract_from_ready,
352    _Scheduler_simple_SMP_Enqueue_fifo,
353    _Scheduler_simple_SMP_Enqueue_scheduled_fifo
354  );
355}
Note: See TracBrowser for help on using the repository browser.