source: rtems/cpukit/score/src/schedulersimplesmp.c @ 52f8e90d

4.115
Last change on this file since 52f8e90d was 8568341, checked in by Sebastian Huber <sebastian.huber@…>, on 06/11/14 at 12:31:03

score: Need for help indicator for scheduler ops

Return a thread in need for help for the following scheduler operations

  • unblock,
  • change priority, and
  • yield.

A thread in need for help is a thread that encounters a scheduler state
change from scheduled to ready or a thread that cannot be scheduled in
an unblock operation. Such a thread can ask threads which depend on
resources owned by this thread for help.

  • Property mode set to 100644
File size: 8.1 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_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
88  (void) node;
89
90  return (Scheduler_Node *) _Chain_First( &self->Ready );
91}
92
93static void _Scheduler_simple_SMP_Move_from_scheduled_to_ready(
94  Scheduler_Context *context,
95  Scheduler_Node    *scheduled_to_ready
96)
97{
98  Scheduler_simple_SMP_Context *self =
99    _Scheduler_simple_SMP_Get_self( context );
100
101  _Chain_Extract_unprotected( &scheduled_to_ready->Node );
102  _Chain_Insert_ordered_unprotected(
103    &self->Ready,
104    &scheduled_to_ready->Node,
105    _Scheduler_SMP_Insert_priority_lifo_order
106  );
107}
108
109static void _Scheduler_simple_SMP_Move_from_ready_to_scheduled(
110  Scheduler_Context *context,
111  Scheduler_Node    *ready_to_scheduled
112)
113{
114  Scheduler_simple_SMP_Context *self =
115    _Scheduler_simple_SMP_Get_self( context );
116
117  _Chain_Extract_unprotected( &ready_to_scheduled->Node );
118  _Chain_Insert_ordered_unprotected(
119    &self->Base.Scheduled,
120    &ready_to_scheduled->Node,
121    _Scheduler_SMP_Insert_priority_fifo_order
122  );
123}
124
125static void _Scheduler_simple_SMP_Insert_ready_lifo(
126  Scheduler_Context *context,
127  Scheduler_Node    *node_to_insert
128)
129{
130  Scheduler_simple_SMP_Context *self =
131    _Scheduler_simple_SMP_Get_self( context );
132
133  _Chain_Insert_ordered_unprotected(
134    &self->Ready,
135    &node_to_insert->Node,
136    _Scheduler_SMP_Insert_priority_lifo_order
137  );
138}
139
140static void _Scheduler_simple_SMP_Insert_ready_fifo(
141  Scheduler_Context *context,
142  Scheduler_Node    *node_to_insert
143)
144{
145  Scheduler_simple_SMP_Context *self =
146    _Scheduler_simple_SMP_Get_self( context );
147
148  _Chain_Insert_ordered_unprotected(
149    &self->Ready,
150    &node_to_insert->Node,
151    _Scheduler_SMP_Insert_priority_fifo_order
152  );
153}
154
155static void _Scheduler_simple_SMP_Extract_from_ready(
156  Scheduler_Context *context,
157  Scheduler_Node    *node_to_extract
158)
159{
160  (void) context;
161
162  _Chain_Extract_unprotected( &node_to_extract->Node );
163}
164
165void _Scheduler_simple_SMP_Block(
166  const Scheduler_Control *scheduler,
167  Thread_Control *thread
168)
169{
170  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
171
172  _Scheduler_SMP_Block(
173    context,
174    thread,
175    _Scheduler_simple_SMP_Extract_from_ready,
176    _Scheduler_simple_SMP_Get_highest_ready,
177    _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
178    _Scheduler_SMP_Allocate_processor_lazy
179  );
180}
181
182static Thread_Control *_Scheduler_simple_SMP_Enqueue_ordered(
183  Scheduler_Context    *context,
184  Scheduler_Node       *node,
185  Thread_Control       *needs_help,
186  Chain_Node_order      order,
187  Scheduler_SMP_Insert  insert_ready,
188  Scheduler_SMP_Insert  insert_scheduled
189)
190{
191  return _Scheduler_SMP_Enqueue_ordered(
192    context,
193    node,
194    needs_help,
195    order,
196    insert_ready,
197    insert_scheduled,
198    _Scheduler_simple_SMP_Move_from_scheduled_to_ready,
199    _Scheduler_SMP_Get_lowest_scheduled,
200    _Scheduler_SMP_Allocate_processor_lazy
201  );
202}
203
204static Thread_Control *_Scheduler_simple_SMP_Enqueue_lifo(
205  Scheduler_Context *context,
206  Scheduler_Node    *node,
207  Thread_Control    *needs_help
208)
209{
210  return _Scheduler_simple_SMP_Enqueue_ordered(
211    context,
212    node,
213    needs_help,
214    _Scheduler_SMP_Insert_priority_lifo_order,
215    _Scheduler_simple_SMP_Insert_ready_lifo,
216    _Scheduler_SMP_Insert_scheduled_lifo
217  );
218}
219
220static Thread_Control *_Scheduler_simple_SMP_Enqueue_fifo(
221  Scheduler_Context *context,
222  Scheduler_Node    *node,
223  Thread_Control    *needs_help
224)
225{
226  return _Scheduler_simple_SMP_Enqueue_ordered(
227    context,
228    node,
229    needs_help,
230    _Scheduler_SMP_Insert_priority_fifo_order,
231    _Scheduler_simple_SMP_Insert_ready_fifo,
232    _Scheduler_SMP_Insert_scheduled_fifo
233  );
234}
235
236static Thread_Control *_Scheduler_simple_SMP_Enqueue_scheduled_ordered(
237  Scheduler_Context *context,
238  Scheduler_Node *node,
239  Chain_Node_order order,
240  Scheduler_SMP_Insert insert_ready,
241  Scheduler_SMP_Insert insert_scheduled
242)
243{
244  return _Scheduler_SMP_Enqueue_scheduled_ordered(
245    context,
246    node,
247    order,
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 Thread_Control *_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 Thread_Control *_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
284Thread_Control *_Scheduler_simple_SMP_Unblock(
285  const Scheduler_Control *scheduler,
286  Thread_Control *thread
287)
288{
289  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
290
291  return _Scheduler_SMP_Unblock(
292    context,
293    thread,
294    _Scheduler_simple_SMP_Enqueue_fifo
295  );
296}
297
298Thread_Control *_Scheduler_simple_SMP_Change_priority(
299  const Scheduler_Control *scheduler,
300  Thread_Control          *thread,
301  Priority_Control         new_priority,
302  bool                     prepend_it
303)
304{
305  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
306
307  return _Scheduler_SMP_Change_priority(
308    context,
309    thread,
310    new_priority,
311    prepend_it,
312    _Scheduler_simple_SMP_Extract_from_ready,
313    _Scheduler_simple_SMP_Do_update,
314    _Scheduler_simple_SMP_Enqueue_fifo,
315    _Scheduler_simple_SMP_Enqueue_lifo,
316    _Scheduler_simple_SMP_Enqueue_scheduled_fifo,
317    _Scheduler_simple_SMP_Enqueue_scheduled_lifo
318  );
319}
320
321Thread_Control *_Scheduler_simple_SMP_Yield(
322  const Scheduler_Control *scheduler,
323  Thread_Control *thread
324)
325{
326  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
327
328  return _Scheduler_SMP_Yield(
329    context,
330    thread,
331    _Scheduler_simple_SMP_Extract_from_ready,
332    _Scheduler_simple_SMP_Enqueue_fifo,
333    _Scheduler_simple_SMP_Enqueue_scheduled_fifo
334  );
335}
Note: See TracBrowser for help on using the repository browser.