source: rtems/cpukit/score/src/schedulerprioritysmp.c @ 3730a07f

4.115
Last change on this file since 3730a07f was 3730a07f, checked in by Sebastian Huber <sebastian.huber@…>, on 05/13/14 at 13:08:07

score: Use Scheduler_Context for SMP scheduler

Use the basic Scheduler_Context for the general SMP scheduler operations
to avoid usage of structure offsets to get the specialized context
variants.

  • Property mode set to 100644
File size: 8.0 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ScoreSchedulerPrioritySMP
5 *
6 * @brief Deterministic Priority SMP Scheduler Implementation
7 */
8
9/*
10 * Copyright (c) 2013-2014 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/schedulerprioritysmp.h>
28#include <rtems/score/schedulerpriorityimpl.h>
29#include <rtems/score/schedulersmpimpl.h>
30#include <rtems/score/wkspace.h>
31
32static Scheduler_priority_SMP_Context *
33_Scheduler_priority_SMP_Get_context( const Scheduler_Control *scheduler )
34{
35  return (Scheduler_priority_SMP_Context *) scheduler->context;
36}
37
38static Scheduler_priority_SMP_Context *
39_Scheduler_priority_SMP_Get_self( Scheduler_Context *context )
40{
41  return (Scheduler_priority_SMP_Context *) context;
42}
43
44static Scheduler_priority_SMP_Node *_Scheduler_priority_SMP_Node_get(
45  Thread_Control *thread
46)
47{
48  return (Scheduler_priority_SMP_Node *) _Scheduler_Node_get( thread );
49}
50
51void _Scheduler_priority_SMP_Initialize( const Scheduler_Control *scheduler )
52{
53  Scheduler_priority_SMP_Context *self =
54    _Scheduler_priority_SMP_Get_context( scheduler );
55
56  _Scheduler_SMP_Initialize( &self->Base );
57  _Priority_bit_map_Initialize( &self->Bit_map );
58  _Scheduler_priority_Ready_queue_initialize( &self->Ready[ 0 ] );
59}
60
61bool _Scheduler_priority_SMP_Allocate(
62  const Scheduler_Control *scheduler,
63  Thread_Control *thread
64)
65{
66  Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
67
68  _Scheduler_SMP_Node_initialize( node );
69
70  return true;
71}
72
73void _Scheduler_priority_SMP_Update(
74  const Scheduler_Control *scheduler,
75  Thread_Control *thread
76)
77{
78  Scheduler_priority_SMP_Context *self =
79    _Scheduler_priority_SMP_Get_context( scheduler );
80  Scheduler_priority_SMP_Node *node =
81    _Scheduler_priority_SMP_Node_get( thread );
82
83  _Scheduler_priority_Ready_queue_update(
84    thread,
85    &node->Ready_queue,
86    &self->Bit_map,
87    &self->Ready[ 0 ]
88  );
89}
90
91static Thread_Control *_Scheduler_priority_SMP_Get_highest_ready(
92  Scheduler_Context *context
93)
94{
95  Scheduler_priority_SMP_Context *self =
96    _Scheduler_priority_SMP_Get_self( context );
97  Thread_Control *highest_ready = NULL;
98
99  if ( !_Priority_bit_map_Is_empty( &self->Bit_map ) ) {
100    highest_ready = _Scheduler_priority_Ready_queue_first(
101      &self->Bit_map,
102      &self->Ready[ 0 ]
103    );
104  }
105
106  return highest_ready;
107}
108
109static void _Scheduler_priority_SMP_Move_from_scheduled_to_ready(
110  Scheduler_Context *context,
111  Thread_Control *scheduled_to_ready
112)
113{
114  Scheduler_priority_SMP_Context *self =
115    _Scheduler_priority_SMP_Get_self( context );
116  Scheduler_priority_SMP_Node *node =
117    _Scheduler_priority_SMP_Node_get( scheduled_to_ready );
118
119  _Chain_Extract_unprotected( &scheduled_to_ready->Object.Node );
120  _Scheduler_priority_Ready_queue_enqueue_first(
121    scheduled_to_ready,
122    &node->Ready_queue,
123    &self->Bit_map
124  );
125}
126
127static void _Scheduler_priority_SMP_Move_from_ready_to_scheduled(
128  Scheduler_Context *context,
129  Thread_Control *ready_to_scheduled
130)
131{
132  Scheduler_priority_SMP_Context *self =
133    _Scheduler_priority_SMP_Get_self( context );
134  Scheduler_priority_SMP_Node *node =
135    _Scheduler_priority_SMP_Node_get( ready_to_scheduled );
136
137  _Scheduler_priority_Ready_queue_extract(
138    ready_to_scheduled,
139    &node->Ready_queue,
140    &self->Bit_map
141  );
142  _Scheduler_simple_Insert_priority_fifo(
143    &self->Base.Scheduled,
144    ready_to_scheduled
145  );
146}
147
148static void _Scheduler_priority_SMP_Insert_ready_lifo(
149  Scheduler_Context *context,
150  Thread_Control *thread
151)
152{
153  Scheduler_priority_SMP_Context *self =
154    _Scheduler_priority_SMP_Get_self( context );
155  Scheduler_priority_SMP_Node *node =
156    _Scheduler_priority_SMP_Node_get( thread );
157
158  _Scheduler_priority_Ready_queue_enqueue(
159    thread,
160    &node->Ready_queue,
161    &self->Bit_map
162  );
163}
164
165static void _Scheduler_priority_SMP_Insert_ready_fifo(
166  Scheduler_Context *context,
167  Thread_Control *thread
168)
169{
170  Scheduler_priority_SMP_Context *self =
171    _Scheduler_priority_SMP_Get_self( context );
172  Scheduler_priority_SMP_Node *node =
173    _Scheduler_priority_SMP_Node_get( thread );
174
175  _Scheduler_priority_Ready_queue_enqueue_first(
176    thread,
177    &node->Ready_queue,
178    &self->Bit_map
179  );
180}
181
182static void _Scheduler_priority_SMP_Do_extract(
183  Scheduler_Context *context,
184  Thread_Control *thread
185)
186{
187  Scheduler_priority_SMP_Context *self =
188    _Scheduler_priority_SMP_Get_self( context );
189  Scheduler_priority_SMP_Node *node =
190    _Scheduler_priority_SMP_Node_get( thread );
191
192  if ( node->Base.state == SCHEDULER_SMP_NODE_SCHEDULED ) {
193    _Scheduler_SMP_Node_change_state(
194      &node->Base,
195      SCHEDULER_SMP_NODE_IN_THE_AIR
196    );
197    _Chain_Extract_unprotected( &thread->Object.Node );
198  } else {
199    _Scheduler_SMP_Node_change_state(
200      &node->Base,
201      SCHEDULER_SMP_NODE_BLOCKED
202    );
203    _Scheduler_priority_Ready_queue_extract(
204      thread,
205      &node->Ready_queue,
206      &self->Bit_map
207    );
208  }
209}
210
211void _Scheduler_priority_SMP_Block(
212  const Scheduler_Control *scheduler,
213  Thread_Control *thread
214)
215{
216  Scheduler_priority_SMP_Context *self =
217    _Scheduler_priority_SMP_Get_context( scheduler );
218
219  _Scheduler_SMP_Block(
220    &self->Base.Base,
221    thread,
222    _Scheduler_priority_SMP_Do_extract,
223    _Scheduler_priority_SMP_Get_highest_ready,
224    _Scheduler_priority_SMP_Move_from_ready_to_scheduled
225  );
226}
227
228static void _Scheduler_priority_SMP_Enqueue_ordered(
229  Scheduler_Context *context,
230  Thread_Control *thread,
231  Chain_Node_order order,
232  Scheduler_SMP_Insert insert_ready,
233  Scheduler_SMP_Insert insert_scheduled
234)
235{
236  _Scheduler_SMP_Enqueue_ordered(
237    context,
238    thread,
239    order,
240    _Scheduler_priority_SMP_Get_highest_ready,
241    insert_ready,
242    insert_scheduled,
243    _Scheduler_priority_SMP_Move_from_ready_to_scheduled,
244    _Scheduler_priority_SMP_Move_from_scheduled_to_ready
245  );
246}
247
248void _Scheduler_priority_SMP_Enqueue_lifo(
249  const Scheduler_Control *scheduler,
250  Thread_Control *thread
251)
252{
253  Scheduler_priority_SMP_Context *self =
254    _Scheduler_priority_SMP_Get_context( scheduler );
255
256  _Scheduler_priority_SMP_Enqueue_ordered(
257    &self->Base.Base,
258    thread,
259    _Scheduler_simple_Insert_priority_lifo_order,
260    _Scheduler_priority_SMP_Insert_ready_lifo,
261    _Scheduler_SMP_Insert_scheduled_lifo
262  );
263}
264
265void _Scheduler_priority_SMP_Enqueue_fifo(
266  const Scheduler_Control *scheduler,
267  Thread_Control *thread
268)
269{
270  Scheduler_priority_SMP_Context *self =
271    _Scheduler_priority_SMP_Get_context( scheduler );
272
273  _Scheduler_priority_SMP_Enqueue_ordered(
274    &self->Base.Base,
275    thread,
276    _Scheduler_simple_Insert_priority_fifo_order,
277    _Scheduler_priority_SMP_Insert_ready_fifo,
278    _Scheduler_SMP_Insert_scheduled_fifo
279  );
280}
281
282void _Scheduler_priority_SMP_Extract(
283  const Scheduler_Control *scheduler,
284  Thread_Control *thread
285)
286{
287  Scheduler_priority_SMP_Context *self =
288    _Scheduler_priority_SMP_Get_context( scheduler );
289
290  _Scheduler_SMP_Extract(
291    &self->Base.Base,
292    thread,
293    _Scheduler_priority_SMP_Do_extract
294  );
295}
296
297void _Scheduler_priority_SMP_Yield(
298  const Scheduler_Control *scheduler,
299  Thread_Control *thread
300)
301{
302  ISR_Level level;
303
304  _ISR_Disable( level );
305
306  _Scheduler_priority_SMP_Extract( scheduler, thread );
307  _Scheduler_priority_SMP_Enqueue_fifo( scheduler, thread );
308
309  _ISR_Enable( level );
310}
311
312void _Scheduler_priority_SMP_Schedule(
313  const Scheduler_Control *scheduler,
314  Thread_Control *thread
315)
316{
317  Scheduler_priority_SMP_Context *self =
318    _Scheduler_priority_SMP_Get_context( scheduler );
319
320  _Scheduler_SMP_Schedule(
321    &self->Base.Base,
322    thread,
323    _Scheduler_priority_SMP_Get_highest_ready,
324    _Scheduler_priority_SMP_Move_from_ready_to_scheduled
325  );
326}
327
328void _Scheduler_priority_SMP_Start_idle(
329  const Scheduler_Control *scheduler,
330  Thread_Control *thread,
331  Per_CPU_Control *cpu
332)
333{
334  Scheduler_priority_SMP_Context *self =
335    _Scheduler_priority_SMP_Get_context( scheduler );
336
337  _Scheduler_SMP_Start_idle( &self->Base.Base, thread, cpu );
338}
Note: See TracBrowser for help on using the repository browser.