Changeset f39f667a in rtems


Ignore:
Timestamp:
May 14, 2014, 11:50:48 AM (5 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
3733b224
Parents:
2369b10
git-author:
Sebastian Huber <sebastian.huber@…> (05/14/14 11:50:48)
git-committer:
Sebastian Huber <sebastian.huber@…> (05/15/14 10:18:44)
Message:

score: Simplify _Thread_Change_priority()

The function to change a thread priority was too complex. Simplify it
with a new scheduler operation. This increases the average case
performance due to the simplified logic. The interrupt disabled
critical section is a bit prolonged since now the extract, update and
enqueue steps are executed atomically. This should however not impact
the worst-case interrupt latency since at least for the Deterministic
Priority Scheduler this sequence can be carried out with a wee bit of
instructions and no loops.

Add _Scheduler_Change_priority() to replace the sequence of

  • _Thread_Set_transient(),
  • _Scheduler_Extract(),
  • _Scheduler_Enqueue(), and
  • _Scheduler_Enqueue_first().

Delete STATES_TRANSIENT, _States_Is_transient() and
_Thread_Set_transient() since this state is now superfluous.

With this change it is possible to get rid of the
SCHEDULER_SMP_NODE_IN_THE_AIR state. This considerably simplifies the
implementation of the new SMP locking protocols.

Files:
1 added
14 deleted
32 edited
2 moved

Legend:

Unmodified
Added
Removed
  • cpukit/libmisc/capture/capture.c

    r2369b10 rf39f667a  
    914914
    915915
    916     if (_States_Is_transient (current_task->current_state)
    917      || _States_Is_dormant (current_task->current_state))
     916    if (_States_Is_dormant (current_task->current_state))
    918917    {
    919918      rtems_id ct_id = current_task->Object.id;
  • cpukit/libmisc/monitor/mon-prmisc.c

    r2369b10 rf39f667a  
    117117    { "DORM",   STATES_DORMANT, 0 },
    118118    { "SUSP",   STATES_SUSPENDED, 0 },
    119     { "TRANS",  STATES_TRANSIENT, 0 },
    120119    { "DELAY",  STATES_DELAYING, 0 },
    121120    { "Wtime",  STATES_WAITING_FOR_TIME, 0 },
  • cpukit/posix/src/pthreadexit.c

    r2369b10 rf39f667a  
    5555      } while ( (unblocked = _Thread_queue_Dequeue( &api->Join_List )) );
    5656    } else {
    57       _Thread_Set_state(
    58         the_thread,
    59         STATES_WAITING_FOR_JOIN_AT_EXIT | STATES_TRANSIENT
    60       );
     57      _Thread_Set_state( the_thread, STATES_WAITING_FOR_JOIN_AT_EXIT );
    6158      _Thread_Enable_dispatch();
    6259      /* now waiting for thread to arrive */
  • cpukit/posix/src/pthreadjoin.c

    r2369b10 rf39f667a  
    6262       */
    6363
    64       if ( the_thread->current_state ==
    65              (STATES_WAITING_FOR_JOIN_AT_EXIT | STATES_TRANSIENT) ) {
     64      if ( the_thread->current_state == STATES_WAITING_FOR_JOIN_AT_EXIT ) {
    6665         return_pointer = the_thread->Wait.return_argument;
    67          _Thread_Clear_state(
    68            the_thread,
    69            (STATES_WAITING_FOR_JOIN_AT_EXIT | STATES_TRANSIENT)
    70          );
     66         _Thread_Clear_state( the_thread, STATES_WAITING_FOR_JOIN_AT_EXIT );
    7167      } else {
    7268        executing->Wait.return_argument = &return_pointer;
  • cpukit/score/Makefile.am

    r2369b10 rf39f667a  
    209209libscore_a_SOURCES += src/schedulerpriority.c \
    210210    src/schedulerpriorityblock.c \
    211     src/schedulerpriorityenqueue.c \
    212     src/schedulerpriorityenqueuefirst.c \
    213     src/schedulerpriorityextract.c \
     211    src/schedulerprioritychangepriority.c \
    214212    src/schedulerpriorityprioritycompare.c \
    215213    src/schedulerpriorityschedule.c \
     
    221219libscore_a_SOURCES += src/schedulersimple.c \
    222220    src/schedulersimpleblock.c \
    223     src/schedulersimpleenqueue.c \
    224     src/schedulersimpleenqueuefirst.c \
    225     src/schedulersimpleextract.c \
    226     src/schedulersimplereadyqueueenqueue.c \
    227     src/schedulersimplereadyqueueenqueuefirst.c \
     221    src/schedulersimplechangepriority.c \
    228222    src/schedulersimpleschedule.c \
    229223    src/schedulersimpleunblock.c \
     
    234228    src/scheduleredfallocate.c \
    235229    src/scheduleredfblock.c \
    236     src/scheduleredfenqueue.c \
    237     src/scheduleredfenqueuefirst.c \
    238     src/scheduleredfextract.c \
     230    src/scheduleredfchangepriority.c \
    239231    src/scheduleredfprioritycompare.c \
    240232    src/scheduleredfreleasejob.c \
     
    283275    src/threadloadenv.c src/threadready.c \
    284276    src/threadrestart.c src/threadsetpriority.c \
    285     src/threadsetstate.c src/threadsettransient.c \
     277    src/threadsetstate.c \
    286278    src/threadstackallocate.c src/threadstackfree.c src/threadstart.c \
    287279    src/threadstartmultitasking.c src/iterateoverthreads.c \
  • cpukit/score/include/rtems/score/scheduler.h

    r2369b10 rf39f667a  
    6464  void ( *unblock )( const Scheduler_Control *, Thread_Control * );
    6565
     66  /** @see _Scheduler_Change_priority() */
     67  void ( *change_priority )(
     68    const Scheduler_Control *,
     69    Thread_Control *,
     70    Priority_Control,
     71    bool
     72  );
     73
    6674  /** @see _Scheduler_Allocate() */
    6775  bool ( *allocate )( const Scheduler_Control *, Thread_Control * );
     
    7280  /** @see _Scheduler_Update() */
    7381  void ( *update )( const Scheduler_Control *, Thread_Control * );
    74 
    75   /** @see _Scheduler_Enqueue() */
    76   void ( *enqueue )( const Scheduler_Control *, Thread_Control * );
    77 
    78   /** @see _Scheduler_Enqueue_first() */
    79   void ( *enqueue_first )( const Scheduler_Control *, Thread_Control * );
    80 
    81   /** @see _Scheduler_Extract() */
    82   void ( *extract )( const Scheduler_Control *, Thread_Control * );
    8382
    8483  /** @see _Scheduler_Priority_compare() */
  • cpukit/score/include/rtems/score/schedulercbs.h

    r2369b10 rf39f667a  
    5353    _Scheduler_EDF_Block,            /* block entry point */ \
    5454    _Scheduler_CBS_Unblock,          /* unblock entry point */ \
     55    _Scheduler_EDF_Change_priority,  /* change priority entry point */ \
    5556    _Scheduler_CBS_Allocate,         /* allocate entry point */ \
    5657    _Scheduler_default_Free,         /* free entry point */ \
    5758    _Scheduler_EDF_Update,           /* update entry point */ \
    58     _Scheduler_EDF_Enqueue,          /* enqueue entry point */ \
    59     _Scheduler_EDF_Enqueue_first,    /* enqueue_first entry point */ \
    60     _Scheduler_EDF_Extract,          /* extract entry point */ \
    6159    _Scheduler_EDF_Priority_compare, /* compares two priorities */ \
    6260    _Scheduler_CBS_Release_job,      /* new period of task */ \
  • cpukit/score/include/rtems/score/scheduleredf.h

    r2369b10 rf39f667a  
    4646    _Scheduler_EDF_Block,            /* block entry point */ \
    4747    _Scheduler_EDF_Unblock,          /* unblock entry point */ \
     48    _Scheduler_EDF_Change_priority,  /* change priority entry point */ \
    4849    _Scheduler_EDF_Allocate,         /* allocate entry point */ \
    4950    _Scheduler_default_Free,         /* free entry point */ \
    5051    _Scheduler_EDF_Update,           /* update entry point */ \
    51     _Scheduler_EDF_Enqueue,          /* enqueue entry point */ \
    52     _Scheduler_EDF_Enqueue_first,    /* enqueue_first entry point */ \
    53     _Scheduler_EDF_Extract,          /* extract entry point */ \
    5452    _Scheduler_EDF_Priority_compare, /* compares two priorities */ \
    5553    _Scheduler_EDF_Release_job,      /* new period of task */ \
     
    188186);
    189187
     188void _Scheduler_EDF_Change_priority(
     189  const Scheduler_Control *scheduler,
     190  Thread_Control          *the_thread,
     191  Priority_Control         new_priority,
     192  bool                     prepend_it
     193);
     194
    190195/**
    191196 *  @brief invoked when a thread wishes to voluntarily
     
    204209 */
    205210void _Scheduler_EDF_Yield(
    206   const Scheduler_Control *scheduler,
    207   Thread_Control          *the_thread
    208 );
    209 
    210 /**
    211  *  @brief Put @a the_thread to the rbtree ready queue.
    212  *
    213  *  This routine puts @a the_thread to the rbtree ready queue.
    214  *
    215  *  @param[in] the_thread will be enqueued to the ready queue.
    216  */
    217 void _Scheduler_EDF_Enqueue(
    218   const Scheduler_Control *scheduler,
    219   Thread_Control          *the_thread
    220 );
    221 
    222 /**
    223  *  @brief Enqueue a thread to the ready queue.
    224  *
    225  *  This routine puts @a the_thread to the rbtree ready queue.
    226  *  For the EDF scheduler this is the same as @a _Scheduler_EDF_Enqueue.
    227  *
    228  *  @param[in] the_thread will be enqueued to the ready queue.
    229  */
    230 void _Scheduler_EDF_Enqueue_first(
    231   const Scheduler_Control *scheduler,
    232   Thread_Control          *the_thread
    233 );
    234 
    235 /**
    236  *  @brief Remove a specific thread from the scheduler's set
    237  *  of ready threads.
    238  *
    239  *  This routine removes a specific thread from the scheduler's set
    240  *  of ready threads.
    241  *
    242  *  @param[in] the_thread will be extracted from the ready set.
    243  */
    244 void _Scheduler_EDF_Extract(
    245211  const Scheduler_Control *scheduler,
    246212  Thread_Control          *the_thread
  • cpukit/score/include/rtems/score/scheduleredfimpl.h

    r2369b10 rf39f667a  
    4545}
    4646
     47RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Enqueue(
     48  const Scheduler_Control *scheduler,
     49  Thread_Control          *the_thread
     50)
     51{
     52  Scheduler_EDF_Context *context =
     53    _Scheduler_EDF_Get_context( scheduler );
     54  Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread );
     55
     56  _RBTree_Insert( &context->Ready, &node->Node );
     57  node->queue_state = SCHEDULER_EDF_QUEUE_STATE_YES;
     58}
     59
     60RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Extract(
     61  const Scheduler_Control *scheduler,
     62  Thread_Control          *the_thread
     63)
     64{
     65  Scheduler_EDF_Context *context =
     66    _Scheduler_EDF_Get_context( scheduler );
     67  Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread );
     68
     69  _RBTree_Extract( &context->Ready, &node->Node );
     70}
     71
    4772RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Schedule_body(
    4873  const Scheduler_Control *scheduler,
  • cpukit/score/include/rtems/score/schedulerimpl.h

    r2369b10 rf39f667a  
    145145
    146146/**
     147 * @brief Propagates a priority change of a thread to the scheduler.
     148 *
     149 * The caller must ensure that the thread is in the ready state.  The caller
     150 * must ensure that the priority value actually changed and is not equal to the
     151 * current priority value.
     152 *
     153 * @param[in] scheduler The scheduler instance.
     154 * @param[in] the_thread The thread changing its priority.
     155 * @param[in] new_priority The new thread priority.
     156 * @param[in] prepend_it In case this is true, then enqueue the thread as the
     157 * first of its priority group, otherwise enqueue the thread as the last of its
     158 * priority group.
     159 */
     160RTEMS_INLINE_ROUTINE void _Scheduler_Change_priority(
     161  const Scheduler_Control *scheduler,
     162  Thread_Control          *the_thread,
     163  Priority_Control         new_priority,
     164  bool                     prepend_it
     165)
     166{
     167  ( *scheduler->Operations.change_priority )(
     168    scheduler,
     169    the_thread,
     170    new_priority,
     171    prepend_it
     172  );
     173}
     174
     175/**
    147176 * @brief Scheduler allocate.
    148177 *
     
    181210{
    182211  ( *scheduler->Operations.update )( scheduler, the_thread );
    183 }
    184 
    185 /**
    186  * @brief Enqueues a thread as the last of its priority group.
    187  *
    188  * @param[in] scheduler The scheduler instance.
    189  * @param[in] the_thread The thread to enqueue.
    190  */
    191 RTEMS_INLINE_ROUTINE void _Scheduler_Enqueue(
    192   const Scheduler_Control *scheduler,
    193   Thread_Control          *the_thread
    194 )
    195 {
    196   ( *scheduler->Operations.enqueue )( scheduler, the_thread );
    197 }
    198 
    199 /**
    200  * @brief Enqueues a thread as the first of its priority group.
    201  *
    202  * @param[in] scheduler The scheduler instance.
    203  * @param[in] the_thread The thread to enqueue.
    204  */
    205 RTEMS_INLINE_ROUTINE void _Scheduler_Enqueue_first(
    206   const Scheduler_Control *scheduler,
    207   Thread_Control          *the_thread
    208 )
    209 {
    210   ( *scheduler->Operations.enqueue_first )( scheduler, the_thread );
    211 }
    212 
    213 /**
    214  * @brief Scheduler extract.
    215  *
    216  * This routine extract @a the_thread->scheduler
    217  */
    218 RTEMS_INLINE_ROUTINE void _Scheduler_Extract(
    219   const Scheduler_Control *scheduler,
    220   Thread_Control          *the_thread
    221 )
    222 {
    223   ( *scheduler->Operations.extract )( scheduler, the_thread );
    224212}
    225213
  • cpukit/score/include/rtems/score/schedulerpriority.h

    r2369b10 rf39f667a  
    5353    _Scheduler_priority_Block,            /* block entry point */ \
    5454    _Scheduler_priority_Unblock,          /* unblock entry point */ \
    55     _Scheduler_default_Allocate,         /* allocate entry point */ \
    56     _Scheduler_default_Free,             /* free entry point */ \
     55    _Scheduler_priority_Change_priority,  /* change priority entry point */ \
     56    _Scheduler_default_Allocate,          /* allocate entry point */ \
     57    _Scheduler_default_Free,              /* free entry point */ \
    5758    _Scheduler_priority_Update,           /* update entry point */ \
    58     _Scheduler_priority_Enqueue,          /* enqueue entry point */ \
    59     _Scheduler_priority_Enqueue_first,    /* enqueue_first entry point */ \
    60     _Scheduler_priority_Extract,          /* extract entry point */ \
    6159    _Scheduler_priority_Priority_compare, /* compares two priorities */ \
    6260    _Scheduler_default_Release_job,       /* new period of task */ \
     
    168166);
    169167
     168void _Scheduler_priority_Change_priority(
     169  const Scheduler_Control *scheduler,
     170  Thread_Control          *the_thread,
     171  Priority_Control         new_priority,
     172  bool                     prepend_it
     173);
     174
    170175/**
    171176 *  @brief The specified THREAD yields.
     
    193198
    194199/**
    195  *  @brief Puts @a the_thread on to the priority-based ready queue.
    196  *
    197  *  This routine puts @a the_thread on to the priority-based ready queue.
    198  *
    199  *  @param[in] the_thread will be enqueued at the TAIL of its priority.
    200  */
    201 void _Scheduler_priority_Enqueue(
    202   const Scheduler_Control *scheduler,
    203   Thread_Control          *the_thread
    204 );
    205 
    206 /**
    207  *  @brief Puts @a the_thread to the head of the ready queue.
    208  *
    209  *  This routine puts @a the_thread to the head of the ready queue.
    210  *  For priority-based ready queues, the thread will be the first thread
    211  *  at its priority level.
    212  *
    213  *  @param[in] the_thread will be enqueued at the HEAD of its priority.
    214  */
    215 void _Scheduler_priority_Enqueue_first(
    216   const Scheduler_Control *scheduler,
    217   Thread_Control          *the_thread
    218 );
    219 
    220 /**
    221  *  @brief Remove a specific thread from scheduler.
    222  *
    223  *  This routine removes a specific thread from the scheduler's set
    224  *  of ready threads.
    225  *
    226  *  @param[in] the_thread will be extracted from the ready set.
    227  */
    228 void _Scheduler_priority_Extract(
    229   const Scheduler_Control *scheduler,
    230   Thread_Control          *the_thread
    231 );
    232 
    233 /**
    234200 *  @brief Compare two priorities.
    235201 *
  • cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h

    r2369b10 rf39f667a  
    5454    _Scheduler_priority_SMP_Yield, \
    5555    _Scheduler_priority_SMP_Block, \
    56     _Scheduler_priority_SMP_Enqueue_fifo, \
     56    _Scheduler_priority_SMP_Unblock, \
     57    _Scheduler_priority_SMP_Change_priority, \
    5758    _Scheduler_priority_affinity_SMP_Allocate, \
    5859    _Scheduler_default_Free, \
    5960    _Scheduler_priority_SMP_Update, \
    60     _Scheduler_priority_SMP_Enqueue_fifo, \
    61     _Scheduler_priority_SMP_Enqueue_lifo, \
    62     _Scheduler_priority_SMP_Extract, \
    6361    _Scheduler_priority_Priority_compare, \
    6462    _Scheduler_default_Release_job, \
  • cpukit/score/include/rtems/score/schedulerpriorityimpl.h

    r2369b10 rf39f667a  
    197197
    198198/**
    199  * @brief Updates the specified ready queue data according to the current
    200  * priority of the thread.
    201  *
    202  * @param[in] the_thread The thread.
    203  * @param[in] ready_queue The ready queue.
     199 * @brief Updates the specified ready queue data according to the new priority
     200 * value.
     201 *
     202 * @param[in] ready_queue The ready queue.
     203 * @param[in] new_priority The new priority.
    204204 * @param[in] bit_map The priority bit map of the scheduler instance.
    205205 * @param[in] ready_queues The ready queues of the scheduler instance.
    206206 */
    207207RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_update(
    208   Thread_Control                 *the_thread,
    209   Scheduler_priority_Ready_queue *ready_queue,
     208  Scheduler_priority_Ready_queue *ready_queue,
     209  Priority_Control                new_priority,
    210210  Priority_bit_map_Control       *bit_map,
    211211  Chain_Control                  *ready_queues
    212212)
    213213{
    214   Priority_Control priority = the_thread->current_priority;
    215   ready_queue->ready_chain = &ready_queues[ priority ];
     214  ready_queue->ready_chain = &ready_queues[ new_priority ];
    216215
    217216  _Priority_bit_map_Initialize_information(
    218217    bit_map,
    219218    &ready_queue->Priority_map,
    220     priority
     219    new_priority
    221220  );
    222221}
  • cpukit/score/include/rtems/score/schedulerprioritysmp.h

    r2369b10 rf39f667a  
    88
    99/*
    10  * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
     10 * Copyright (c) 2013-2014 embedded brains GmbH.  All rights reserved.
    1111 *
    1212 *  embedded brains GmbH
     
    8383    _Scheduler_priority_SMP_Yield, \
    8484    _Scheduler_priority_SMP_Block, \
    85     _Scheduler_priority_SMP_Enqueue_fifo, \
     85    _Scheduler_priority_SMP_Unblock, \
     86    _Scheduler_priority_SMP_Change_priority, \
    8687    _Scheduler_priority_SMP_Allocate, \
    8788    _Scheduler_default_Free, \
    8889    _Scheduler_priority_SMP_Update, \
    89     _Scheduler_priority_SMP_Enqueue_fifo, \
    90     _Scheduler_priority_SMP_Enqueue_lifo, \
    91     _Scheduler_priority_SMP_Extract, \
    9290    _Scheduler_priority_Priority_compare, \
    9391    _Scheduler_default_Release_job, \
     
    115113);
    116114
    117 void _Scheduler_priority_SMP_Update(
     115void _Scheduler_priority_SMP_Unblock(
    118116  const Scheduler_Control *scheduler,
    119117  Thread_Control *thread
    120118);
    121119
    122 void _Scheduler_priority_SMP_Enqueue_fifo(
     120void _Scheduler_priority_SMP_Change_priority(
    123121  const Scheduler_Control *scheduler,
    124   Thread_Control *thread
     122  Thread_Control          *the_thread,
     123  Priority_Control         new_priority,
     124  bool                     prepend_it
    125125);
    126126
    127 void _Scheduler_priority_SMP_Enqueue_lifo(
    128   const Scheduler_Control *scheduler,
    129   Thread_Control *thread
    130 );
    131 
    132 void _Scheduler_priority_SMP_Extract(
     127void _Scheduler_priority_SMP_Update(
    133128  const Scheduler_Control *scheduler,
    134129  Thread_Control *thread
  • cpukit/score/include/rtems/score/schedulersimple.h

    r2369b10 rf39f667a  
    4343    _Scheduler_simple_Block,              /* block entry point */ \
    4444    _Scheduler_simple_Unblock,            /* unblock entry point */ \
     45    _Scheduler_simple_Change_priority,    /* change priority entry point */ \
    4546    _Scheduler_default_Allocate,          /* allocate entry point */ \
    4647    _Scheduler_default_Free,              /* free entry point */ \
    4748    _Scheduler_default_Update,            /* update entry point */ \
    48     _Scheduler_simple_Enqueue,            /* enqueue entry point */ \
    49     _Scheduler_simple_Enqueue_first,      /* enqueue_first entry point */ \
    50     _Scheduler_simple_Extract,            /* extract entry point */ \
    5149    _Scheduler_priority_Priority_compare, /* compares two priorities */ \
    5250    _Scheduler_default_Release_job,       /* new period of task */ \
     
    137135);
    138136
    139 /**
    140  *  @brief Removes a simple-priority-based thread from a simple queue.
    141  *
    142  *  This routine removes a specific thread from the specified
    143  *  simple-based ready queue.
    144  *
    145  *  @param[in] the_thread is the thread to be blocked
    146  */
    147 void _Scheduler_simple_Extract(
     137void _Scheduler_simple_Change_priority(
    148138  const Scheduler_Control *scheduler,
    149   Thread_Control          *the_thread
    150 );
    151 
    152 /**
    153  *  @brief Puts simple-priority-based thread onto the ready queue.
    154  *
    155  *  This routine puts @a the_thread on to the ready queue.
    156  *
    157  *  @param[in] the_thread is the thread to be enqueued
    158  */
    159 void _Scheduler_simple_Enqueue(
    160   const Scheduler_Control *scheduler,
    161   Thread_Control          *the_thread
    162 );
    163 
    164 /**
    165  *  @brief Put simple-priority-based @a the_thread to
    166  *  the head of the ready queue.
    167  *
    168  *  This routine puts @a the_thread to the head of the ready queue.
    169  *  The thread will be the first thread at its priority level.
    170  *
    171  *  @param[in] the_thread is the thread to be blocked
    172  */
    173 void _Scheduler_simple_Enqueue_first(
    174   const Scheduler_Control *scheduler,
    175   Thread_Control          *the_thread
    176 );
    177 
    178 /**
    179  *  _Scheduler_simple_Ready_queue_enqueue
    180  *
    181  *  This routine puts @a the_thread on the ready queue
    182  *  at the end of its priority group.
    183  *
    184  *  @param[in] the_thread - pointer to a thread control block
    185  */
    186 void _Scheduler_simple_Ready_queue_enqueue(
    187   const Scheduler_Control *scheduler,
    188   Thread_Control          *the_thread
    189 );
    190 
    191 /**
    192  *  @brief Puts simple-priority-based @a the_thread on to the ready queue
    193  *  at the beginning of its priority group.
    194  *
    195  *  This routine puts @a the_thread on to the ready queue
    196  *  at the beginning of its priority group.
    197  *
    198  *  @param[in] the_thread - pointer to a thread control block
    199  */
    200 void _Scheduler_simple_Ready_queue_enqueue_first(
    201   const Scheduler_Control *scheduler,
    202   Thread_Control          *the_thread
     139  Thread_Control          *the_thread,
     140  Priority_Control         new_priority,
     141  bool                     prepend_it
    203142);
    204143
  • cpukit/score/include/rtems/score/schedulersimpleimpl.h

    r2369b10 rf39f667a  
    3737{
    3838  return (Scheduler_simple_Context *) _Scheduler_Get_context( scheduler );
    39 }
    40 
    41 /**
    42  * This routine puts @a the_thread on to the ready queue.
    43  *
    44  * @param[in] the_ready_queue is a pointer to the ready queue head
    45  * @param[in] the_thread is the thread to be blocked
    46  */
    47 RTEMS_INLINE_ROUTINE void _Scheduler_simple_Ready_queue_requeue(
    48   const Scheduler_Control *scheduler,
    49   Thread_Control          *the_thread
    50 )
    51 {
    52   /* extract */
    53   _Chain_Extract_unprotected( &the_thread->Object.Node );
    54 
    55   /* enqueue */
    56   _Scheduler_simple_Ready_queue_enqueue( scheduler, the_thread );
    5739}
    5840
     
    10385}
    10486
     87RTEMS_INLINE_ROUTINE void _Scheduler_simple_Extract(
     88  const Scheduler_Control *scheduler,
     89  Thread_Control          *the_thread
     90)
     91{
     92  (void) scheduler;
     93
     94  _Chain_Extract_unprotected( &the_thread->Object.Node );
     95}
     96
    10597RTEMS_INLINE_ROUTINE void _Scheduler_simple_Schedule_body(
    10698  const Scheduler_Control *scheduler,
  • cpukit/score/include/rtems/score/schedulersimplesmp.h

    r2369b10 rf39f667a  
    6464    _Scheduler_simple_SMP_Yield, \
    6565    _Scheduler_simple_SMP_Block, \
    66     _Scheduler_simple_SMP_Enqueue_priority_fifo, \
     66    _Scheduler_simple_SMP_Unblock, \
     67    _Scheduler_simple_SMP_Change_priority, \
    6768    _Scheduler_simple_SMP_Allocate, \
    6869    _Scheduler_default_Free, \
    6970    _Scheduler_default_Update, \
    70     _Scheduler_simple_SMP_Enqueue_priority_fifo, \
    71     _Scheduler_simple_SMP_Enqueue_priority_lifo, \
    72     _Scheduler_simple_SMP_Extract, \
    7371    _Scheduler_priority_Priority_compare, \
    7472    _Scheduler_default_Release_job, \
     
    9189);
    9290
    93 void _Scheduler_simple_SMP_Enqueue_priority_fifo(
     91void _Scheduler_simple_SMP_Unblock(
    9492  const Scheduler_Control *scheduler,
    9593  Thread_Control *thread
    9694);
    9795
    98 void _Scheduler_simple_SMP_Enqueue_priority_lifo(
     96void _Scheduler_simple_SMP_Change_priority(
    9997  const Scheduler_Control *scheduler,
    100   Thread_Control *thread
    101 );
    102 
    103 void _Scheduler_simple_SMP_Extract(
    104   const Scheduler_Control *scheduler,
    105   Thread_Control *thread
     98  Thread_Control          *the_thread,
     99  Priority_Control         new_priority,
     100  bool                     prepend_it
    106101);
    107102
  • cpukit/score/include/rtems/score/schedulersmp.h

    r2369b10 rf39f667a  
    7070   * A scheduler node is scheduled if the corresponding thread is ready and the
    7171   * scheduler allocated a processor for it.  A scheduled node is assigned to
    72    * exactly one processor.  The sum of scheduled and in the air nodes equals
    73    * the processor count owned by a scheduler instance.
     72   * exactly one processor.  The count of scheduled nodes in this scheduler
     73   * instance equals the processor count owned by the scheduler instance.
    7474   */
    7575  SCHEDULER_SMP_NODE_SCHEDULED,
     
    8181   * scheduler did not allocate a processor for it.
    8282   */
    83   SCHEDULER_SMP_NODE_READY,
    84 
    85   /**
    86    * @brief This scheduler node is in the air.
    87    *
    88    * A scheduled node is in the air if it has an allocated processor and the
    89    * corresponding thread is in a transient state.  Such a node is not an
    90    * element of the set of scheduled nodes.  The extract operation on a
    91    * scheduled node will produce a scheduler node in the air (see also
    92    * _Thread_Set_transient()).  The next enqueue or schedule operation will
    93    * decide what to do based on this state indication.  It can either place the
    94    * scheduler node back on the set of scheduled nodes and the thread can keep
    95    * its allocated processor, or it can take the processor away from the thread
    96    * and give the processor to another thread of higher priority.
    97    */
    98   SCHEDULER_SMP_NODE_IN_THE_AIR
     83  SCHEDULER_SMP_NODE_READY
    9984} Scheduler_SMP_Node_state;
    10085
  • cpukit/score/include/rtems/score/schedulersmpimpl.h

    r2369b10 rf39f667a  
    3838 * The scheduler nodes can be in four states
    3939 * - @ref SCHEDULER_SMP_NODE_BLOCKED,
    40  * - @ref SCHEDULER_SMP_NODE_SCHEDULED,
    41  * - @ref SCHEDULER_SMP_NODE_READY, and
    42  * - @ref SCHEDULER_SMP_NODE_IN_THE_AIR.
    43  *
    44  * State transitions are triggered via basic three operations
    45  * - _Scheduler_SMP_Enqueue_ordered(),
    46  * - _Scheduler_SMP_Extract(), and
    47  * - _Scheduler_SMP_Schedule().
     40 * - @ref SCHEDULER_SMP_NODE_SCHEDULED, and
     41 * - @ref SCHEDULER_SMP_NODE_READY.
     42 *
     43 * State transitions are triggered via basic operations
     44 * - _Scheduler_SMP_Enqueue_ordered(), and
     45 * - _Scheduler_SMP_Block().
    4846 *
    4947 * @dot
     
    5452 *   ss [label="SCHEDULED", fillcolor="green"];
    5553 *   rs [label="READY", fillcolor="red"];
    56  *   as [label="IN THE AIR", fillcolor="orange"];
    5754 *
    5855 *   edge [label="enqueue"];
     
    6057 *
    6158 *   bs -> ss;
    62  *   as -> ss;
    63  *
    64  *   edge [label="enqueue"];
     59 *
    6560 *   edge [fontcolor="red", color="red"];
    6661 *
    6762 *   bs -> rs;
    68  *   as -> rs;
    6963 *
    7064 *   edge [label="enqueue other"];
     
    7266 *   ss -> rs;
    7367 *
    74  *   edge [label="schedule"];
     68 *   edge [label="block"];
    7569 *   edge [fontcolor="black", color="black"];
    7670 *
    77  *   as -> bs;
    78  *
    79  *   edge [label="extract"];
    80  *   edge [fontcolor="brown", color="brown"];
    81  *
    82  *   ss -> as;
    83  *
    84  *   edge [fontcolor="black", color="black"];
    85  *
    8671 *   rs -> bs;
    8772 *
    88  *   edge [label="enqueue other\nschedule other"];
     73 *   edge [label="block other"];
    8974 *   edge [fontcolor="darkgreen", color="darkgreen"];
    9075 *
     
    217202 * @enddot
    218203 *
    219  * Lets do something with A.  This can be a blocking operation or a priority
    220  * change.  For this an extract operation is performed first.
    221  *
    222  * @dot
    223  * digraph {
    224  *   node [style="filled"];
    225  *   edge [dir="none"];
    226  *
    227  *   subgraph {
    228  *     rank = same;
    229  *
    230  *     b [label="B (2)", fillcolor="green"];
    231  *     a [label="A (1)", fillcolor="orange"];
    232  *     c [label="C (3)", fillcolor="red"];
    233  *     i [label="I (5)", fillcolor="red"];
    234  *     j [label="J (5)", fillcolor="red"];
    235  *     c -> i -> j;
    236  *   }
    237  *
    238  *   subgraph {
    239  *     rank = same;
    240  *
    241  *     p0 [label="PROCESSOR 0", shape="box"];
    242  *     p1 [label="PROCESSOR 1", shape="box"];
    243  *   }
    244  *
    245  *   b -> p0;
    246  *   a -> p1;
    247  * }
    248  * @enddot
    249  *
    250  * Lets change the priority of thread A to 4 and enqueue it.
     204 * Lets change the priority of thread A to 4.
    251205 *
    252206 * @dot
     
    279233 * @enddot
    280234 *
    281  * Alternatively we can also do a blocking operation with thread A.  In this
    282  * case schedule will be called.
     235 * Now perform a blocking operation with thread B.  Please note that thread A
     236 * migrated now from processor 0 to processor 1 and thread C still executes on
     237 * processor 1.
    283238 *
    284239 * @dot
     
    290245 *     rank = same;
    291246 *
    292  *     b [label="B (2)", fillcolor="green"];
    293247 *     c [label="C (3)", fillcolor="green"];
     248 *     a [label="A (4)", fillcolor="green"];
    294249 *     i [label="I (5)", fillcolor="red"];
    295250 *     j [label="J (5)", fillcolor="red"];
    296  *     a [label="A (1)"];
    297  *     b -> c;
     251 *     b [label="B (2)"];
     252 *     c -> a;
    298253 *     i -> j;
    299254 *   }
     
    306261 *   }
    307262 *
    308  *   b -> p0;
     263 *   a -> p0;
    309264 *   c -> p1;
    310265 * }
     
    333288);
    334289
     290typedef void ( *Scheduler_SMP_Update )(
     291  Scheduler_Context *context,
     292  Scheduler_Node *node,
     293  Priority_Control new_priority
     294);
     295
     296typedef void ( *Scheduler_SMP_Enqueue )(
     297  Scheduler_Context *context,
     298  Thread_Control *thread_to_enqueue,
     299  bool has_processor_allocated
     300);
     301
    335302static inline Scheduler_SMP_Context *_Scheduler_SMP_Get_self(
    336303  Scheduler_Context *context
     
    361328}
    362329
    363 extern const bool _Scheduler_SMP_Node_valid_state_changes[ 4 ][ 4 ];
     330extern const bool _Scheduler_SMP_Node_valid_state_changes[ 3 ][ 3 ];
    364331
    365332static inline void _Scheduler_SMP_Node_change_state(
     
    468435 * @param[in] context The scheduler instance context.
    469436 * @param[in] thread The thread to enqueue.
     437 * @param[in] has_processor_allocated The thread has a processor allocated.
    470438 * @param[in] order The order function.
    471439 * @param[in] get_highest_ready Function to get the highest ready node.
     
    482450  Scheduler_Context *context,
    483451  Thread_Control *thread,
     452  bool has_processor_allocated,
    484453  Chain_Node_order order,
    485454  Scheduler_SMP_Get_highest_ready get_highest_ready,
     
    493462  Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
    494463
    495   if ( node->state == SCHEDULER_SMP_NODE_IN_THE_AIR ) {
     464  if ( has_processor_allocated) {
    496465    Thread_Control *highest_ready = ( *get_highest_ready )( &self->Base );
     466
     467    _Assert( highest_ready != NULL);
    497468
    498469    /*
     
    502473     * NOTE: Do not exchange parameters to do the negation of the order check.
    503474     */
    504     if (
    505       highest_ready != NULL
    506         && !( *order )( &thread->Object.Node, &highest_ready->Object.Node )
    507     ) {
     475    if ( !( *order )( &thread->Object.Node, &highest_ready->Object.Node ) ) {
    508476      _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
    509477      _Scheduler_SMP_Allocate_processor( self, highest_ready, thread );
     
    518486      _Scheduler_SMP_Get_lowest_scheduled( self );
    519487
    520     /*
    521      * The scheduled chain is empty if nested interrupts change the priority of
    522      * all scheduled threads.  These threads are in the air.
    523      */
    524     if (
    525       lowest_scheduled != NULL
    526         && ( *order )( &thread->Object.Node, &lowest_scheduled->Object.Node )
    527     ) {
     488    _Assert( lowest_scheduled != NULL);
     489
     490    if ( ( *order )( &thread->Object.Node, &lowest_scheduled->Object.Node ) ) {
    528491      Scheduler_SMP_Node *lowest_scheduled_node =
    529492        _Scheduler_SMP_Node_get( lowest_scheduled );
     
    543506}
    544507
     508static inline void _Scheduler_SMP_Extract_from_scheduled( Thread_Control *thread )
     509{
     510  _Chain_Extract_unprotected( &thread->Object.Node );
     511}
     512
    545513static inline void _Scheduler_SMP_Schedule_highest_ready(
    546514  Scheduler_Context *context,
     
    559527
    560528/**
    561  * @brief Finalize a scheduling operation.
     529 * @brief Blocks a thread.
    562530 *
    563531 * @param[in] context The scheduler instance context.
    564532 * @param[in] thread The thread of the scheduling operation.
     533 * @param[in] extract_from_ready Function to extract a node from the set of
     534 * ready nodes.
    565535 * @param[in] get_highest_ready Function to get the highest ready node.
    566536 * @param[in] move_from_ready_to_scheduled Function to move a node from the set
    567537 * of ready nodes to the set of scheduled nodes.
    568538 */
    569 static inline void _Scheduler_SMP_Schedule(
     539static inline void _Scheduler_SMP_Block(
    570540  Scheduler_Context *context,
    571541  Thread_Control *thread,
     542  Scheduler_SMP_Extract extract_from_ready,
    572543  Scheduler_SMP_Get_highest_ready get_highest_ready,
    573544  Scheduler_SMP_Move move_from_ready_to_scheduled
     
    575546{
    576547  Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
    577 
    578   if ( node->state == SCHEDULER_SMP_NODE_IN_THE_AIR ) {
    579     _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_BLOCKED );
     548  bool is_scheduled = node->state == SCHEDULER_SMP_NODE_SCHEDULED;
     549
     550  _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_BLOCKED );
     551
     552  if ( is_scheduled ) {
     553    _Scheduler_SMP_Extract_from_scheduled( thread );
    580554
    581555    _Scheduler_SMP_Schedule_highest_ready(
     
    585559      move_from_ready_to_scheduled
    586560    );
    587   }
    588 }
    589 
    590 static inline void _Scheduler_SMP_Block(
     561  } else {
     562    ( *extract_from_ready )( context, thread );
     563  }
     564}
     565
     566static inline void _Scheduler_SMP_Change_priority(
    591567  Scheduler_Context *context,
    592568  Thread_Control *thread,
    593   Scheduler_SMP_Extract extract,
    594   Scheduler_SMP_Get_highest_ready get_highest_ready,
    595   Scheduler_SMP_Move move_from_ready_to_scheduled
    596 )
    597 {
    598   ( *extract )( context, thread );
    599 
    600   _Scheduler_SMP_Schedule(
    601     context,
    602     thread,
    603     get_highest_ready,
    604     move_from_ready_to_scheduled
    605   );
    606 }
    607 
    608 /**
    609  * @brief Extracts a thread from the set of scheduled or ready nodes.
    610  *
    611  * @param[in] context The scheduler instance context.
    612  * @param[in] thread The thread to extract.
    613  * @param[in] extract Function to extract a node from the set of scheduled or
    614  * ready nodes.
    615  */
    616 static inline void _Scheduler_SMP_Extract(
    617   Scheduler_Context *context,
    618   Thread_Control *thread,
    619   Scheduler_SMP_Extract extract
    620 )
    621 {
    622   ( *extract )( context, thread );
     569  Priority_Control new_priority,
     570  bool prepend_it,
     571  Scheduler_SMP_Extract extract_from_ready,
     572  Scheduler_SMP_Update update,
     573  Scheduler_SMP_Enqueue enqueue_fifo,
     574  Scheduler_SMP_Enqueue enqueue_lifo
     575)
     576{
     577  Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
     578  bool has_processor_allocated = node->state == SCHEDULER_SMP_NODE_SCHEDULED;
     579
     580  if ( has_processor_allocated ) {
     581    _Scheduler_SMP_Extract_from_scheduled( thread );
     582  } else {
     583    ( *extract_from_ready )( context, thread );
     584  }
     585
     586  ( *update )( context, &node->Base, new_priority );
     587
     588  if ( prepend_it ) {
     589    ( *enqueue_lifo )( context, thread, has_processor_allocated );
     590  } else {
     591    ( *enqueue_fifo )( context, thread, has_processor_allocated );
     592  }
    623593}
    624594
  • cpukit/score/include/rtems/score/statesimpl.h

    r2369b10 rf39f667a  
    4343/** This macro corresponds to a task being suspended. */
    4444#define STATES_SUSPENDED                       0x00002
    45 /** This macro corresponds to a task being in an internal state transition. */
    46 #define STATES_TRANSIENT                       0x00004
    4745/** This macro corresponds to a task which is waiting for a timeout. */
    4846#define STATES_DELAYING                        0x00008
     
    216214
    217215/**
    218  * This function returns true if the TRANSIENT state is set in
    219  * the_states, and false otherwise.
    220  *
    221  * @param[in] the_states is the task state set to test
    222  *
    223  * @return This method returns true if the desired state condition is set.
    224  */
    225 RTEMS_INLINE_ROUTINE bool _States_Is_transient (
    226   States_Control the_states
    227 )
    228 {
    229    return (the_states & STATES_TRANSIENT);
    230 }
    231 
    232 /**
    233216 * This function returns true if the DELAYING state is set in
    234217 * the_states, and false otherwise.
  • cpukit/score/src/schedulercbsunblock.c

    r2369b10 rf39f667a  
    2121
    2222#include <rtems/score/schedulercbsimpl.h>
     23#include <rtems/score/scheduleredfimpl.h>
    2324#include <rtems/score/schedulerimpl.h>
    2425#include <rtems/score/threadimpl.h>
  • cpukit/score/src/scheduleredfchangepriority.c

    r2369b10 rf39f667a  
    2121#include <rtems/score/scheduleredfimpl.h>
    2222
    23 void _Scheduler_EDF_Extract(
     23void _Scheduler_EDF_Change_priority(
    2424  const Scheduler_Control *scheduler,
    25   Thread_Control          *the_thread
     25  Thread_Control          *the_thread,
     26  Priority_Control         new_priority,
     27  bool                     prepend_it
    2628)
    2729{
     
    3133
    3234  _RBTree_Extract( &context->Ready, &node->Node );
    33   node->queue_state = SCHEDULER_EDF_QUEUE_STATE_NOT_PRESENTLY;
     35  _RBTree_Insert( &context->Ready, &node->Node );
    3436}
  • cpukit/score/src/scheduleredfunblock.c

    r2369b10 rf39f667a  
    1919#endif
    2020
    21 #include <rtems/score/scheduleredf.h>
     21#include <rtems/score/scheduleredfimpl.h>
    2222#include <rtems/score/schedulerimpl.h>
    2323#include <rtems/score/thread.h>
  • cpukit/score/src/schedulerprioritysmp.c

    r2369b10 rf39f667a  
    2828#include <rtems/score/schedulerpriorityimpl.h>
    2929#include <rtems/score/schedulersmpimpl.h>
    30 #include <rtems/score/wkspace.h>
    3130
    3231static Scheduler_priority_SMP_Context *
     
    4746{
    4847  return (Scheduler_priority_SMP_Node *) _Scheduler_Node_get( thread );
     48}
     49
     50static Scheduler_priority_SMP_Node *_Scheduler_priority_SMP_Node_downcast(
     51  Scheduler_Node *node
     52)
     53{
     54  return (Scheduler_priority_SMP_Node *) node;
    4955}
    5056
     
    7177}
    7278
    73 void _Scheduler_priority_SMP_Update(
    74   const Scheduler_Control *scheduler,
    75   Thread_Control *thread
    76 )
    77 {
    78   Scheduler_priority_SMP_Context *self =
    79     _Scheduler_priority_SMP_Get_context( scheduler );
    80   Scheduler_priority_SMP_Node *node =
    81     _Scheduler_priority_SMP_Node_get( thread );
     79static void _Scheduler_priority_SMP_Do_update(
     80  Scheduler_Context *context,
     81  Scheduler_Node *base_node,
     82  Priority_Control new_priority
     83)
     84{
     85  Scheduler_priority_SMP_Context *self =
     86    _Scheduler_priority_SMP_Get_self( context );
     87  Scheduler_priority_SMP_Node *node =
     88    _Scheduler_priority_SMP_Node_downcast( base_node );
    8289
    8390  _Scheduler_priority_Ready_queue_update(
    84     thread,
    85     &node->Ready_queue,
     91    &node->Ready_queue,
     92    new_priority,
    8693    &self->Bit_map,
    8794    &self->Ready[ 0 ]
     
    8996}
    9097
     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
    91109static Thread_Control *_Scheduler_priority_SMP_Get_highest_ready(
    92110  Scheduler_Context *context
     
    95113  Scheduler_priority_SMP_Context *self =
    96114    _Scheduler_priority_SMP_Get_self( context );
    97   Thread_Control *highest_ready = NULL;
    98 
    99   if ( !_Priority_bit_map_Is_empty( &self->Bit_map ) ) {
    100     highest_ready = _Scheduler_priority_Ready_queue_first(
    101       &self->Bit_map,
    102       &self->Ready[ 0 ]
    103     );
    104   }
    105 
    106   return highest_ready;
     115
     116  return _Scheduler_priority_Ready_queue_first(
     117    &self->Bit_map,
     118    &self->Ready[ 0 ]
     119  );
    107120}
    108121
     
    180193}
    181194
    182 static void _Scheduler_priority_SMP_Do_extract(
     195static void _Scheduler_priority_SMP_Extract_from_ready(
    183196  Scheduler_Context *context,
    184197  Thread_Control *thread
     
    190203    _Scheduler_priority_SMP_Node_get( thread );
    191204
    192   if ( node->Base.state == SCHEDULER_SMP_NODE_SCHEDULED ) {
    193     _Scheduler_SMP_Node_change_state(
    194       &node->Base,
    195       SCHEDULER_SMP_NODE_IN_THE_AIR
    196     );
    197     _Chain_Extract_unprotected( &thread->Object.Node );
    198   } else {
    199     _Scheduler_SMP_Node_change_state(
    200       &node->Base,
    201       SCHEDULER_SMP_NODE_BLOCKED
    202     );
    203     _Scheduler_priority_Ready_queue_extract(
    204       thread,
    205       &node->Ready_queue,
    206       &self->Bit_map
    207     );
    208   }
     205  _Scheduler_priority_Ready_queue_extract(
     206    thread,
     207    &node->Ready_queue,
     208    &self->Bit_map
     209  );
    209210}
    210211
     
    214215)
    215216{
    216   Scheduler_priority_SMP_Context *self =
    217     _Scheduler_priority_SMP_Get_context( scheduler );
     217  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
    218218
    219219  _Scheduler_SMP_Block(
    220     &self->Base.Base,
    221     thread,
    222     _Scheduler_priority_SMP_Do_extract,
     220    context,
     221    thread,
     222    _Scheduler_priority_SMP_Extract_from_ready,
    223223    _Scheduler_priority_SMP_Get_highest_ready,
    224224    _Scheduler_priority_SMP_Move_from_ready_to_scheduled
     
    229229  Scheduler_Context *context,
    230230  Thread_Control *thread,
     231  bool has_processor_allocated,
    231232  Chain_Node_order order,
    232233  Scheduler_SMP_Insert insert_ready,
     
    237238    context,
    238239    thread,
     240    has_processor_allocated,
    239241    order,
    240242    _Scheduler_priority_SMP_Get_highest_ready,
     
    246248}
    247249
    248 void _Scheduler_priority_SMP_Enqueue_lifo(
    249   const Scheduler_Control *scheduler,
    250   Thread_Control *thread
    251 )
    252 {
    253   Scheduler_priority_SMP_Context *self =
    254     _Scheduler_priority_SMP_Get_context( scheduler );
    255 
     250static void _Scheduler_priority_SMP_Enqueue_lifo(
     251  Scheduler_Context *context,
     252  Thread_Control *thread,
     253  bool has_processor_allocated
     254)
     255{
    256256  _Scheduler_priority_SMP_Enqueue_ordered(
    257     &self->Base.Base,
    258     thread,
     257    context,
     258    thread,
     259    has_processor_allocated,
    259260    _Scheduler_simple_Insert_priority_lifo_order,
    260261    _Scheduler_priority_SMP_Insert_ready_lifo,
     
    263264}
    264265
    265 void _Scheduler_priority_SMP_Enqueue_fifo(
    266   const Scheduler_Control *scheduler,
    267   Thread_Control *thread
    268 )
    269 {
    270   Scheduler_priority_SMP_Context *self =
    271     _Scheduler_priority_SMP_Get_context( scheduler );
    272 
     266static void _Scheduler_priority_SMP_Enqueue_fifo(
     267  Scheduler_Context *context,
     268  Thread_Control *thread,
     269  bool has_processor_allocated
     270)
     271{
    273272  _Scheduler_priority_SMP_Enqueue_ordered(
    274     &self->Base.Base,
    275     thread,
     273    context,
     274    thread,
     275    has_processor_allocated,
    276276    _Scheduler_simple_Insert_priority_fifo_order,
    277277    _Scheduler_priority_SMP_Insert_ready_fifo,
     
    280280}
    281281
    282 void _Scheduler_priority_SMP_Extract(
    283   const Scheduler_Control *scheduler,
    284   Thread_Control *thread
    285 )
    286 {
    287   Scheduler_priority_SMP_Context *self =
    288     _Scheduler_priority_SMP_Get_context( scheduler );
    289 
    290   _Scheduler_SMP_Extract(
    291     &self->Base.Base,
    292     thread,
    293     _Scheduler_priority_SMP_Do_extract
     282void _Scheduler_priority_SMP_Unblock(
     283  const Scheduler_Control *scheduler,
     284  Thread_Control *thread
     285)
     286{
     287  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
     288
     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,
     303    thread,
     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
    294310  );
    295311}
     
    300316)
    301317{
     318  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
    302319  ISR_Level level;
    303320
    304321  _ISR_Disable( level );
    305322
    306   _Scheduler_priority_SMP_Extract( scheduler, thread );
    307   _Scheduler_priority_SMP_Enqueue_fifo( scheduler, thread );
     323  _Scheduler_SMP_Extract_from_scheduled( thread );
     324  _Scheduler_priority_SMP_Enqueue_fifo( context, thread, true );
    308325
    309326  _ISR_Enable( level );
     
    315332)
    316333{
    317   Scheduler_priority_SMP_Context *self =
    318     _Scheduler_priority_SMP_Get_context( scheduler );
    319 
    320   _Scheduler_SMP_Schedule(
    321     &self->Base.Base,
    322     thread,
    323     _Scheduler_priority_SMP_Get_highest_ready,
    324     _Scheduler_priority_SMP_Move_from_ready_to_scheduled
    325   );
     334  (void) scheduler;
     335  (void) thread;
    326336}
    327337
     
    332342)
    333343{
    334   Scheduler_priority_SMP_Context *self =
    335     _Scheduler_priority_SMP_Get_context( scheduler );
    336 
    337   _Scheduler_SMP_Start_idle( &self->Base.Base, thread, cpu );
    338 }
     344  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
     345
     346  _Scheduler_SMP_Start_idle( context, thread, cpu );
     347}
  • cpukit/score/src/schedulerpriorityupdate.c

    r2369b10 rf39f667a  
    3131
    3232  _Scheduler_priority_Ready_queue_update(
    33     the_thread,
    3433    &node->Ready_queue,
     34    the_thread->current_priority,
    3535    &context->Bit_map,
    3636    &context->Ready[ 0 ]
  • cpukit/score/src/schedulersimplechangepriority.c

    r2369b10 rf39f667a  
    22 * @file
    33 *
    4  * @brief Scheduler Simple Priority Enqueue Ready Thread
     4 * @brief Removes a Thread from the Simple Queue
     5 *
    56 * @ingroup ScoreScheduler
    67 */
     
    2122#include <rtems/score/schedulersimpleimpl.h>
    2223
    23 void _Scheduler_simple_Ready_queue_enqueue(
     24void _Scheduler_simple_Change_priority(
    2425  const Scheduler_Control *scheduler,
    25   Thread_Control          *the_thread
     26  Thread_Control          *the_thread,
     27  Priority_Control         new_priority,
     28  bool                     prepend_it
    2629)
    2730{
     
    2932    _Scheduler_simple_Get_context( scheduler );
    3033
    31   _Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread );
     34  _Scheduler_simple_Extract( scheduler, the_thread );
     35
     36  if ( prepend_it ) {
     37    _Scheduler_simple_Insert_priority_lifo( &context->Ready, the_thread );
     38  } else {
     39    _Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread );
     40  }
    3241}
  • cpukit/score/src/schedulersimplesmp.c

    r2369b10 rf39f667a  
    2121#include <rtems/score/schedulersimplesmp.h>
    2222#include <rtems/score/schedulersmpimpl.h>
    23 #include <rtems/score/wkspace.h>
    2423
    2524static Scheduler_simple_SMP_Context *
     
    5655}
    5756
     57static void _Scheduler_simple_SMP_Do_update(
     58  Scheduler_Context *context,
     59  Scheduler_Node *node,
     60  Priority_Control new_priority
     61)
     62{
     63  (void) context;
     64  (void) node;
     65  (void) new_priority;
     66}
     67
    5868static Thread_Control *_Scheduler_simple_SMP_Get_highest_ready(
    5969  Scheduler_Context *context
     
    6272  Scheduler_simple_SMP_Context *self =
    6373    _Scheduler_simple_SMP_Get_self( context );
    64   Thread_Control *highest_ready = NULL;
    65   Chain_Control *ready = &self->Ready;
    66 
    67   if ( !_Chain_Is_empty( ready ) ) {
    68     highest_ready = (Thread_Control *) _Chain_First( ready );
    69   }
    70 
    71   return highest_ready;
     74
     75  return (Thread_Control *) _Chain_First( &self->Ready );
    7276}
    7377
     
    132136}
    133137
    134 static void _Scheduler_simple_SMP_Do_extract(
    135   Scheduler_Context *context,
    136   Thread_Control *thread
    137 )
    138 {
    139   Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
    140 
     138static void _Scheduler_simple_SMP_Extract_from_ready(
     139  Scheduler_Context *context,
     140  Thread_Control *thread
     141)
     142{
    141143  (void) context;
    142144
    143   if ( node->state == SCHEDULER_SMP_NODE_SCHEDULED ) {
    144     _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_IN_THE_AIR );
    145   } else {
    146     _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_BLOCKED );
    147   }
    148 
    149145  _Chain_Extract_unprotected( &thread->Object.Node );
    150146}
     
    155151)
    156152{
    157   Scheduler_simple_SMP_Context *self =
    158     _Scheduler_simple_SMP_Get_context( scheduler );
     153  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
    159154
    160155  _Scheduler_SMP_Block(
    161     &self->Base.Base,
    162     thread,
    163     _Scheduler_simple_SMP_Do_extract,
     156    context,
     157    thread,
     158    _Scheduler_simple_SMP_Extract_from_ready,
    164159    _Scheduler_simple_SMP_Get_highest_ready,
    165160    _Scheduler_simple_SMP_Move_from_ready_to_scheduled
     
    170165  Scheduler_Context *context,
    171166  Thread_Control *thread,
     167  bool has_processor_allocated,
    172168  Chain_Node_order order,
    173169  Scheduler_SMP_Insert insert_ready,
     
    178174    context,
    179175    thread,
     176    has_processor_allocated,
    180177    order,
    181178    _Scheduler_simple_SMP_Get_highest_ready,
     
    187184}
    188185
    189 void _Scheduler_simple_SMP_Enqueue_priority_lifo(
    190   const Scheduler_Control *scheduler,
    191   Thread_Control *thread
    192 )
    193 {
    194   Scheduler_simple_SMP_Context *self =
    195     _Scheduler_simple_SMP_Get_context( scheduler );
    196 
     186static void _Scheduler_simple_SMP_Enqueue_lifo(
     187  Scheduler_Context *context,
     188  Thread_Control *thread,
     189  bool has_processor_allocated
     190)
     191{
    197192  _Scheduler_simple_SMP_Enqueue_ordered(
    198     &self->Base.Base,
    199     thread,
     193    context,
     194    thread,
     195    has_processor_allocated,
    200196    _Scheduler_simple_Insert_priority_lifo_order,
    201197    _Scheduler_simple_SMP_Insert_ready_lifo,
     
    204200}
    205201
    206 void _Scheduler_simple_SMP_Enqueue_priority_fifo(
    207   const Scheduler_Control *scheduler,
    208   Thread_Control *thread
    209 )
    210 {
    211   Scheduler_simple_SMP_Context *self =
    212     _Scheduler_simple_SMP_Get_context( scheduler );
    213 
     202static void _Scheduler_simple_SMP_Enqueue_fifo(
     203  Scheduler_Context *context,
     204  Thread_Control *thread,
     205  bool has_processor_allocated
     206)
     207{
    214208  _Scheduler_simple_SMP_Enqueue_ordered(
    215     &self->Base.Base,
    216     thread,
     209    context,
     210    thread,
     211    has_processor_allocated,
    217212    _Scheduler_simple_Insert_priority_fifo_order,
    218213    _Scheduler_simple_SMP_Insert_ready_fifo,
     
    221216}
    222217
    223 void _Scheduler_simple_SMP_Extract(
    224   const Scheduler_Control *scheduler,
    225   Thread_Control *thread
    226 )
    227 {
    228   Scheduler_simple_SMP_Context *self =
    229     _Scheduler_simple_SMP_Get_context( scheduler );
    230 
    231   _Scheduler_SMP_Extract(
    232     &self->Base.Base,
    233     thread,
    234     _Scheduler_simple_SMP_Do_extract
     218void _Scheduler_simple_SMP_Unblock(
     219  const Scheduler_Control *scheduler,
     220  Thread_Control *thread
     221)
     222{
     223  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
     224
     225  _Scheduler_simple_SMP_Enqueue_fifo( context, thread, false );
     226}
     227
     228void _Scheduler_simple_SMP_Change_priority(
     229  const Scheduler_Control *scheduler,
     230  Thread_Control          *thread,
     231  Priority_Control         new_priority,
     232  bool                     prepend_it
     233)
     234{
     235  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
     236
     237  _Scheduler_SMP_Change_priority(
     238    context,
     239    thread,
     240    new_priority,
     241    prepend_it,
     242    _Scheduler_simple_SMP_Extract_from_ready,
     243    _Scheduler_simple_SMP_Do_update,
     244    _Scheduler_simple_SMP_Enqueue_fifo,
     245    _Scheduler_simple_SMP_Enqueue_lifo
    235246  );
    236247}
     
    241252)
    242253{
     254  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
    243255  ISR_Level level;
    244256
    245257  _ISR_Disable( level );
    246258
    247   _Scheduler_simple_SMP_Extract( scheduler, thread );
    248   _Scheduler_simple_SMP_Enqueue_priority_fifo( scheduler, thread );
     259  _Scheduler_SMP_Extract_from_scheduled( thread );
     260  _Scheduler_simple_SMP_Enqueue_fifo( context, thread, true );
    249261
    250262  _ISR_Enable( level );
     
    256268)
    257269{
    258   Scheduler_simple_SMP_Context *self =
    259     _Scheduler_simple_SMP_Get_context( scheduler );
    260 
    261   _Scheduler_SMP_Schedule(
    262     &self->Base.Base,
    263     thread,
    264     _Scheduler_simple_SMP_Get_highest_ready,
    265     _Scheduler_simple_SMP_Move_from_ready_to_scheduled
    266   );
     270  (void) scheduler;
     271  (void) thread;
    267272}
    268273
     
    273278)
    274279{
    275   Scheduler_simple_SMP_Context *self =
    276     _Scheduler_simple_SMP_Get_context( scheduler );
    277 
    278   _Scheduler_SMP_Start_idle( &self->Base.Base, thread, cpu );
    279 }
     280  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
     281
     282  _Scheduler_SMP_Start_idle( context, thread, cpu );
     283}
  • cpukit/score/src/schedulersimpleunblock.c

    r2369b10 rf39f667a  
    2727)
    2828{
    29   _Scheduler_simple_Ready_queue_enqueue( scheduler, the_thread );
     29  Scheduler_simple_Context *context =
     30    _Scheduler_simple_Get_context( scheduler );
     31
     32  _Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread );
    3033
    3134  /*
  • cpukit/score/src/schedulersimpleyield.c

    r2369b10 rf39f667a  
    2727)
    2828{
     29  Scheduler_simple_Context *context =
     30    _Scheduler_simple_Get_context( scheduler );
    2931  ISR_Level       level;
    3032
    3133  _ISR_Disable( level );
    3234
    33     _Scheduler_simple_Ready_queue_requeue( scheduler, the_thread );
     35    _Chain_Extract_unprotected( &the_thread->Object.Node );
     36    _Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread );
    3437
    3538    _ISR_Flash( level );
  • cpukit/score/src/schedulersmpvalidstatechanges.c

    r2369b10 rf39f667a  
    3131 * _Scheduler_SMP_Node_change_state() in case RTEMS_DEBUG is defined.
    3232 */
    33 const bool _Scheduler_SMP_Node_valid_state_changes[ 4 ][ 4 ] = {
    34   /*                 BLOCKED SCHEDULED READY  IN THE AIR */
    35   /* BLOCKED    */ { false,  true,     true,  false },
    36   /* SCHEDULED  */ { false,  false,    true,  true },
    37   /* READY      */ { true,   true,     false, false },
    38   /* IN THE AIR */ { true,   true,     true,  false }
     33const bool _Scheduler_SMP_Node_valid_state_changes[ 3 ][ 3 ] = {
     34  /* FROM / TO       BLOCKED SCHEDULED READY */
     35  /* BLOCKED    */ { false,  true,     true },
     36  /* SCHEDULED  */ { true,   false,    true },
     37  /* READY      */ { true,   true,     false }
    3938};
  • cpukit/score/src/threadchangepriority.c

    r2369b10 rf39f667a  
    3030)
    3131{
    32   const Scheduler_Control *scheduler = _Scheduler_Get( the_thread );
    33   ISR_Level                level;
    34   States_Control           state, original_state;
    35 
    36   /*
    37    * Save original state
    38    */
    39   original_state = the_thread->current_state;
    40 
    41   /*
    42    * Set a transient state for the thread so it is pulled off the Ready chains.
    43    * This will prevent it from being scheduled no matter what happens in an
    44    * ISR.
    45    */
    46   _Thread_Set_transient( the_thread );
    47 
    4832  /*
    4933   *  Do not bother recomputing all the priority related information if
    5034   *  we are not REALLY changing priority.
    5135   */
    52  if ( the_thread->current_priority != new_priority )
    53     _Thread_Set_priority( the_thread, new_priority );
     36  if ( the_thread->current_priority != new_priority ) {
     37    ISR_Level                level;
     38    const Scheduler_Control *scheduler;
    5439
    55   _ISR_Disable( level );
     40    _ISR_Disable( level );
    5641
    57   /*
    58    *  If the thread has more than STATES_TRANSIENT set, then it is blocked,
    59    *  If it is blocked on a thread queue, then we need to requeue it.
    60    */
    61   state = the_thread->current_state;
    62   if ( state != STATES_TRANSIENT ) {
    63     /* Only clear the transient state if it wasn't set already */
    64     if ( ! _States_Is_transient( original_state ) )
    65       the_thread->current_state = _States_Clear( STATES_TRANSIENT, state );
     42    scheduler = _Scheduler_Get( the_thread );
     43    the_thread->current_priority = new_priority;
    6644
    67     /*
    68      * The thread may have new blocking states added by interrupt service
    69      * routines after the change into the transient state.  This will not
    70      * result in a _Scheduler_Block() operation.  Make sure we select an heir
    71      * now.
    72      */
    73     _Scheduler_Schedule( scheduler, the_thread );
     45    if ( _States_Is_ready( the_thread->current_state ) ) {
     46      _Scheduler_Change_priority(
     47        scheduler,
     48        the_thread,
     49        new_priority,
     50        prepend_it
     51      );
    7452
     53      _ISR_Flash( level );
     54
     55      /*
     56       *  We altered the set of thread priorities.  So let's figure out
     57       *  who is the heir and if we need to switch to them.
     58       */
     59      scheduler = _Scheduler_Get( the_thread );
     60      _Scheduler_Schedule( scheduler, the_thread );
     61    } else {
     62      _Scheduler_Update( scheduler, the_thread );
     63    }
    7564    _ISR_Enable( level );
    76     if ( _States_Is_waiting_on_thread_queue( state ) ) {
    77       _Thread_queue_Requeue( the_thread->Wait.queue, the_thread );
    78     }
    79     return;
     65
     66    _Thread_queue_Requeue( the_thread->Wait.queue, the_thread );
    8067  }
    81 
    82   /* Only clear the transient state if it wasn't set already */
    83   if ( ! _States_Is_transient( original_state ) ) {
    84     /*
    85      *  Interrupts are STILL disabled.
    86      *  We now know the thread will be in the READY state when we remove
    87      *  the TRANSIENT state.  So we have to place it on the appropriate
    88      *  Ready Queue with interrupts off.
    89      */
    90     the_thread->current_state = _States_Clear( STATES_TRANSIENT, state );
    91 
    92     if ( prepend_it )
    93       _Scheduler_Enqueue_first( scheduler, the_thread );
    94     else
    95       _Scheduler_Enqueue( scheduler, the_thread );
    96   }
    97 
    98   _ISR_Flash( level );
    99 
    100   /*
    101    *  We altered the set of thread priorities.  So let's figure out
    102    *  who is the heir and if we need to switch to them.
    103    */
    104   _Scheduler_Schedule( scheduler, the_thread );
    105 
    106   _ISR_Enable( level );
    10768}
  • doc/user/glossary.texi

    r2369b10 rf39f667a  
    278278A special low priority task which assumes
    279279control of the CPU when no other task is able to execute.
    280 
    281 @item in the air task
    282 A task is @dfn{in the air} if it is in a transient state and has a processor
    283 assigned.  The next scheduler operation will turn it into a blocked, ready or
    284 scheduled task.  This state is specific to SMP configurations.
    285280
    286281@item interface
  • testsuites/sptests/Makefile.am

    r2369b10 rf39f667a  
    5151_SUBDIRS += sptls01
    5252_SUBDIRS += spintrcritical20
    53 _SUBDIRS += spintrcritical19
    5453_SUBDIRS += spcontext01
    5554_SUBDIRS += spfatal26
  • testsuites/sptests/configure.ac

    r2369b10 rf39f667a  
    5151sptls01/Makefile
    5252spintrcritical20/Makefile
    53 spintrcritical19/Makefile
    5453spcontext01/Makefile
    5554spfatal26/Makefile
Note: See TracChangeset for help on using the changeset viewer.