source: rtems/cpukit/score/src/schedulersimplesmp.c @ df2177ab

5
Last change on this file since df2177ab was df2177ab, checked in by Sebastian Huber <sebastian.huber@…>, on 07/01/16 at 12:47:07

score: Change scheduler node init and destroy

Provide the scheduler node to initialize or destroy to the corresponding
operations. This makes it possible to have more than one scheduler node
per thread.

  • Property mode set to 100644
File size: 8.3 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  Scheduler_Node          *node,
48  Thread_Control          *the_thread,
49  Priority_Control         priority
50)
51{
52  Scheduler_SMP_Node *the_node;
53
54  the_node = _Scheduler_SMP_Node_downcast( node );
55  _Scheduler_SMP_Node_initialize( the_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 *the_node;
65
66  (void) context;
67
68  the_node = _Scheduler_SMP_Node_downcast( node );
69  _Scheduler_SMP_Node_update_priority( the_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)
164{
165  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
166
167  _Scheduler_SMP_Block(
168    context,
169    thread,
170    _Scheduler_simple_SMP_Extract_from_ready,
171    _Scheduler_simple_SMP_Get_highest_ready,
172    _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
173    _Scheduler_SMP_Allocate_processor_lazy
174  );
175}
176
177static Thread_Control *_Scheduler_simple_SMP_Enqueue_ordered(
178  Scheduler_Context    *context,
179  Scheduler_Node       *node,
180  Thread_Control       *needs_help,
181  Chain_Node_order      order,
182  Scheduler_SMP_Insert  insert_ready,
183  Scheduler_SMP_Insert  insert_scheduled
184)
185{
186  return _Scheduler_SMP_Enqueue_ordered(
187    context,
188    node,
189    needs_help,
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 Thread_Control *_Scheduler_simple_SMP_Enqueue_lifo(
200  Scheduler_Context *context,
201  Scheduler_Node    *node,
202  Thread_Control    *needs_help
203)
204{
205  return _Scheduler_simple_SMP_Enqueue_ordered(
206    context,
207    node,
208    needs_help,
209    _Scheduler_SMP_Insert_priority_lifo_order,
210    _Scheduler_simple_SMP_Insert_ready_lifo,
211    _Scheduler_SMP_Insert_scheduled_lifo
212  );
213}
214
215static Thread_Control *_Scheduler_simple_SMP_Enqueue_fifo(
216  Scheduler_Context *context,
217  Scheduler_Node    *node,
218  Thread_Control    *needs_help
219)
220{
221  return _Scheduler_simple_SMP_Enqueue_ordered(
222    context,
223    node,
224    needs_help,
225    _Scheduler_SMP_Insert_priority_fifo_order,
226    _Scheduler_simple_SMP_Insert_ready_fifo,
227    _Scheduler_SMP_Insert_scheduled_fifo
228  );
229}
230
231static Thread_Control *_Scheduler_simple_SMP_Enqueue_scheduled_ordered(
232  Scheduler_Context *context,
233  Scheduler_Node *node,
234  Chain_Node_order order,
235  Scheduler_SMP_Insert insert_ready,
236  Scheduler_SMP_Insert insert_scheduled
237)
238{
239  return _Scheduler_SMP_Enqueue_scheduled_ordered(
240    context,
241    node,
242    order,
243    _Scheduler_simple_SMP_Extract_from_ready,
244    _Scheduler_simple_SMP_Get_highest_ready,
245    insert_ready,
246    insert_scheduled,
247    _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
248    _Scheduler_SMP_Allocate_processor_lazy
249  );
250}
251
252static Thread_Control *_Scheduler_simple_SMP_Enqueue_scheduled_lifo(
253  Scheduler_Context *context,
254  Scheduler_Node *node
255)
256{
257  return _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
258    context,
259    node,
260    _Scheduler_SMP_Insert_priority_lifo_order,
261    _Scheduler_simple_SMP_Insert_ready_lifo,
262    _Scheduler_SMP_Insert_scheduled_lifo
263  );
264}
265
266static Thread_Control *_Scheduler_simple_SMP_Enqueue_scheduled_fifo(
267  Scheduler_Context *context,
268  Scheduler_Node *node
269)
270{
271  return _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
272    context,
273    node,
274    _Scheduler_SMP_Insert_priority_fifo_order,
275    _Scheduler_simple_SMP_Insert_ready_fifo,
276    _Scheduler_SMP_Insert_scheduled_fifo
277  );
278}
279
280Thread_Control *_Scheduler_simple_SMP_Unblock(
281  const Scheduler_Control *scheduler,
282  Thread_Control *thread
283)
284{
285  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
286
287  return _Scheduler_SMP_Unblock(
288    context,
289    thread,
290    _Scheduler_simple_SMP_Do_update,
291    _Scheduler_simple_SMP_Enqueue_fifo
292  );
293}
294
295Thread_Control *_Scheduler_simple_SMP_Update_priority(
296  const Scheduler_Control *scheduler,
297  Thread_Control          *thread
298)
299{
300  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
301
302  return _Scheduler_SMP_Update_priority(
303    context,
304    thread,
305    _Scheduler_simple_SMP_Extract_from_ready,
306    _Scheduler_simple_SMP_Do_update,
307    _Scheduler_simple_SMP_Enqueue_fifo,
308    _Scheduler_simple_SMP_Enqueue_lifo,
309    _Scheduler_simple_SMP_Enqueue_scheduled_fifo,
310    _Scheduler_simple_SMP_Enqueue_scheduled_lifo
311  );
312}
313
314Thread_Control *_Scheduler_simple_SMP_Ask_for_help(
315  const Scheduler_Control *scheduler,
316  Thread_Control          *offers_help,
317  Thread_Control          *needs_help
318)
319{
320  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
321
322  return _Scheduler_SMP_Ask_for_help(
323    context,
324    offers_help,
325    needs_help,
326    _Scheduler_simple_SMP_Enqueue_fifo
327  );
328}
329
330Thread_Control *_Scheduler_simple_SMP_Yield(
331  const Scheduler_Control *scheduler,
332  Thread_Control *thread
333)
334{
335  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
336
337  return _Scheduler_SMP_Yield(
338    context,
339    thread,
340    _Scheduler_simple_SMP_Extract_from_ready,
341    _Scheduler_simple_SMP_Enqueue_fifo,
342    _Scheduler_simple_SMP_Enqueue_scheduled_fifo
343  );
344}
Note: See TracBrowser for help on using the repository browser.