source: rtems/cpukit/score/src/schedulerprioritysmp.c @ 3733b224

4.115
Last change on this file since 3733b224 was 3733b224, checked in by Sebastian Huber <sebastian.huber@…>, on 05/15/14 at 06:46:56

score: Add and use _Scheduler_default_Schedule()

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