Changeset 8568341 in rtems


Ignore:
Timestamp:
06/11/14 12:31:03 (9 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, 5, master
Children:
52f8e90d
Parents:
ac532f3
git-author:
Sebastian Huber <sebastian.huber@…> (06/11/14 12:31:03)
git-committer:
Sebastian Huber <sebastian.huber@…> (07/08/14 14:30:48)
Message:

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.

Files:
24 edited

Legend:

Unmodified
Added
Removed
  • cpukit/score/include/rtems/score/scheduler.h

    rac532f3 r8568341  
    4545typedef struct Scheduler_Node Scheduler_Node;
    4646
     47#if defined(RTEMS_SMP)
     48  typedef Thread_Control * Scheduler_Void_or_thread;
     49
     50  #define SCHEDULER_RETURN_VOID_OR_NULL return NULL
     51#else
     52  typedef void Scheduler_Void_or_thread;
     53
     54  #define SCHEDULER_RETURN_VOID_OR_NULL return
     55#endif
     56
    4757/**
    4858 * @brief The scheduler operations.
     
    5666
    5767  /** @see _Scheduler_Yield() */
    58   void ( *yield )( const Scheduler_Control *, Thread_Control *);
     68  Scheduler_Void_or_thread ( *yield )(
     69    const Scheduler_Control *,
     70    Thread_Control *
     71  );
    5972
    6073  /** @see _Scheduler_Block() */
    61   void ( *block )( const Scheduler_Control *, Thread_Control * );
     74  void ( *block )(
     75    const Scheduler_Control *,
     76    Thread_Control *
     77  );
    6278
    6379  /** @see _Scheduler_Unblock() */
    64   void ( *unblock )( const Scheduler_Control *, Thread_Control * );
     80  Scheduler_Void_or_thread ( *unblock )(
     81    const Scheduler_Control *,
     82    Thread_Control *
     83  );
    6584
    6685  /** @see _Scheduler_Change_priority() */
    67   void ( *change_priority )(
     86  Scheduler_Void_or_thread ( *change_priority )(
    6887    const Scheduler_Control *,
    6988    Thread_Control *,
  • cpukit/score/include/rtems/score/schedulercbs.h

    rac532f3 r8568341  
    154154 *  @note This has to be asessed as missed deadline of the current job.
    155155 */
    156 void _Scheduler_CBS_Unblock(
     156Scheduler_Void_or_thread _Scheduler_CBS_Unblock(
    157157  const Scheduler_Control *scheduler,
    158158  Thread_Control          *the_thread
  • cpukit/score/include/rtems/score/scheduleredf.h

    rac532f3 r8568341  
    178178 *  @param[in] the_thread will be unblocked.
    179179 */
    180 void _Scheduler_EDF_Unblock(
    181   const Scheduler_Control *scheduler,
    182   Thread_Control          *the_thread
    183 );
    184 
    185 void _Scheduler_EDF_Change_priority(
     180Scheduler_Void_or_thread _Scheduler_EDF_Unblock(
     181  const Scheduler_Control *scheduler,
     182  Thread_Control          *the_thread
     183);
     184
     185Scheduler_Void_or_thread _Scheduler_EDF_Change_priority(
    186186  const Scheduler_Control *scheduler,
    187187  Thread_Control          *the_thread,
     
    205205 *  @param[in,out] thread The yielding thread.
    206206 */
    207 void _Scheduler_EDF_Yield(
     207Scheduler_Void_or_thread _Scheduler_EDF_Yield(
    208208  const Scheduler_Control *scheduler,
    209209  Thread_Control          *the_thread
  • cpukit/score/include/rtems/score/schedulerimpl.h

    rac532f3 r8568341  
    117117}
    118118
     119#if defined(RTEMS_SMP)
     120/**
     121 * @brief Ask threads depending on resources owned by the thread for help.
     122 *
     123 * A thread is in need for help if it lost its assigned processor due to
     124 * pre-emption by a higher priority thread or it was not possible to assign it
     125 * a processor since its priority is to low on its current scheduler instance.
     126 *
     127 * @param[in] needs_help The thread needing help.
     128 */
     129RTEMS_INLINE_ROUTINE void _Scheduler_Ask_for_help_if_necessary(
     130  Thread_Control *needs_help
     131)
     132{
     133  (void) needs_help;
     134}
     135#endif
     136
    119137/**
    120138 * @brief Scheduler yield with a particular thread.
     
    128146{
    129147  const Scheduler_Control *scheduler = _Scheduler_Get( the_thread );
    130 
     148#if defined(RTEMS_SMP)
     149  Thread_Control *needs_help;
     150
     151  needs_help =
     152#endif
    131153  ( *scheduler->Operations.yield )( scheduler, the_thread );
     154
     155#if defined(RTEMS_SMP)
     156  _Scheduler_Ask_for_help_if_necessary( needs_help );
     157#endif
    132158}
    133159
     
    162188{
    163189  const Scheduler_Control *scheduler = _Scheduler_Get( the_thread );
    164 
     190#if defined(RTEMS_SMP)
     191  Thread_Control *needs_help;
     192
     193  needs_help =
     194#endif
    165195  ( *scheduler->Operations.unblock )( scheduler, the_thread );
     196
     197#if defined(RTEMS_SMP)
     198  _Scheduler_Ask_for_help_if_necessary( needs_help );
     199#endif
    166200}
    167201
     
    186220{
    187221  const Scheduler_Control *scheduler = _Scheduler_Get( the_thread );
    188 
     222#if defined(RTEMS_SMP)
     223  Thread_Control *needs_help;
     224
     225  needs_help =
     226#endif
    189227  ( *scheduler->Operations.change_priority )(
    190228    scheduler,
     
    193231    prepend_it
    194232  );
     233
     234#if defined(RTEMS_SMP)
     235  _Scheduler_Ask_for_help_if_necessary( needs_help );
     236#endif
    195237}
    196238
  • cpukit/score/include/rtems/score/schedulerpriority.h

    rac532f3 r8568341  
    150150 *  @param[in] the_thread will be unblocked
    151151 */
    152 void _Scheduler_priority_Unblock(
    153   const Scheduler_Control *scheduler,
    154   Thread_Control          *the_thread
    155 );
    156 
    157 void _Scheduler_priority_Change_priority(
     152Scheduler_Void_or_thread _Scheduler_priority_Unblock(
     153  const Scheduler_Control *scheduler,
     154  Thread_Control          *the_thread
     155);
     156
     157Scheduler_Void_or_thread _Scheduler_priority_Change_priority(
    158158  const Scheduler_Control *scheduler,
    159159  Thread_Control          *the_thread,
     
    181181 *  @param[in,out] thread The yielding thread.
    182182 */
    183 void _Scheduler_priority_Yield(
     183Scheduler_Void_or_thread _Scheduler_priority_Yield(
    184184  const Scheduler_Control *scheduler,
    185185  Thread_Control          *the_thread
  • cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h

    rac532f3 r8568341  
    102102 * @param[in] thread is the thread to unblock
    103103 */
    104 void _Scheduler_priority_affinity_SMP_Unblock(
     104Thread_Control *_Scheduler_priority_affinity_SMP_Unblock(
    105105  const Scheduler_Control *scheduler,
    106106  Thread_Control          *thread
     
    133133 * @param[in] prepend_it Append or prepend the thread to its priority FIFO.
    134134 */
    135 void _Scheduler_priority_affinity_SMP_Change_priority(
     135Thread_Control *_Scheduler_priority_affinity_SMP_Change_priority(
    136136  const Scheduler_Control *scheduler,
    137137  Thread_Control          *the_thread,
  • cpukit/score/include/rtems/score/schedulerprioritysmp.h

    rac532f3 r8568341  
    107107);
    108108
    109 void _Scheduler_priority_SMP_Unblock(
     109Thread_Control *_Scheduler_priority_SMP_Unblock(
    110110  const Scheduler_Control *scheduler,
    111111  Thread_Control *thread
    112112);
    113113
    114 void _Scheduler_priority_SMP_Change_priority(
     114Thread_Control *_Scheduler_priority_SMP_Change_priority(
    115115  const Scheduler_Control *scheduler,
    116116  Thread_Control          *the_thread,
     
    125125);
    126126
    127 void _Scheduler_priority_SMP_Yield(
     127Thread_Control *_Scheduler_priority_SMP_Yield(
    128128  const Scheduler_Control *scheduler,
    129129  Thread_Control *thread
  • cpukit/score/include/rtems/score/schedulersimple.h

    rac532f3 r8568341  
    102102 *  @param[in,out] thread The yielding thread.
    103103 */
    104 void _Scheduler_simple_Yield(
     104Scheduler_Void_or_thread _Scheduler_simple_Yield(
    105105  const Scheduler_Control *scheduler,
    106106  Thread_Control          *the_thread
     
    131131 *  @param[in] the_thread is the thread that is to be unblocked
    132132 */
    133 void _Scheduler_simple_Unblock(
     133Scheduler_Void_or_thread _Scheduler_simple_Unblock(
    134134  const Scheduler_Control *scheduler,
    135135  Thread_Control          *the_thread
    136136);
    137137
    138 void _Scheduler_simple_Change_priority(
     138Scheduler_Void_or_thread _Scheduler_simple_Change_priority(
    139139  const Scheduler_Control *scheduler,
    140140  Thread_Control          *the_thread,
  • cpukit/score/include/rtems/score/schedulersimplesmp.h

    rac532f3 r8568341  
    8888);
    8989
    90 void _Scheduler_simple_SMP_Unblock(
     90Thread_Control *_Scheduler_simple_SMP_Unblock(
    9191  const Scheduler_Control *scheduler,
    9292  Thread_Control *thread
    9393);
    9494
    95 void _Scheduler_simple_SMP_Change_priority(
     95Thread_Control *_Scheduler_simple_SMP_Change_priority(
    9696  const Scheduler_Control *scheduler,
    9797  Thread_Control          *the_thread,
     
    106106);
    107107
    108 void _Scheduler_simple_SMP_Yield(
     108Thread_Control *_Scheduler_simple_SMP_Yield(
    109109  const Scheduler_Control *scheduler,
    110110  Thread_Control *thread
  • cpukit/score/include/rtems/score/schedulersmpimpl.h

    rac532f3 r8568341  
    307307);
    308308
    309 typedef void ( *Scheduler_SMP_Enqueue )(
     309typedef Thread_Control *( *Scheduler_SMP_Enqueue )(
     310  Scheduler_Context *context,
     311  Scheduler_Node    *node_to_enqueue,
     312  Thread_Control    *needs_help
     313);
     314
     315typedef Thread_Control *( *Scheduler_SMP_Enqueue_scheduled )(
    310316  Scheduler_Context *context,
    311317  Scheduler_Node    *node_to_enqueue
     
    493499 * @param[in] context The scheduler instance context.
    494500 * @param[in] node The node to enqueue.
     501 * @param[in] needs_help The thread needing help in case the node cannot be
     502 *   scheduled.
    495503 * @param[in] order The order function.
    496504 * @param[in] insert_ready Function to insert a node into the set of ready
     
    507515 *   based on the rules of the scheduler.
    508516 */
    509 static inline void _Scheduler_SMP_Enqueue_ordered(
     517static inline Thread_Control *_Scheduler_SMP_Enqueue_ordered(
    510518  Scheduler_Context                  *context,
    511519  Scheduler_Node                     *node,
     520  Thread_Control                     *needs_help,
    512521  Chain_Node_order                    order,
    513522  Scheduler_SMP_Insert                insert_ready,
     
    536545    ( *insert_scheduled )( context, node );
    537546    ( *move_from_scheduled_to_ready )( context, lowest_scheduled );
     547
     548    needs_help = _Scheduler_Node_get_user( lowest_scheduled );
    538549  } else {
    539550    ( *insert_ready )( context, node );
    540551  }
     552
     553  return needs_help;
    541554}
    542555
     
    558571 *   based on the rules of the scheduler.
    559572 */
    560 static inline void _Scheduler_SMP_Enqueue_scheduled_ordered(
     573static inline Thread_Control *_Scheduler_SMP_Enqueue_scheduled_ordered(
    561574  Scheduler_Context                *context,
    562575  Scheduler_Node                   *node,
     
    570583{
    571584  Scheduler_Node *highest_ready = ( *get_highest_ready )( context, node );
     585  Thread_Control *needs_help;
    572586
    573587  _Assert( highest_ready != NULL );
     
    579593  if ( ( *order )( &node->Node, &highest_ready->Node ) ) {
    580594    ( *insert_scheduled )( context, node );
     595
     596    needs_help = NULL;
    581597  } else {
    582598    _Scheduler_SMP_Node_change_state(
     
    594610    ( *insert_ready )( context, node );
    595611    ( *move_from_ready_to_scheduled )( context, highest_ready );
     612
     613    needs_help = _Scheduler_Node_get_user( node );
    596614  }
     615
     616  return needs_help;
    597617}
    598618
     
    664684}
    665685
    666 static inline void _Scheduler_SMP_Unblock(
     686static inline Thread_Control *_Scheduler_SMP_Unblock(
    667687  Scheduler_Context     *context,
    668688  Thread_Control        *thread,
     
    674694  _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
    675695
    676   ( *enqueue_fifo )( context, &node->Base );
    677 }
    678 
    679 static inline void _Scheduler_SMP_Change_priority(
    680   Scheduler_Context     *context,
    681   Thread_Control        *thread,
    682   Priority_Control       new_priority,
    683   bool                   prepend_it,
    684   Scheduler_SMP_Extract  extract_from_ready,
    685   Scheduler_SMP_Update   update,
    686   Scheduler_SMP_Enqueue  enqueue_fifo,
    687   Scheduler_SMP_Enqueue  enqueue_lifo,
    688   Scheduler_SMP_Enqueue  enqueue_scheduled_fifo,
    689   Scheduler_SMP_Enqueue  enqueue_scheduled_lifo
     696  return ( *enqueue_fifo )( context, &node->Base, thread );
     697}
     698
     699static inline Thread_Control *_Scheduler_SMP_Change_priority(
     700  Scheduler_Context               *context,
     701  Thread_Control                  *thread,
     702  Priority_Control                 new_priority,
     703  bool                             prepend_it,
     704  Scheduler_SMP_Extract            extract_from_ready,
     705  Scheduler_SMP_Update             update,
     706  Scheduler_SMP_Enqueue            enqueue_fifo,
     707  Scheduler_SMP_Enqueue            enqueue_lifo,
     708  Scheduler_SMP_Enqueue_scheduled  enqueue_scheduled_fifo,
     709  Scheduler_SMP_Enqueue_scheduled  enqueue_scheduled_lifo
    690710)
    691711{
    692712  Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_node( thread );
     713  Thread_Control *needs_help;
    693714
    694715  if ( node->state == SCHEDULER_SMP_NODE_SCHEDULED ) {
     
    698719
    699720    if ( prepend_it ) {
    700       ( *enqueue_scheduled_lifo )( context, &node->Base );
     721      needs_help = ( *enqueue_scheduled_lifo )( context, &node->Base );
    701722    } else {
    702       ( *enqueue_scheduled_fifo )( context, &node->Base );
     723      needs_help = ( *enqueue_scheduled_fifo )( context, &node->Base );
    703724    }
    704725  } else {
     
    708729
    709730    if ( prepend_it ) {
    710       ( *enqueue_lifo )( context, &node->Base );
     731      needs_help = ( *enqueue_lifo )( context, &node->Base, NULL );
    711732    } else {
    712       ( *enqueue_fifo )( context, &node->Base );
     733      needs_help = ( *enqueue_fifo )( context, &node->Base, NULL );
    713734    }
    714735  }
    715 }
    716 
    717 static inline void _Scheduler_SMP_Yield(
    718   Scheduler_Context     *context,
    719   Thread_Control        *thread,
    720   Scheduler_SMP_Extract  extract_from_ready,
    721   Scheduler_SMP_Enqueue  enqueue_fifo,
    722   Scheduler_SMP_Enqueue  enqueue_scheduled_fifo
     736
     737  return needs_help;
     738}
     739
     740static inline Thread_Control *_Scheduler_SMP_Yield(
     741  Scheduler_Context               *context,
     742  Thread_Control                  *thread,
     743  Scheduler_SMP_Extract            extract_from_ready,
     744  Scheduler_SMP_Enqueue            enqueue_fifo,
     745  Scheduler_SMP_Enqueue_scheduled  enqueue_scheduled_fifo
    723746)
    724747{
    725748  Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_node( thread );
     749  Thread_Control *needs_help;
    726750
    727751  if ( node->state == SCHEDULER_SMP_NODE_SCHEDULED ) {
    728752    _Scheduler_SMP_Extract_from_scheduled( &node->Base );
    729753
    730     ( *enqueue_scheduled_fifo )( context, &node->Base );
     754    needs_help = ( *enqueue_scheduled_fifo )( context, &node->Base );
    731755  } else {
    732756    ( *extract_from_ready )( context, &node->Base );
    733757
    734     ( *enqueue_fifo )( context, &node->Base );
     758    needs_help = ( *enqueue_fifo )( context, &node->Base, NULL );
    735759  }
     760
     761  return needs_help;
    736762}
    737763
  • cpukit/score/src/schedulercbsunblock.c

    rac532f3 r8568341  
    2626#include <rtems/score/watchdogimpl.h>
    2727
    28 void _Scheduler_CBS_Unblock(
     28Scheduler_Void_or_thread _Scheduler_CBS_Unblock(
    2929  const Scheduler_Control *scheduler,
    3030  Thread_Control          *the_thread
     
    8585      _Thread_Dispatch_necessary = true;
    8686  }
     87
     88  SCHEDULER_RETURN_VOID_OR_NULL;
    8789}
  • cpukit/score/src/scheduleredfchangepriority.c

    rac532f3 r8568341  
    2121#include <rtems/score/scheduleredfimpl.h>
    2222
    23 void _Scheduler_EDF_Change_priority(
     23Scheduler_Void_or_thread _Scheduler_EDF_Change_priority(
    2424  const Scheduler_Control *scheduler,
    2525  Thread_Control          *the_thread,
     
    3434  _RBTree_Extract( &context->Ready, &node->Node );
    3535  _RBTree_Insert( &context->Ready, &node->Node );
     36
     37  SCHEDULER_RETURN_VOID_OR_NULL;
    3638}
  • cpukit/score/src/scheduleredfunblock.c

    rac532f3 r8568341  
    2323#include <rtems/score/thread.h>
    2424
    25 void _Scheduler_EDF_Unblock(
     25Scheduler_Void_or_thread _Scheduler_EDF_Unblock(
    2626  const Scheduler_Control *scheduler,
    2727  Thread_Control          *the_thread
     
    5252      _Thread_Dispatch_necessary = true;
    5353  }
     54
     55  SCHEDULER_RETURN_VOID_OR_NULL;
    5456}
  • cpukit/score/src/scheduleredfyield.c

    rac532f3 r8568341  
    2222#include <rtems/score/scheduleredfimpl.h>
    2323
    24 void _Scheduler_EDF_Yield(
     24Scheduler_Void_or_thread _Scheduler_EDF_Yield(
    2525  const Scheduler_Control *scheduler,
    2626  Thread_Control          *the_thread
     
    3939
    4040  _Scheduler_EDF_Schedule_body( scheduler, the_thread, false );
     41
     42  SCHEDULER_RETURN_VOID_OR_NULL;
    4143}
  • cpukit/score/src/schedulerpriorityaffinitysmp.c

    rac532f3 r8568341  
    289289 * _Scheduler_SMP_Enqueue_ordered.
    290290 */
    291 static void _Scheduler_priority_affinity_SMP_Enqueue_fifo(
     291static Thread_Control *_Scheduler_priority_affinity_SMP_Enqueue_fifo(
    292292  Scheduler_Context *context,
    293   Scheduler_Node    *node
    294 )
    295 {
    296   _Scheduler_SMP_Enqueue_ordered(
     293  Scheduler_Node    *node,
     294  Thread_Control    *needs_help
     295)
     296{
     297  return _Scheduler_SMP_Enqueue_ordered(
    297298    context,
    298299    node,
     300    needs_help,
    299301    _Scheduler_priority_affinity_SMP_Insert_priority_fifo_order,
    300302    _Scheduler_priority_SMP_Insert_ready_fifo,
     
    375377 * This is the public scheduler specific Unblock operation.
    376378 */
    377 void _Scheduler_priority_affinity_SMP_Unblock(
     379Thread_Control *_Scheduler_priority_affinity_SMP_Unblock(
    378380  const Scheduler_Control *scheduler,
    379381  Thread_Control *thread
     
    381383{
    382384  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
    383 
    384   _Scheduler_SMP_Unblock(
     385  Thread_Control    *needs_help;
     386
     387  needs_help = _Scheduler_SMP_Unblock(
    385388    context,
    386389    thread,
     
    392395   */
    393396  _Scheduler_priority_affinity_SMP_Check_for_migrations( context );
     397
     398  return needs_help;
    394399}
    395400
     
    398403 *  get_lowest_scheduled helper to _Scheduler_SMP_Enqueue_ordered.
    399404 */
    400 static void _Scheduler_priority_affinity_SMP_Enqueue_ordered(
     405static Thread_Control *_Scheduler_priority_affinity_SMP_Enqueue_ordered(
    401406  Scheduler_Context     *context,
    402407  Scheduler_Node        *node,
     408  Thread_Control        *needs_help,
    403409  Chain_Node_order       order,
    404410  Scheduler_SMP_Insert   insert_ready,
     
    406412)
    407413{
    408   _Scheduler_SMP_Enqueue_ordered(
     414  return _Scheduler_SMP_Enqueue_ordered(
    409415    context,
    410416    node,
     417    needs_help,
    411418    order,
    412419    insert_ready,
     
    423430 *  invokes a scheduler unique get_lowest_scheduled helper.
    424431 */
    425 static void _Scheduler_priority_affinity_SMP_Enqueue_lifo(
     432static Thread_Control *_Scheduler_priority_affinity_SMP_Enqueue_lifo(
    426433  Scheduler_Context *context,
    427   Scheduler_Node    *node
    428 )
    429 {
    430   _Scheduler_priority_affinity_SMP_Enqueue_ordered(
     434  Scheduler_Node    *node,
     435  Thread_Control    *needs_help
     436)
     437{
     438  return _Scheduler_priority_affinity_SMP_Enqueue_ordered(
    431439    context,
    432440    node,
     441    needs_help,
    433442    _Scheduler_priority_affinity_SMP_Insert_priority_lifo_order,
    434443    _Scheduler_priority_SMP_Insert_ready_lifo,
     
    442451 * this scheduler's get_highest_ready() helper.
    443452 */
    444 static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered(
     453static Thread_Control *
     454_Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered(
    445455  Scheduler_Context    *context,
    446456  Scheduler_Node       *node,
     
    450460)
    451461{
    452   _Scheduler_SMP_Enqueue_scheduled_ordered(
     462  return _Scheduler_SMP_Enqueue_scheduled_ordered(
    453463    context,
    454464    node,
     
    467477 *  invokes a scheduler unique get_lowest_scheduled helper.
    468478 */
    469 static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_lifo(
     479static Thread_Control *_Scheduler_priority_affinity_SMP_Enqueue_scheduled_lifo(
    470480  Scheduler_Context *context,
    471481  Scheduler_Node    *node
    472482)
    473483{
    474   _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered(
     484  return _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered(
    475485    context,
    476486    node,
     
    486496 *  invokes a scheduler unique get_lowest_scheduled helper.
    487497 */
    488 static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_fifo(
     498static Thread_Control *_Scheduler_priority_affinity_SMP_Enqueue_scheduled_fifo(
    489499  Scheduler_Context *context,
    490500  Scheduler_Node    *node
    491501)
    492502{
    493   _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered(
     503  return _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered(
    494504    context,
    495505    node,
     
    503513 * This is the public scheduler specific Change Priority operation.
    504514 */
    505 void _Scheduler_priority_affinity_SMP_Change_priority(
     515Thread_Control *_Scheduler_priority_affinity_SMP_Change_priority(
    506516  const Scheduler_Control *scheduler,
    507517  Thread_Control          *thread,
     
    511521{
    512522  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
    513 
    514   _Scheduler_SMP_Change_priority(
     523  Thread_Control    *displaced;
     524
     525  displaced = _Scheduler_SMP_Change_priority(
    515526    context,
    516527    thread,
     
    529540   */
    530541  _Scheduler_priority_affinity_SMP_Check_for_migrations( context );
     542
     543  return displaced;
    531544}
    532545
  • cpukit/score/src/schedulerprioritychangepriority.c

    rac532f3 r8568341  
    2222#include <rtems/score/schedulerpriorityimpl.h>
    2323
    24 void _Scheduler_priority_Change_priority(
     24Scheduler_Void_or_thread _Scheduler_priority_Change_priority(
    2525  const Scheduler_Control *scheduler,
    2626  Thread_Control          *the_thread,
     
    5959    );
    6060  }
     61
     62  SCHEDULER_RETURN_VOID_OR_NULL;
    6163}
  • cpukit/score/src/schedulerprioritysmp.c

    rac532f3 r8568341  
    9898}
    9999
    100 static void _Scheduler_priority_SMP_Enqueue_ordered(
    101   Scheduler_Context *context,
    102   Scheduler_Node *node,
    103   Chain_Node_order order,
    104   Scheduler_SMP_Insert insert_ready,
    105   Scheduler_SMP_Insert insert_scheduled
    106 )
    107 {
    108   _Scheduler_SMP_Enqueue_ordered(
    109     context,
    110     node,
     100static Thread_Control *_Scheduler_priority_SMP_Enqueue_ordered(
     101  Scheduler_Context    *context,
     102  Scheduler_Node       *node,
     103  Thread_Control       *needs_help,
     104  Chain_Node_order      order,
     105  Scheduler_SMP_Insert  insert_ready,
     106  Scheduler_SMP_Insert  insert_scheduled
     107)
     108{
     109  return _Scheduler_SMP_Enqueue_ordered(
     110    context,
     111    node,
     112    needs_help,
    111113    order,
    112114    insert_ready,
     
    118120}
    119121
    120 static void _Scheduler_priority_SMP_Enqueue_lifo(
    121   Scheduler_Context *context,
    122   Scheduler_Node *node
    123 )
    124 {
    125   _Scheduler_priority_SMP_Enqueue_ordered(
    126     context,
    127     node,
     122static Thread_Control *_Scheduler_priority_SMP_Enqueue_lifo(
     123  Scheduler_Context *context,
     124  Scheduler_Node    *node,
     125  Thread_Control    *needs_help
     126)
     127{
     128  return _Scheduler_priority_SMP_Enqueue_ordered(
     129    context,
     130    node,
     131    needs_help,
    128132    _Scheduler_SMP_Insert_priority_lifo_order,
    129133    _Scheduler_priority_SMP_Insert_ready_lifo,
     
    132136}
    133137
    134 static void _Scheduler_priority_SMP_Enqueue_fifo(
    135   Scheduler_Context *context,
    136   Scheduler_Node *node
    137 )
    138 {
    139   _Scheduler_priority_SMP_Enqueue_ordered(
    140     context,
    141     node,
     138static Thread_Control *_Scheduler_priority_SMP_Enqueue_fifo(
     139  Scheduler_Context *context,
     140  Scheduler_Node    *node,
     141  Thread_Control    *needs_help
     142)
     143{
     144  return _Scheduler_priority_SMP_Enqueue_ordered(
     145    context,
     146    node,
     147    needs_help,
    142148    _Scheduler_SMP_Insert_priority_fifo_order,
    143149    _Scheduler_priority_SMP_Insert_ready_fifo,
     
    146152}
    147153
    148 static void _Scheduler_priority_SMP_Enqueue_scheduled_ordered(
     154static Thread_Control *_Scheduler_priority_SMP_Enqueue_scheduled_ordered(
    149155  Scheduler_Context *context,
    150156  Scheduler_Node *node,
     
    154160)
    155161{
    156   _Scheduler_SMP_Enqueue_scheduled_ordered(
     162  return _Scheduler_SMP_Enqueue_scheduled_ordered(
    157163    context,
    158164    node,
     
    166172}
    167173
    168 static void _Scheduler_priority_SMP_Enqueue_scheduled_lifo(
     174static Thread_Control *_Scheduler_priority_SMP_Enqueue_scheduled_lifo(
    169175  Scheduler_Context *context,
    170176  Scheduler_Node *node
    171177)
    172178{
    173   _Scheduler_priority_SMP_Enqueue_scheduled_ordered(
     179  return _Scheduler_priority_SMP_Enqueue_scheduled_ordered(
    174180    context,
    175181    node,
     
    180186}
    181187
    182 static void _Scheduler_priority_SMP_Enqueue_scheduled_fifo(
     188static Thread_Control *_Scheduler_priority_SMP_Enqueue_scheduled_fifo(
    183189  Scheduler_Context *context,
    184190  Scheduler_Node *node
    185191)
    186192{
    187   _Scheduler_priority_SMP_Enqueue_scheduled_ordered(
     193  return _Scheduler_priority_SMP_Enqueue_scheduled_ordered(
    188194    context,
    189195    node,
     
    194200}
    195201
    196 void _Scheduler_priority_SMP_Unblock(
    197   const Scheduler_Control *scheduler,
    198   Thread_Control *thread
    199 )
    200 {
    201   Scheduler_Context *context = _Scheduler_Get_context( scheduler );
    202 
    203   _Scheduler_SMP_Unblock(
     202Thread_Control *_Scheduler_priority_SMP_Unblock(
     203  const Scheduler_Control *scheduler,
     204  Thread_Control *thread
     205)
     206{
     207  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
     208
     209  return _Scheduler_SMP_Unblock(
    204210    context,
    205211    thread,
     
    208214}
    209215
    210 void _Scheduler_priority_SMP_Change_priority(
     216Thread_Control *_Scheduler_priority_SMP_Change_priority(
    211217  const Scheduler_Control *scheduler,
    212218  Thread_Control          *thread,
     
    217223  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
    218224
    219   _Scheduler_SMP_Change_priority(
     225  return _Scheduler_SMP_Change_priority(
    220226    context,
    221227    thread,
     
    231237}
    232238
    233 void _Scheduler_priority_SMP_Yield(
     239Thread_Control *_Scheduler_priority_SMP_Yield(
    234240  const Scheduler_Control *scheduler,
    235241  Thread_Control *thread
  • cpukit/score/src/schedulerpriorityunblock.c

    rac532f3 r8568341  
    2323#include <rtems/score/schedulerpriorityimpl.h>
    2424
    25 void _Scheduler_priority_Unblock (
     25Scheduler_Void_or_thread _Scheduler_priority_Unblock (
    2626  const Scheduler_Control *scheduler,
    2727  Thread_Control          *the_thread
     
    5858      _Thread_Dispatch_necessary = true;
    5959  }
     60
     61  SCHEDULER_RETURN_VOID_OR_NULL;
    6062}
  • cpukit/score/src/schedulerpriorityyield.c

    rac532f3 r8568341  
    2222#include <rtems/score/threadimpl.h>
    2323
    24 void _Scheduler_priority_Yield(
     24Scheduler_Void_or_thread _Scheduler_priority_Yield(
    2525  const Scheduler_Control *scheduler,
    2626  Thread_Control          *the_thread
     
    4444    _Thread_Dispatch_necessary = true;
    4545  }
     46
     47  SCHEDULER_RETURN_VOID_OR_NULL;
    4648}
  • cpukit/score/src/schedulersimplechangepriority.c

    rac532f3 r8568341  
    2222#include <rtems/score/schedulersimpleimpl.h>
    2323
    24 void _Scheduler_simple_Change_priority(
     24Scheduler_Void_or_thread _Scheduler_simple_Change_priority(
    2525  const Scheduler_Control *scheduler,
    2626  Thread_Control          *the_thread,
     
    3939    _Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread );
    4040  }
     41
     42  SCHEDULER_RETURN_VOID_OR_NULL;
    4143}
  • cpukit/score/src/schedulersimplesmp.c

    rac532f3 r8568341  
    180180}
    181181
    182 static void _Scheduler_simple_SMP_Enqueue_ordered(
    183   Scheduler_Context *context,
    184   Scheduler_Node *node,
    185   Chain_Node_order order,
    186   Scheduler_SMP_Insert insert_ready,
    187   Scheduler_SMP_Insert insert_scheduled
    188 )
    189 {
    190   _Scheduler_SMP_Enqueue_ordered(
    191     context,
    192     node,
     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,
    193195    order,
    194196    insert_ready,
     
    200202}
    201203
    202 static void _Scheduler_simple_SMP_Enqueue_lifo(
    203   Scheduler_Context *context,
    204   Scheduler_Node *node
    205 )
    206 {
    207   _Scheduler_simple_SMP_Enqueue_ordered(
    208     context,
    209     node,
     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,
    210214    _Scheduler_SMP_Insert_priority_lifo_order,
    211215    _Scheduler_simple_SMP_Insert_ready_lifo,
     
    214218}
    215219
    216 static void _Scheduler_simple_SMP_Enqueue_fifo(
    217   Scheduler_Context *context,
    218   Scheduler_Node *node
    219 )
    220 {
    221   _Scheduler_simple_SMP_Enqueue_ordered(
    222     context,
    223     node,
     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,
    224230    _Scheduler_SMP_Insert_priority_fifo_order,
    225231    _Scheduler_simple_SMP_Insert_ready_fifo,
     
    228234}
    229235
    230 static void _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
     236static Thread_Control *_Scheduler_simple_SMP_Enqueue_scheduled_ordered(
    231237  Scheduler_Context *context,
    232238  Scheduler_Node *node,
     
    236242)
    237243{
    238   _Scheduler_SMP_Enqueue_scheduled_ordered(
     244  return _Scheduler_SMP_Enqueue_scheduled_ordered(
    239245    context,
    240246    node,
     
    248254}
    249255
    250 static void _Scheduler_simple_SMP_Enqueue_scheduled_lifo(
     256static Thread_Control *_Scheduler_simple_SMP_Enqueue_scheduled_lifo(
    251257  Scheduler_Context *context,
    252258  Scheduler_Node *node
    253259)
    254260{
    255   _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
     261  return _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
    256262    context,
    257263    node,
     
    262268}
    263269
    264 static void _Scheduler_simple_SMP_Enqueue_scheduled_fifo(
     270static Thread_Control *_Scheduler_simple_SMP_Enqueue_scheduled_fifo(
    265271  Scheduler_Context *context,
    266272  Scheduler_Node *node
    267273)
    268274{
    269   _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
     275  return _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
    270276    context,
    271277    node,
     
    276282}
    277283
    278 void _Scheduler_simple_SMP_Unblock(
     284Thread_Control *_Scheduler_simple_SMP_Unblock(
    279285  const Scheduler_Control *scheduler,
    280286  Thread_Control *thread
     
    283289  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
    284290
    285   _Scheduler_SMP_Unblock(
     291  return _Scheduler_SMP_Unblock(
    286292    context,
    287293    thread,
     
    290296}
    291297
    292 void _Scheduler_simple_SMP_Change_priority(
     298Thread_Control *_Scheduler_simple_SMP_Change_priority(
    293299  const Scheduler_Control *scheduler,
    294300  Thread_Control          *thread,
     
    299305  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
    300306
    301   _Scheduler_SMP_Change_priority(
     307  return _Scheduler_SMP_Change_priority(
    302308    context,
    303309    thread,
     
    313319}
    314320
    315 void _Scheduler_simple_SMP_Yield(
     321Thread_Control *_Scheduler_simple_SMP_Yield(
    316322  const Scheduler_Control *scheduler,
    317323  Thread_Control *thread
  • cpukit/score/src/schedulersimpleunblock.c

    rac532f3 r8568341  
    2222#include <rtems/score/thread.h>
    2323
    24 void _Scheduler_simple_Unblock(
     24Scheduler_Void_or_thread _Scheduler_simple_Unblock(
    2525  const Scheduler_Control *scheduler,
    2626  Thread_Control          *the_thread
     
    5050      _Thread_Dispatch_necessary = true;
    5151  }
     52
     53  SCHEDULER_RETURN_VOID_OR_NULL;
    5254}
  • cpukit/score/src/schedulersimpleyield.c

    rac532f3 r8568341  
    2121#include <rtems/score/schedulersimpleimpl.h>
    2222
    23 void _Scheduler_simple_Yield(
     23Scheduler_Void_or_thread _Scheduler_simple_Yield(
    2424  const Scheduler_Control *scheduler,
    2525  Thread_Control          *the_thread
     
    3232  _Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread );
    3333  _Scheduler_simple_Schedule_body( scheduler, the_thread, false );
     34
     35  SCHEDULER_RETURN_VOID_OR_NULL;
    3436}
  • testsuites/smptests/smpscheduler03/init.c

    rac532f3 r8568341  
    5454}
    5555
    56 static void test_case(
     56static rtems_id start_task(rtems_task_priority prio)
     57{
     58  rtems_status_code sc;
     59  rtems_id task_id;
     60
     61  sc = rtems_task_create(
     62    rtems_build_name('T', 'A', 'S', 'K'),
     63    prio,
     64    RTEMS_MINIMUM_STACK_SIZE,
     65    RTEMS_DEFAULT_MODES,
     66    RTEMS_DEFAULT_ATTRIBUTES,
     67    &task_id
     68  );
     69  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     70
     71  sc = rtems_task_start(task_id, task, 0);
     72  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     73
     74  return task_id;
     75}
     76
     77static Thread_Control *get_thread_by_id(rtems_id task_id)
     78{
     79  Objects_Locations location;
     80  Thread_Control *thread;
     81
     82  thread = _Thread_Get(task_id, &location);
     83  rtems_test_assert(location == OBJECTS_LOCAL);
     84  _Thread_Enable_dispatch();
     85
     86  return thread;
     87}
     88
     89static void test_case_change_priority(
    5790  Thread_Control *executing,
    5891  Scheduler_SMP_Node *node,
     
    99132  size_t k;
    100133
    101   sc = rtems_task_create(
    102     rtems_build_name('T', 'A', 'S', 'K'),
    103     3,
    104     RTEMS_MINIMUM_STACK_SIZE,
    105     RTEMS_DEFAULT_MODES,
    106     RTEMS_DEFAULT_ATTRIBUTES,
    107     &task_id
    108   );
    109   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    110 
    111   sc = rtems_task_start(task_id, task, 0);
    112   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     134  task_id = start_task(3);
    113135
    114136  _Thread_Disable_dispatch();
     
    120142    for (j = 0; j < RTEMS_ARRAY_SIZE(priorities); ++j) {
    121143      for (k = 0; k < RTEMS_ARRAY_SIZE(prepend_it); ++k) {
    122         test_case(
     144        test_case_change_priority(
    123145          executing,
    124146          node,
     
    141163}
    142164
     165static Thread_Control *change_priority_op(
     166  Thread_Control *thread,
     167  Priority_Control new_priority,
     168  bool prepend_it
     169)
     170{
     171  const Scheduler_Control *scheduler = _Scheduler_Get(thread);
     172  Thread_Control *needs_help;
     173  ISR_Level level;
     174
     175  _ISR_Disable( level );
     176  thread->current_priority = new_priority;
     177  needs_help = (*scheduler->Operations.change_priority)(
     178    scheduler,
     179    thread,
     180    new_priority,
     181    prepend_it
     182  );
     183  _ISR_Enable( level );
     184
     185  return needs_help;
     186}
     187
     188static void test_case_change_priority_op(
     189  Thread_Control *executing,
     190  Scheduler_SMP_Node *executing_node,
     191  Thread_Control *other,
     192  Scheduler_SMP_Node_state start_state,
     193  Priority_Control prio,
     194  bool prepend_it,
     195  Scheduler_SMP_Node_state new_state
     196)
     197{
     198  Thread_Control *needs_help;
     199
     200  switch (start_state) {
     201    case SCHEDULER_SMP_NODE_SCHEDULED:
     202      _Thread_Change_priority(executing, 1, true);
     203      break;
     204    case SCHEDULER_SMP_NODE_READY:
     205      _Thread_Change_priority(executing, 4, true);
     206      break;
     207    default:
     208      rtems_test_assert(0);
     209      break;
     210  }
     211  rtems_test_assert(executing_node->state == start_state);
     212
     213  needs_help = change_priority_op(executing, prio, prepend_it);
     214  rtems_test_assert(executing_node->state == new_state);
     215
     216  if (start_state != new_state) {
     217    switch (start_state) {
     218      case SCHEDULER_SMP_NODE_SCHEDULED:
     219        rtems_test_assert(needs_help == executing);
     220        break;
     221      case SCHEDULER_SMP_NODE_READY:
     222        rtems_test_assert(needs_help == other);
     223        break;
     224      default:
     225        rtems_test_assert(0);
     226        break;
     227    }
     228  } else {
     229    rtems_test_assert(needs_help == NULL);
     230  }
     231}
     232
     233static void test_change_priority_op(void)
     234{
     235  rtems_status_code sc;
     236  rtems_id task_id;
     237  Thread_Control *executing;
     238  Scheduler_SMP_Node *executing_node;
     239  Thread_Control *other;
     240  size_t i;
     241  size_t j;
     242  size_t k;
     243
     244  task_id = start_task(3);
     245
     246  _Thread_Disable_dispatch();
     247
     248  executing = _Thread_Executing;
     249  executing_node = _Scheduler_SMP_Thread_get_node(executing);
     250
     251  other = get_thread_by_id(task_id);
     252
     253  for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) {
     254    for (j = 0; j < RTEMS_ARRAY_SIZE(priorities); ++j) {
     255      for (k = 0; k < RTEMS_ARRAY_SIZE(prepend_it); ++k) {
     256        test_case_change_priority_op(
     257          executing,
     258          executing_node,
     259          other,
     260          states[i],
     261          priorities[j],
     262          prepend_it[k],
     263          states[j]
     264        );
     265      }
     266    }
     267  }
     268
     269  _Thread_Change_priority(executing, 1, true);
     270  rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED);
     271
     272  _Thread_Enable_dispatch();
     273
     274  sc = rtems_task_delete(task_id);
     275  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     276}
     277
     278static Thread_Control *yield_op(Thread_Control *thread)
     279{
     280  const Scheduler_Control *scheduler = _Scheduler_Get(thread);
     281  Thread_Control *needs_help;
     282  ISR_Level level;
     283
     284  _ISR_Disable( level );
     285  needs_help = (*scheduler->Operations.yield)(scheduler, thread);
     286  _ISR_Enable( level );
     287
     288  return needs_help;
     289}
     290
     291static void test_case_yield_op(
     292  Thread_Control *executing,
     293  Scheduler_SMP_Node *executing_node,
     294  Thread_Control *other,
     295  Scheduler_SMP_Node_state start_state,
     296  Scheduler_SMP_Node_state new_state
     297)
     298{
     299  Thread_Control *needs_help;
     300
     301  _Thread_Change_priority(executing, 4, false);
     302  _Thread_Change_priority(other, 4, false);
     303
     304  switch (start_state) {
     305    case SCHEDULER_SMP_NODE_SCHEDULED:
     306      switch (new_state) {
     307        case SCHEDULER_SMP_NODE_SCHEDULED:
     308          _Thread_Change_priority(executing, 2, false);
     309          _Thread_Change_priority(other, 3, false);
     310          break;
     311        case SCHEDULER_SMP_NODE_READY:
     312          _Thread_Change_priority(executing, 2, false);
     313          _Thread_Change_priority(other, 2, false);
     314          break;
     315        default:
     316          rtems_test_assert(0);
     317          break;
     318      }
     319      break;
     320    case SCHEDULER_SMP_NODE_READY:
     321      switch (new_state) {
     322        case SCHEDULER_SMP_NODE_SCHEDULED:
     323          rtems_test_assert(0);
     324          break;
     325        case SCHEDULER_SMP_NODE_READY:
     326          _Thread_Change_priority(executing, 3, false);
     327          _Thread_Change_priority(other, 2, false);
     328          break;
     329        default:
     330          rtems_test_assert(0);
     331          break;
     332      }
     333      break;
     334    default:
     335      rtems_test_assert(0);
     336      break;
     337  }
     338  rtems_test_assert(executing_node->state == start_state);
     339
     340  needs_help = yield_op(executing);
     341  rtems_test_assert(executing_node->state == new_state);
     342
     343  if (start_state != new_state) {
     344    switch (start_state) {
     345      case SCHEDULER_SMP_NODE_SCHEDULED:
     346        rtems_test_assert(needs_help == executing);
     347        break;
     348      case SCHEDULER_SMP_NODE_READY:
     349        rtems_test_assert(needs_help == other);
     350        break;
     351      default:
     352        rtems_test_assert(0);
     353        break;
     354    }
     355  } else {
     356    rtems_test_assert(needs_help == NULL);
     357  }
     358}
     359
     360static void test_yield_op(void)
     361{
     362  rtems_status_code sc;
     363  rtems_id task_id;
     364  Thread_Control *executing;
     365  Scheduler_SMP_Node *executing_node;
     366  Thread_Control *other;
     367  size_t i;
     368  size_t j;
     369
     370  task_id = start_task(2);
     371
     372  _Thread_Disable_dispatch();
     373
     374  executing = _Thread_Executing;
     375  executing_node = _Scheduler_SMP_Thread_get_node(executing);
     376
     377  other = get_thread_by_id(task_id);
     378
     379  for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) {
     380    for (j = 0; j < RTEMS_ARRAY_SIZE(states); ++j) {
     381      if (
     382        states[i] != SCHEDULER_SMP_NODE_READY
     383          || states[j] != SCHEDULER_SMP_NODE_SCHEDULED
     384      ) {
     385        test_case_yield_op(
     386          executing,
     387          executing_node,
     388          other,
     389          states[i],
     390          states[j]
     391        );
     392      }
     393    }
     394  }
     395
     396  _Thread_Change_priority(executing, 1, true);
     397  rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED);
     398
     399  _Thread_Enable_dispatch();
     400
     401  sc = rtems_task_delete(task_id);
     402  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     403}
     404
     405static void block_op(Thread_Control *thread)
     406{
     407  const Scheduler_Control *scheduler = _Scheduler_Get(thread);
     408  ISR_Level level;
     409
     410  _ISR_Disable( level );
     411  (*scheduler->Operations.block)(scheduler, thread);
     412  _ISR_Enable( level );
     413}
     414
     415static Thread_Control *unblock_op(Thread_Control *thread)
     416{
     417  const Scheduler_Control *scheduler = _Scheduler_Get(thread);
     418  Thread_Control *needs_help;
     419  ISR_Level level;
     420
     421  _ISR_Disable( level );
     422  needs_help = (*scheduler->Operations.unblock)(scheduler, thread);
     423  _ISR_Enable( level );
     424
     425  return needs_help;
     426}
     427
     428static void test_case_unblock_op(
     429  Thread_Control *executing,
     430  Scheduler_SMP_Node *executing_node,
     431  Thread_Control *other,
     432  Scheduler_SMP_Node_state new_state
     433)
     434{
     435  Thread_Control *needs_help;
     436
     437  switch (new_state) {
     438    case SCHEDULER_SMP_NODE_SCHEDULED:
     439      _Thread_Change_priority(executing, 2, false);
     440      rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED);
     441      break;
     442    case SCHEDULER_SMP_NODE_READY:
     443      _Thread_Change_priority(executing, 4, false);
     444      rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_READY);
     445      break;
     446    default:
     447      rtems_test_assert(0);
     448      break;
     449  }
     450
     451  block_op(executing);
     452  rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_BLOCKED);
     453
     454  needs_help = unblock_op(executing);
     455  rtems_test_assert(executing_node->state == new_state);
     456
     457  switch (new_state) {
     458    case SCHEDULER_SMP_NODE_SCHEDULED:
     459      rtems_test_assert(needs_help == other);
     460      break;
     461    case SCHEDULER_SMP_NODE_READY:
     462      rtems_test_assert(needs_help == executing);
     463      break;
     464    default:
     465      rtems_test_assert(0);
     466      break;
     467  }
     468}
     469
     470static void test_unblock_op(void)
     471{
     472  rtems_status_code sc;
     473  rtems_id task_id;
     474  Thread_Control *executing;
     475  Scheduler_SMP_Node *executing_node;
     476  Thread_Control *other;
     477  size_t i;
     478
     479  task_id = start_task(3);
     480
     481  _Thread_Disable_dispatch();
     482
     483  executing = _Thread_Executing;
     484  executing_node = _Scheduler_SMP_Thread_get_node(executing);
     485
     486  other = get_thread_by_id(task_id);
     487
     488  for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) {
     489    test_case_unblock_op(
     490      executing,
     491      executing_node,
     492      other,
     493      states[i]
     494    );
     495  }
     496
     497  _Thread_Change_priority(executing, 1, true);
     498  rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED);
     499
     500  _Thread_Enable_dispatch();
     501
     502  sc = rtems_task_delete(task_id);
     503  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     504}
     505
     506static void tests(void)
     507{
     508  test_change_priority();
     509  test_change_priority_op();
     510  test_yield_op();
     511  test_unblock_op();
     512}
     513
    143514static void test_task(rtems_task_argument arg)
    144515{
    145516  test_context *ctx = &test_instance;
    146517
    147   test_change_priority();
     518  tests();
    148519
    149520  ctx->cpu_index[arg] = rtems_get_current_processor();
     
    203574  }
    204575
    205   test_change_priority();
     576  tests();
    206577
    207578  barrier_wait(ctx);
Note: See TracChangeset for help on using the changeset viewer.