source: rtems/cpukit/score/src/schedulersimplesmp.c @ 24934e36

4.115
Last change on this file since 24934e36 was 24934e36, checked in by Sebastian Huber <sebastian.huber@…>, on 04/03/14 at 13:03:35

score: Add scheduler control to scheduler ops

Scheduler operations must be free of a global scheduler context to
enable partitioned/clustered scheduling.

  • Property mode set to 100644
File size: 6.0 KB
Line 
1/**
2 * @file
3 *
4 * @brief Simple SMP Scheduler Implementation
5 *
6 * @ingroup ScoreSchedulerSMP
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#include <rtems/score/wkspace.h>
24
25static Scheduler_simple_SMP_Control *
26_Scheduler_simple_SMP_Self_from_base( Scheduler_Control *base )
27{
28  return (Scheduler_simple_SMP_Control *) base->information;
29}
30
31static Scheduler_simple_SMP_Control *
32_Scheduler_simple_SMP_Self_from_SMP_base( Scheduler_SMP_Control *smp_base )
33{
34  return (Scheduler_simple_SMP_Control *)
35    ( (char *) smp_base - offsetof( Scheduler_simple_SMP_Control, Base ) );
36}
37
38void _Scheduler_simple_smp_Initialize( void )
39{
40  Scheduler_simple_SMP_Control *self =
41    _Workspace_Allocate_or_fatal_error( sizeof( *self ) );
42
43  _Scheduler_SMP_Initialize( &self->Base );
44  _Chain_Initialize_empty( &self->Ready );
45
46  _Scheduler.information = self;
47}
48
49static Thread_Control *_Scheduler_simple_smp_Get_highest_ready(
50  Scheduler_SMP_Control *smp_base
51)
52{
53  Scheduler_simple_SMP_Control *self =
54    _Scheduler_simple_SMP_Self_from_SMP_base( smp_base );
55  Thread_Control *highest_ready = NULL;
56  Chain_Control *ready = &self->Ready;
57
58  if ( !_Chain_Is_empty( ready ) ) {
59    highest_ready = (Thread_Control *) _Chain_First( ready );
60  }
61
62  return highest_ready;
63}
64
65static void _Scheduler_simple_smp_Move_from_scheduled_to_ready(
66  Scheduler_SMP_Control *smp_base,
67  Thread_Control *scheduled_to_ready
68)
69{
70  Scheduler_simple_SMP_Control *self =
71    _Scheduler_simple_SMP_Self_from_SMP_base( smp_base );
72
73  _Chain_Extract_unprotected( &scheduled_to_ready->Object.Node );
74  _Scheduler_simple_Insert_priority_lifo(
75    &self->Ready,
76    scheduled_to_ready
77  );
78}
79
80static void _Scheduler_simple_smp_Move_from_ready_to_scheduled(
81  Scheduler_SMP_Control *smp_base,
82  Thread_Control *ready_to_scheduled
83)
84{
85  _Chain_Extract_unprotected( &ready_to_scheduled->Object.Node );
86  _Scheduler_simple_Insert_priority_fifo(
87    &smp_base->Scheduled,
88    ready_to_scheduled
89  );
90}
91
92static void _Scheduler_simple_smp_Insert_ready_lifo(
93  Scheduler_SMP_Control *smp_base,
94  Thread_Control *thread
95)
96{
97  Scheduler_simple_SMP_Control *self =
98    _Scheduler_simple_SMP_Self_from_SMP_base( smp_base );
99
100  _Chain_Insert_ordered_unprotected(
101    &self->Ready,
102    &thread->Object.Node,
103    _Scheduler_simple_Insert_priority_lifo_order
104  );
105}
106
107static void _Scheduler_simple_smp_Insert_ready_fifo(
108  Scheduler_SMP_Control *smp_base,
109  Thread_Control *thread
110)
111{
112  Scheduler_simple_SMP_Control *self =
113    _Scheduler_simple_SMP_Self_from_SMP_base( smp_base );
114
115  _Chain_Insert_ordered_unprotected(
116    &self->Ready,
117    &thread->Object.Node,
118    _Scheduler_simple_Insert_priority_fifo_order
119  );
120}
121
122static void _Scheduler_simple_smp_Do_extract(
123  Scheduler_SMP_Control *smp_base,
124  Thread_Control *thread
125)
126{
127  (void) smp_base;
128
129  thread->is_in_the_air = thread->is_scheduled;
130  thread->is_scheduled = false;
131
132  _Chain_Extract_unprotected( &thread->Object.Node );
133}
134
135void _Scheduler_simple_smp_Block(
136  Scheduler_Control *base,
137  Thread_Control *thread
138)
139{
140  Scheduler_simple_SMP_Control *self =
141    _Scheduler_simple_SMP_Self_from_base( base );
142
143  _Scheduler_SMP_Block(
144    &self->Base,
145    thread,
146    _Scheduler_simple_smp_Do_extract,
147    _Scheduler_simple_smp_Get_highest_ready,
148    _Scheduler_simple_smp_Move_from_ready_to_scheduled
149  );
150}
151
152static void _Scheduler_simple_smp_Enqueue_ordered(
153  Scheduler_SMP_Control *smp_base,
154  Thread_Control *thread,
155  Chain_Node_order order,
156  Scheduler_SMP_Insert insert_ready,
157  Scheduler_SMP_Insert insert_scheduled
158)
159{
160  _Scheduler_SMP_Enqueue_ordered(
161    smp_base,
162    thread,
163    order,
164    _Scheduler_simple_smp_Get_highest_ready,
165    insert_ready,
166    insert_scheduled,
167    _Scheduler_simple_smp_Move_from_ready_to_scheduled,
168    _Scheduler_simple_smp_Move_from_scheduled_to_ready
169  );
170}
171
172void _Scheduler_simple_smp_Enqueue_priority_lifo(
173  Scheduler_Control *base,
174  Thread_Control *thread
175)
176{
177  Scheduler_simple_SMP_Control *self =
178    _Scheduler_simple_SMP_Self_from_base( base );
179
180  _Scheduler_simple_smp_Enqueue_ordered(
181    &self->Base,
182    thread,
183    _Scheduler_simple_Insert_priority_lifo_order,
184    _Scheduler_simple_smp_Insert_ready_lifo,
185    _Scheduler_SMP_Insert_scheduled_lifo
186  );
187}
188
189void _Scheduler_simple_smp_Enqueue_priority_fifo(
190  Scheduler_Control *base,
191  Thread_Control *thread
192)
193{
194  Scheduler_simple_SMP_Control *self =
195    _Scheduler_simple_SMP_Self_from_base( base );
196
197  _Scheduler_simple_smp_Enqueue_ordered(
198    &self->Base,
199    thread,
200    _Scheduler_simple_Insert_priority_fifo_order,
201    _Scheduler_simple_smp_Insert_ready_fifo,
202    _Scheduler_SMP_Insert_scheduled_fifo
203  );
204}
205
206void _Scheduler_simple_smp_Extract(
207  Scheduler_Control *base,
208  Thread_Control *thread
209)
210{
211  Scheduler_simple_SMP_Control *self =
212    _Scheduler_simple_SMP_Self_from_base( base );
213
214  _Scheduler_SMP_Extract(
215    &self->Base,
216    thread,
217    _Scheduler_simple_smp_Do_extract
218  );
219}
220
221void _Scheduler_simple_smp_Yield(
222  Scheduler_Control *base,
223  Thread_Control *thread
224)
225{
226  ISR_Level level;
227
228  _ISR_Disable( level );
229
230  _Scheduler_simple_smp_Extract( base, thread );
231  _Scheduler_simple_smp_Enqueue_priority_fifo( base, thread );
232
233  _ISR_Enable( level );
234}
235
236void _Scheduler_simple_smp_Schedule(
237  Scheduler_Control *base,
238  Thread_Control *thread
239)
240{
241  Scheduler_simple_SMP_Control *self =
242    _Scheduler_simple_SMP_Self_from_base( base );
243
244  _Scheduler_SMP_Schedule(
245    &self->Base,
246    thread,
247    _Scheduler_simple_smp_Get_highest_ready,
248    _Scheduler_simple_smp_Move_from_ready_to_scheduled
249  );
250}
251
252void _Scheduler_simple_smp_Start_idle(
253  Scheduler_Control *base,
254  Thread_Control *thread,
255  Per_CPU_Control *cpu
256)
257{
258  Scheduler_simple_SMP_Control *self =
259    _Scheduler_simple_SMP_Self_from_base( base );
260
261  _Scheduler_SMP_Start_idle( &self->Base, thread, cpu );
262}
Note: See TracBrowser for help on using the repository browser.