source: rtems/cpukit/score/src/schedulersimplesmp.c @ 63e2ca1b

5
Last change on this file since 63e2ca1b was 63e2ca1b, checked in by Sebastian Huber <sebastian.huber@…>, on 10/31/16 at 08:13:35

score: Simplify yield and unblock scheduler ops

Update #2556.

  • Property mode set to 100644
File size: 9.6 KB
RevLine 
[a936aa49]1/**
2 * @file
3 *
4 * @brief Simple SMP Scheduler Implementation
5 *
[beab7329]6 * @ingroup ScoreSchedulerSMPSimple
[a936aa49]7 */
8
9/*
[351c14d]10 * Copyright (c) 2013, 2016 embedded brains GmbH.
[a936aa49]11 *
12 * The license and distribution terms for this file may be
13 * found in the file LICENSE in this distribution or at
[c499856]14 * http://www.rtems.org/license/LICENSE.
[a936aa49]15 */
16
17#if HAVE_CONFIG_H
18  #include "config.h"
19#endif
20
21#include <rtems/score/schedulersimplesmp.h>
[9d83f58a]22#include <rtems/score/schedulersmpimpl.h>
[a936aa49]23
[e1598a6]24static Scheduler_simple_SMP_Context *
25_Scheduler_simple_SMP_Get_context( const Scheduler_Control *scheduler )
[494c2e3]26{
[2369b10]27  return (Scheduler_simple_SMP_Context *) _Scheduler_Get_context( scheduler );
[494c2e3]28}
29
[e1598a6]30static Scheduler_simple_SMP_Context *
[3730a07f]31_Scheduler_simple_SMP_Get_self( Scheduler_Context *context )
[494c2e3]32{
[3730a07f]33  return (Scheduler_simple_SMP_Context *) context;
[494c2e3]34}
35
[e9ee2f0]36void _Scheduler_simple_SMP_Initialize( const Scheduler_Control *scheduler )
[a936aa49]37{
[e1598a6]38  Scheduler_simple_SMP_Context *self =
39    _Scheduler_simple_SMP_Get_context( scheduler );
[a936aa49]40
[494c2e3]41  _Scheduler_SMP_Initialize( &self->Base );
42  _Chain_Initialize_empty( &self->Ready );
[a936aa49]43}
44
[8e467384]45void _Scheduler_simple_SMP_Node_initialize(
[beab7329]46  const Scheduler_Control *scheduler,
[df2177ab]47  Scheduler_Node          *node,
[9bfad8c]48  Thread_Control          *the_thread,
49  Priority_Control         priority
[beab7329]50)
51{
[351c14d]52  Scheduler_SMP_Node *smp_node;
[beab7329]53
[351c14d]54  smp_node = _Scheduler_SMP_Node_downcast( node );
55  _Scheduler_SMP_Node_initialize( scheduler, smp_node, the_thread, priority );
[beab7329]56}
57
[f39f667a]58static void _Scheduler_simple_SMP_Do_update(
59  Scheduler_Context *context,
[df2177ab]60  Scheduler_Node    *node,
[8f0c7a46]61  Priority_Control   new_priority
[f39f667a]62)
63{
[351c14d]64  Scheduler_SMP_Node *smp_node;
[8f0c7a46]65
[f39f667a]66  (void) context;
[8f0c7a46]67
[351c14d]68  smp_node = _Scheduler_SMP_Node_downcast( node );
69  _Scheduler_SMP_Node_update_priority( smp_node, new_priority );
[f39f667a]70}
71
[8f0c7a46]72static Scheduler_Node *_Scheduler_simple_SMP_Get_highest_ready(
[238629f]73  Scheduler_Context *context,
[8f0c7a46]74  Scheduler_Node    *node
[aea4a91]75)
76{
[e1598a6]77  Scheduler_simple_SMP_Context *self =
[3730a07f]78    _Scheduler_simple_SMP_Get_self( context );
[333f9426]79  Scheduler_Node *first = (Scheduler_Node *) _Chain_First( &self->Ready );
[aea4a91]80
[8f0c7a46]81  (void) node;
[238629f]82
[333f9426]83  _Assert( &first->Node != _Chain_Tail( &self->Ready ) );
84
85  return first;
[aea4a91]86}
87
[e9ee2f0]88static void _Scheduler_simple_SMP_Move_from_scheduled_to_ready(
[3730a07f]89  Scheduler_Context *context,
[8f0c7a46]90  Scheduler_Node    *scheduled_to_ready
[a936aa49]91)
92{
[e1598a6]93  Scheduler_simple_SMP_Context *self =
[3730a07f]94    _Scheduler_simple_SMP_Get_self( context );
[494c2e3]95
[8f0c7a46]96  _Chain_Extract_unprotected( &scheduled_to_ready->Node );
97  _Chain_Insert_ordered_unprotected(
[494c2e3]98    &self->Ready,
[8f0c7a46]99    &scheduled_to_ready->Node,
100    _Scheduler_SMP_Insert_priority_lifo_order
[aea4a91]101  );
[a936aa49]102}
103
[e9ee2f0]104static void _Scheduler_simple_SMP_Move_from_ready_to_scheduled(
[3730a07f]105  Scheduler_Context *context,
[8f0c7a46]106  Scheduler_Node    *ready_to_scheduled
[a936aa49]107)
108{
[3730a07f]109  Scheduler_simple_SMP_Context *self =
110    _Scheduler_simple_SMP_Get_self( context );
111
[8f0c7a46]112  _Chain_Extract_unprotected( &ready_to_scheduled->Node );
113  _Chain_Insert_ordered_unprotected(
[3730a07f]114    &self->Base.Scheduled,
[8f0c7a46]115    &ready_to_scheduled->Node,
116    _Scheduler_SMP_Insert_priority_fifo_order
[aea4a91]117  );
[a936aa49]118}
119
[e9ee2f0]120static void _Scheduler_simple_SMP_Insert_ready_lifo(
[3730a07f]121  Scheduler_Context *context,
[8f0c7a46]122  Scheduler_Node    *node_to_insert
[a936aa49]123)
124{
[e1598a6]125  Scheduler_simple_SMP_Context *self =
[3730a07f]126    _Scheduler_simple_SMP_Get_self( context );
[494c2e3]127
[48c4a55]128  _Chain_Insert_ordered_unprotected(
[494c2e3]129    &self->Ready,
[8f0c7a46]130    &node_to_insert->Node,
131    _Scheduler_SMP_Insert_priority_lifo_order
[48c4a55]132  );
[a936aa49]133}
134
[e9ee2f0]135static void _Scheduler_simple_SMP_Insert_ready_fifo(
[3730a07f]136  Scheduler_Context *context,
[8f0c7a46]137  Scheduler_Node    *node_to_insert
[aea4a91]138)
139{
[e1598a6]140  Scheduler_simple_SMP_Context *self =
[3730a07f]141    _Scheduler_simple_SMP_Get_self( context );
[494c2e3]142
[48c4a55]143  _Chain_Insert_ordered_unprotected(
[494c2e3]144    &self->Ready,
[8f0c7a46]145    &node_to_insert->Node,
146    _Scheduler_SMP_Insert_priority_fifo_order
[48c4a55]147  );
[aea4a91]148}
149
[f39f667a]150static void _Scheduler_simple_SMP_Extract_from_ready(
[3730a07f]151  Scheduler_Context *context,
[8f0c7a46]152  Scheduler_Node    *node_to_extract
[a936aa49]153)
154{
[3730a07f]155  (void) context;
[a936aa49]156
[8f0c7a46]157  _Chain_Extract_unprotected( &node_to_extract->Node );
[aea4a91]158}
[a936aa49]159
[e9ee2f0]160void _Scheduler_simple_SMP_Block(
[e1598a6]161  const Scheduler_Control *scheduler,
[e382a1b]162  Thread_Control          *thread,
163  Scheduler_Node          *node
[24934e36]164)
[aea4a91]165{
[f39f667a]166  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
[a936aa49]167
[48c4a55]168  _Scheduler_SMP_Block(
[f39f667a]169    context,
[48c4a55]170    thread,
[e382a1b]171    node,
[f39f667a]172    _Scheduler_simple_SMP_Extract_from_ready,
[e9ee2f0]173    _Scheduler_simple_SMP_Get_highest_ready,
[238629f]174    _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
[27783f6]175    _Scheduler_SMP_Allocate_processor_lazy
[48c4a55]176  );
177}
[a936aa49]178
[63e2ca1b]179static bool _Scheduler_simple_SMP_Enqueue_ordered(
[8568341]180  Scheduler_Context    *context,
181  Scheduler_Node       *node,
182  Chain_Node_order      order,
183  Scheduler_SMP_Insert  insert_ready,
184  Scheduler_SMP_Insert  insert_scheduled
[48c4a55]185)
186{
[8568341]187  return _Scheduler_SMP_Enqueue_ordered(
[3730a07f]188    context,
[8f0c7a46]189    node,
[48c4a55]190    order,
191    insert_ready,
192    insert_scheduled,
[238629f]193    _Scheduler_simple_SMP_Move_from_scheduled_to_ready,
194    _Scheduler_SMP_Get_lowest_scheduled,
[27783f6]195    _Scheduler_SMP_Allocate_processor_lazy
[48c4a55]196  );
[a936aa49]197}
198
[63e2ca1b]199static bool _Scheduler_simple_SMP_Enqueue_lifo(
[f39f667a]200  Scheduler_Context *context,
[63e2ca1b]201  Scheduler_Node    *node
[24934e36]202)
[a936aa49]203{
[8568341]204  return _Scheduler_simple_SMP_Enqueue_ordered(
[f39f667a]205    context,
[8f0c7a46]206    node,
207    _Scheduler_SMP_Insert_priority_lifo_order,
[e9ee2f0]208    _Scheduler_simple_SMP_Insert_ready_lifo,
[48c4a55]209    _Scheduler_SMP_Insert_scheduled_lifo
[a936aa49]210  );
211}
212
[63e2ca1b]213static bool _Scheduler_simple_SMP_Enqueue_fifo(
[f39f667a]214  Scheduler_Context *context,
[63e2ca1b]215  Scheduler_Node    *node
[24934e36]216)
[a936aa49]217{
[8568341]218  return _Scheduler_simple_SMP_Enqueue_ordered(
[f39f667a]219    context,
[8f0c7a46]220    node,
221    _Scheduler_SMP_Insert_priority_fifo_order,
[c0bff5e]222    _Scheduler_simple_SMP_Insert_ready_fifo,
223    _Scheduler_SMP_Insert_scheduled_fifo
224  );
225}
226
[63e2ca1b]227static bool _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
[c0bff5e]228  Scheduler_Context *context,
[8f0c7a46]229  Scheduler_Node *node,
[c0bff5e]230  Chain_Node_order order,
231  Scheduler_SMP_Insert insert_ready,
232  Scheduler_SMP_Insert insert_scheduled
233)
234{
[8568341]235  return _Scheduler_SMP_Enqueue_scheduled_ordered(
[c0bff5e]236    context,
[8f0c7a46]237    node,
[c0bff5e]238    order,
[5c3d250]239    _Scheduler_simple_SMP_Extract_from_ready,
[c0bff5e]240    _Scheduler_simple_SMP_Get_highest_ready,
241    insert_ready,
242    insert_scheduled,
[238629f]243    _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
[27783f6]244    _Scheduler_SMP_Allocate_processor_lazy
[c0bff5e]245  );
246}
247
[63e2ca1b]248static bool _Scheduler_simple_SMP_Enqueue_scheduled_lifo(
[c0bff5e]249  Scheduler_Context *context,
[8f0c7a46]250  Scheduler_Node *node
[c0bff5e]251)
252{
[8568341]253  return _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
[c0bff5e]254    context,
[8f0c7a46]255    node,
256    _Scheduler_SMP_Insert_priority_lifo_order,
[c0bff5e]257    _Scheduler_simple_SMP_Insert_ready_lifo,
258    _Scheduler_SMP_Insert_scheduled_lifo
259  );
260}
261
[63e2ca1b]262static bool _Scheduler_simple_SMP_Enqueue_scheduled_fifo(
[c0bff5e]263  Scheduler_Context *context,
[8f0c7a46]264  Scheduler_Node *node
[c0bff5e]265)
266{
[8568341]267  return _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
[c0bff5e]268    context,
[8f0c7a46]269    node,
270    _Scheduler_SMP_Insert_priority_fifo_order,
[e9ee2f0]271    _Scheduler_simple_SMP_Insert_ready_fifo,
[48c4a55]272    _Scheduler_SMP_Insert_scheduled_fifo
[a936aa49]273  );
274}
275
[63e2ca1b]276bool _Scheduler_simple_SMP_Unblock(
[e1598a6]277  const Scheduler_Control *scheduler,
[72e0bdb]278  Thread_Control          *thread,
279  Scheduler_Node          *node
[24934e36]280)
[a936aa49]281{
[f39f667a]282  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
283
[8568341]284  return _Scheduler_SMP_Unblock(
[c0bff5e]285    context,
286    thread,
[72e0bdb]287    node,
[9bfad8c]288    _Scheduler_simple_SMP_Do_update,
[27783f6]289    _Scheduler_simple_SMP_Enqueue_fifo
[c0bff5e]290  );
[f39f667a]291}
[a936aa49]292
[351c14d]293static bool _Scheduler_simple_SMP_Do_ask_for_help(
294  Scheduler_Context *context,
295  Thread_Control    *the_thread,
296  Scheduler_Node    *node
297)
298{
299  return _Scheduler_SMP_Ask_for_help(
300    context,
301    the_thread,
302    node,
303    _Scheduler_SMP_Insert_priority_lifo_order,
304    _Scheduler_simple_SMP_Insert_ready_lifo,
305    _Scheduler_SMP_Insert_scheduled_lifo,
306    _Scheduler_simple_SMP_Move_from_scheduled_to_ready,
307    _Scheduler_SMP_Get_lowest_scheduled,
308    _Scheduler_SMP_Allocate_processor_lazy
309  );
310}
311
[9c238e1]312void _Scheduler_simple_SMP_Update_priority(
[f39f667a]313  const Scheduler_Control *scheduler,
[501043a]314  Thread_Control          *thread,
315  Scheduler_Node          *node
[f39f667a]316)
317{
318  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
319
[9c238e1]320  _Scheduler_SMP_Update_priority(
[f39f667a]321    context,
[48c4a55]322    thread,
[501043a]323    node,
[f39f667a]324    _Scheduler_simple_SMP_Extract_from_ready,
325    _Scheduler_simple_SMP_Do_update,
326    _Scheduler_simple_SMP_Enqueue_fifo,
[c0bff5e]327    _Scheduler_simple_SMP_Enqueue_lifo,
328    _Scheduler_simple_SMP_Enqueue_scheduled_fifo,
[351c14d]329    _Scheduler_simple_SMP_Enqueue_scheduled_lifo,
330    _Scheduler_simple_SMP_Do_ask_for_help
331  );
332}
333
334bool _Scheduler_simple_SMP_Ask_for_help(
335  const Scheduler_Control *scheduler,
336  Thread_Control          *the_thread,
337  Scheduler_Node          *node
338)
339{
340  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
341
342  return _Scheduler_simple_SMP_Do_ask_for_help( context, the_thread, node );
343}
344
345void _Scheduler_simple_SMP_Reconsider_help_request(
346  const Scheduler_Control *scheduler,
347  Thread_Control          *the_thread,
348  Scheduler_Node          *node
349)
350{
351  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
352
353  _Scheduler_SMP_Reconsider_help_request(
354    context,
355    the_thread,
356    node,
357    _Scheduler_simple_SMP_Extract_from_ready
358  );
359}
360
361void _Scheduler_simple_SMP_Withdraw_node(
362  const Scheduler_Control *scheduler,
363  Thread_Control          *the_thread,
364  Scheduler_Node          *node,
365  Thread_Scheduler_state   next_state
366)
367{
368  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
369
370  _Scheduler_SMP_Withdraw_node(
371    context,
372    the_thread,
373    node,
374    next_state,
375    _Scheduler_simple_SMP_Extract_from_ready,
376    _Scheduler_simple_SMP_Get_highest_ready,
377    _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
378    _Scheduler_SMP_Allocate_processor_lazy
[48c4a55]379  );
[a936aa49]380}
381
[63e2ca1b]382bool _Scheduler_simple_SMP_Yield(
[e1598a6]383  const Scheduler_Control *scheduler,
[2df4abc]384  Thread_Control          *thread,
385  Scheduler_Node          *node
[24934e36]386)
[a936aa49]387{
[f39f667a]388  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
[a936aa49]389
[701dd96f]390  return _Scheduler_SMP_Yield(
391    context,
392    thread,
[2df4abc]393    node,
[701dd96f]394    _Scheduler_simple_SMP_Extract_from_ready,
395    _Scheduler_simple_SMP_Enqueue_fifo,
396    _Scheduler_simple_SMP_Enqueue_scheduled_fifo
397  );
[a936aa49]398}
Note: See TracBrowser for help on using the repository browser.