source: rtems/cpukit/score/src/schedulersimplesmp.c @ 0daa8ab

5
Last change on this file since 0daa8ab was 34487537, checked in by Sebastian Huber <sebastian.huber@…>, on 07/04/17 at 07:57:30

score: Add simple affinity support to EDF SMP

Update #3059.

  • Property mode set to 100644
File size: 10.5 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
[05ca53d]72static bool _Scheduler_simple_SMP_Has_ready( Scheduler_Context *context )
73{
74  Scheduler_simple_SMP_Context *self =
75    _Scheduler_simple_SMP_Get_self( context );
76
77  return !_Chain_Is_empty( &self->Ready );
78}
79
[8f0c7a46]80static Scheduler_Node *_Scheduler_simple_SMP_Get_highest_ready(
[238629f]81  Scheduler_Context *context,
[8f0c7a46]82  Scheduler_Node    *node
[aea4a91]83)
84{
[e1598a6]85  Scheduler_simple_SMP_Context *self =
[3730a07f]86    _Scheduler_simple_SMP_Get_self( context );
[333f9426]87  Scheduler_Node *first = (Scheduler_Node *) _Chain_First( &self->Ready );
[aea4a91]88
[8f0c7a46]89  (void) node;
[238629f]90
[15dbc710]91  _Assert( &first->Node.Chain != _Chain_Tail( &self->Ready ) );
[333f9426]92
93  return first;
[aea4a91]94}
95
[e9ee2f0]96static void _Scheduler_simple_SMP_Move_from_scheduled_to_ready(
[3730a07f]97  Scheduler_Context *context,
[8f0c7a46]98  Scheduler_Node    *scheduled_to_ready
[a936aa49]99)
100{
[e1598a6]101  Scheduler_simple_SMP_Context *self =
[3730a07f]102    _Scheduler_simple_SMP_Get_self( context );
[494c2e3]103
[15dbc710]104  _Chain_Extract_unprotected( &scheduled_to_ready->Node.Chain );
[8f0c7a46]105  _Chain_Insert_ordered_unprotected(
[494c2e3]106    &self->Ready,
[15dbc710]107    &scheduled_to_ready->Node.Chain,
[8f0c7a46]108    _Scheduler_SMP_Insert_priority_lifo_order
[aea4a91]109  );
[a936aa49]110}
111
[e9ee2f0]112static void _Scheduler_simple_SMP_Move_from_ready_to_scheduled(
[3730a07f]113  Scheduler_Context *context,
[8f0c7a46]114  Scheduler_Node    *ready_to_scheduled
[a936aa49]115)
116{
[3730a07f]117  Scheduler_simple_SMP_Context *self =
118    _Scheduler_simple_SMP_Get_self( context );
119
[15dbc710]120  _Chain_Extract_unprotected( &ready_to_scheduled->Node.Chain );
[8f0c7a46]121  _Chain_Insert_ordered_unprotected(
[3730a07f]122    &self->Base.Scheduled,
[15dbc710]123    &ready_to_scheduled->Node.Chain,
[8f0c7a46]124    _Scheduler_SMP_Insert_priority_fifo_order
[aea4a91]125  );
[a936aa49]126}
127
[e9ee2f0]128static void _Scheduler_simple_SMP_Insert_ready_lifo(
[3730a07f]129  Scheduler_Context *context,
[8f0c7a46]130  Scheduler_Node    *node_to_insert
[a936aa49]131)
132{
[e1598a6]133  Scheduler_simple_SMP_Context *self =
[3730a07f]134    _Scheduler_simple_SMP_Get_self( context );
[494c2e3]135
[48c4a55]136  _Chain_Insert_ordered_unprotected(
[494c2e3]137    &self->Ready,
[15dbc710]138    &node_to_insert->Node.Chain,
[8f0c7a46]139    _Scheduler_SMP_Insert_priority_lifo_order
[48c4a55]140  );
[a936aa49]141}
142
[e9ee2f0]143static void _Scheduler_simple_SMP_Insert_ready_fifo(
[3730a07f]144  Scheduler_Context *context,
[8f0c7a46]145  Scheduler_Node    *node_to_insert
[aea4a91]146)
147{
[e1598a6]148  Scheduler_simple_SMP_Context *self =
[3730a07f]149    _Scheduler_simple_SMP_Get_self( context );
[494c2e3]150
[48c4a55]151  _Chain_Insert_ordered_unprotected(
[494c2e3]152    &self->Ready,
[15dbc710]153    &node_to_insert->Node.Chain,
[8f0c7a46]154    _Scheduler_SMP_Insert_priority_fifo_order
[48c4a55]155  );
[aea4a91]156}
157
[f39f667a]158static void _Scheduler_simple_SMP_Extract_from_ready(
[3730a07f]159  Scheduler_Context *context,
[8f0c7a46]160  Scheduler_Node    *node_to_extract
[a936aa49]161)
162{
[3730a07f]163  (void) context;
[a936aa49]164
[15dbc710]165  _Chain_Extract_unprotected( &node_to_extract->Node.Chain );
[aea4a91]166}
[a936aa49]167
[e9ee2f0]168void _Scheduler_simple_SMP_Block(
[e1598a6]169  const Scheduler_Control *scheduler,
[e382a1b]170  Thread_Control          *thread,
171  Scheduler_Node          *node
[24934e36]172)
[aea4a91]173{
[f39f667a]174  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
[a936aa49]175
[48c4a55]176  _Scheduler_SMP_Block(
[f39f667a]177    context,
[48c4a55]178    thread,
[e382a1b]179    node,
[f39f667a]180    _Scheduler_simple_SMP_Extract_from_ready,
[e9ee2f0]181    _Scheduler_simple_SMP_Get_highest_ready,
[238629f]182    _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
[27783f6]183    _Scheduler_SMP_Allocate_processor_lazy
[48c4a55]184  );
185}
[a936aa49]186
[63e2ca1b]187static bool _Scheduler_simple_SMP_Enqueue_ordered(
[8568341]188  Scheduler_Context    *context,
189  Scheduler_Node       *node,
190  Chain_Node_order      order,
191  Scheduler_SMP_Insert  insert_ready,
192  Scheduler_SMP_Insert  insert_scheduled
[48c4a55]193)
194{
[8568341]195  return _Scheduler_SMP_Enqueue_ordered(
[3730a07f]196    context,
[8f0c7a46]197    node,
[48c4a55]198    order,
199    insert_ready,
200    insert_scheduled,
[238629f]201    _Scheduler_simple_SMP_Move_from_scheduled_to_ready,
202    _Scheduler_SMP_Get_lowest_scheduled,
[27783f6]203    _Scheduler_SMP_Allocate_processor_lazy
[48c4a55]204  );
[a936aa49]205}
206
[63e2ca1b]207static bool _Scheduler_simple_SMP_Enqueue_lifo(
[f39f667a]208  Scheduler_Context *context,
[63e2ca1b]209  Scheduler_Node    *node
[24934e36]210)
[a936aa49]211{
[8568341]212  return _Scheduler_simple_SMP_Enqueue_ordered(
[f39f667a]213    context,
[8f0c7a46]214    node,
215    _Scheduler_SMP_Insert_priority_lifo_order,
[e9ee2f0]216    _Scheduler_simple_SMP_Insert_ready_lifo,
[48c4a55]217    _Scheduler_SMP_Insert_scheduled_lifo
[a936aa49]218  );
219}
220
[63e2ca1b]221static bool _Scheduler_simple_SMP_Enqueue_fifo(
[f39f667a]222  Scheduler_Context *context,
[63e2ca1b]223  Scheduler_Node    *node
[24934e36]224)
[a936aa49]225{
[8568341]226  return _Scheduler_simple_SMP_Enqueue_ordered(
[f39f667a]227    context,
[8f0c7a46]228    node,
229    _Scheduler_SMP_Insert_priority_fifo_order,
[c0bff5e]230    _Scheduler_simple_SMP_Insert_ready_fifo,
231    _Scheduler_SMP_Insert_scheduled_fifo
232  );
233}
234
[63e2ca1b]235static bool _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
[c0bff5e]236  Scheduler_Context *context,
[8f0c7a46]237  Scheduler_Node *node,
[c0bff5e]238  Chain_Node_order order,
239  Scheduler_SMP_Insert insert_ready,
240  Scheduler_SMP_Insert insert_scheduled
241)
242{
[8568341]243  return _Scheduler_SMP_Enqueue_scheduled_ordered(
[c0bff5e]244    context,
[8f0c7a46]245    node,
[c0bff5e]246    order,
[5c3d250]247    _Scheduler_simple_SMP_Extract_from_ready,
[c0bff5e]248    _Scheduler_simple_SMP_Get_highest_ready,
249    insert_ready,
250    insert_scheduled,
[238629f]251    _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
[27783f6]252    _Scheduler_SMP_Allocate_processor_lazy
[c0bff5e]253  );
254}
255
[63e2ca1b]256static bool _Scheduler_simple_SMP_Enqueue_scheduled_lifo(
[c0bff5e]257  Scheduler_Context *context,
[8f0c7a46]258  Scheduler_Node *node
[c0bff5e]259)
260{
[8568341]261  return _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
[c0bff5e]262    context,
[8f0c7a46]263    node,
264    _Scheduler_SMP_Insert_priority_lifo_order,
[c0bff5e]265    _Scheduler_simple_SMP_Insert_ready_lifo,
266    _Scheduler_SMP_Insert_scheduled_lifo
267  );
268}
269
[63e2ca1b]270static bool _Scheduler_simple_SMP_Enqueue_scheduled_fifo(
[c0bff5e]271  Scheduler_Context *context,
[8f0c7a46]272  Scheduler_Node *node
[c0bff5e]273)
274{
[8568341]275  return _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
[c0bff5e]276    context,
[8f0c7a46]277    node,
278    _Scheduler_SMP_Insert_priority_fifo_order,
[e9ee2f0]279    _Scheduler_simple_SMP_Insert_ready_fifo,
[48c4a55]280    _Scheduler_SMP_Insert_scheduled_fifo
[a936aa49]281  );
282}
283
[ca1e546e]284void _Scheduler_simple_SMP_Unblock(
[e1598a6]285  const Scheduler_Control *scheduler,
[72e0bdb]286  Thread_Control          *thread,
287  Scheduler_Node          *node
[24934e36]288)
[a936aa49]289{
[f39f667a]290  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
291
[ca1e546e]292  _Scheduler_SMP_Unblock(
[c0bff5e]293    context,
294    thread,
[72e0bdb]295    node,
[9bfad8c]296    _Scheduler_simple_SMP_Do_update,
[27783f6]297    _Scheduler_simple_SMP_Enqueue_fifo
[c0bff5e]298  );
[f39f667a]299}
[a936aa49]300
[351c14d]301static bool _Scheduler_simple_SMP_Do_ask_for_help(
302  Scheduler_Context *context,
303  Thread_Control    *the_thread,
304  Scheduler_Node    *node
305)
306{
307  return _Scheduler_SMP_Ask_for_help(
308    context,
309    the_thread,
310    node,
311    _Scheduler_SMP_Insert_priority_lifo_order,
312    _Scheduler_simple_SMP_Insert_ready_lifo,
313    _Scheduler_SMP_Insert_scheduled_lifo,
314    _Scheduler_simple_SMP_Move_from_scheduled_to_ready,
315    _Scheduler_SMP_Get_lowest_scheduled,
316    _Scheduler_SMP_Allocate_processor_lazy
317  );
318}
319
[9c238e1]320void _Scheduler_simple_SMP_Update_priority(
[f39f667a]321  const Scheduler_Control *scheduler,
[501043a]322  Thread_Control          *thread,
323  Scheduler_Node          *node
[f39f667a]324)
325{
326  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
327
[9c238e1]328  _Scheduler_SMP_Update_priority(
[f39f667a]329    context,
[48c4a55]330    thread,
[501043a]331    node,
[f39f667a]332    _Scheduler_simple_SMP_Extract_from_ready,
333    _Scheduler_simple_SMP_Do_update,
334    _Scheduler_simple_SMP_Enqueue_fifo,
[c0bff5e]335    _Scheduler_simple_SMP_Enqueue_lifo,
336    _Scheduler_simple_SMP_Enqueue_scheduled_fifo,
[351c14d]337    _Scheduler_simple_SMP_Enqueue_scheduled_lifo,
338    _Scheduler_simple_SMP_Do_ask_for_help
339  );
340}
341
342bool _Scheduler_simple_SMP_Ask_for_help(
343  const Scheduler_Control *scheduler,
344  Thread_Control          *the_thread,
345  Scheduler_Node          *node
346)
347{
348  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
349
350  return _Scheduler_simple_SMP_Do_ask_for_help( context, the_thread, node );
351}
352
353void _Scheduler_simple_SMP_Reconsider_help_request(
354  const Scheduler_Control *scheduler,
355  Thread_Control          *the_thread,
356  Scheduler_Node          *node
357)
358{
359  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
360
361  _Scheduler_SMP_Reconsider_help_request(
362    context,
363    the_thread,
364    node,
365    _Scheduler_simple_SMP_Extract_from_ready
366  );
367}
368
369void _Scheduler_simple_SMP_Withdraw_node(
370  const Scheduler_Control *scheduler,
371  Thread_Control          *the_thread,
372  Scheduler_Node          *node,
373  Thread_Scheduler_state   next_state
374)
375{
376  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
377
378  _Scheduler_SMP_Withdraw_node(
379    context,
380    the_thread,
381    node,
382    next_state,
383    _Scheduler_simple_SMP_Extract_from_ready,
384    _Scheduler_simple_SMP_Get_highest_ready,
385    _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
386    _Scheduler_SMP_Allocate_processor_lazy
[48c4a55]387  );
[a936aa49]388}
389
[05ca53d]390void _Scheduler_simple_SMP_Add_processor(
391  const Scheduler_Control *scheduler,
392  Thread_Control          *idle
393)
394{
395  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
396
397  _Scheduler_SMP_Add_processor(
398    context,
399    idle,
400    _Scheduler_simple_SMP_Has_ready,
[34487537]401    _Scheduler_simple_SMP_Enqueue_scheduled_fifo,
402    _Scheduler_SMP_Do_nothing_register_idle
[05ca53d]403  );
404}
405
406Thread_Control *_Scheduler_simple_SMP_Remove_processor(
407  const Scheduler_Control *scheduler,
408  Per_CPU_Control         *cpu
409)
410{
411  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
412
413  return _Scheduler_SMP_Remove_processor(
414    context,
415    cpu,
416    _Scheduler_simple_SMP_Extract_from_ready,
417    _Scheduler_simple_SMP_Enqueue_fifo
418  );
419}
420
[ca1e546e]421void _Scheduler_simple_SMP_Yield(
[e1598a6]422  const Scheduler_Control *scheduler,
[2df4abc]423  Thread_Control          *thread,
424  Scheduler_Node          *node
[24934e36]425)
[a936aa49]426{
[f39f667a]427  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
[a936aa49]428
[ca1e546e]429  _Scheduler_SMP_Yield(
[701dd96f]430    context,
431    thread,
[2df4abc]432    node,
[701dd96f]433    _Scheduler_simple_SMP_Extract_from_ready,
434    _Scheduler_simple_SMP_Enqueue_fifo,
435    _Scheduler_simple_SMP_Enqueue_scheduled_fifo
436  );
[a936aa49]437}
Note: See TracBrowser for help on using the repository browser.