Changeset ac532f3 in rtems


Ignore:
Timestamp:
07/04/14 11:40:10 (9 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, 5, master
Children:
8568341
Parents:
08d9760
git-author:
Sebastian Huber <sebastian.huber@…> (07/04/14 11:40:10)
git-committer:
Sebastian Huber <sebastian.huber@…> (07/08/14 14:30:48)
Message:

score: Add _Scheduler_Help()

Manage the help state of threads with respect to scheduling decisions.

Location:
cpukit/score/include/rtems/score
Files:
4 edited

Legend:

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

    r08d9760 rac532f3  
    103103  mrsp->initial_priority_of_owner = initial_priority;
    104104  _MRSP_Elevate_priority( mrsp, new_owner, ceiling_priority );
     105  _Scheduler_Thread_change_help_state( new_owner, SCHEDULER_HELP_ACTIVE_OWNER );
    105106}
    106107
     
    186187  bool previous_life_protection;
    187188  unsigned int state;
     189  Scheduler_Help_state previous_help_state;
    188190
    189191  _MRSP_Elevate_priority( mrsp, executing, ceiling_priority );
     
    194196  _Resource_Add_rival( &mrsp->Resource, &executing->Resource_node );
    195197  _Resource_Node_set_dependency( &executing->Resource_node, &mrsp->Resource );
     198  previous_help_state =
     199    _Scheduler_Thread_change_help_state( executing, SCHEDULER_HELP_ACTIVE_RIVAL );
    196200  _MRSP_Set_root(
    197201    &executing->Resource_node,
     
    235239    status = MRSP_SUCCESSFUL;
    236240  } else {
    237     Resource_Node *executing_node = &executing->Resource_node;
    238 
    239     _Resource_Node_extract( executing_node );
    240     _Resource_Node_set_dependency( executing_node, NULL );
    241     _MRSP_Set_root( executing_node, executing_node );
     241    _Resource_Node_extract( &executing->Resource_node );
     242    _Resource_Node_set_dependency( &executing->Resource_node, NULL );
     243    _Scheduler_Thread_change_help_state( executing, previous_help_state );
     244    _MRSP_Set_root( &executing->Resource_node, &executing->Resource_node );
    242245    _MRSP_Restore_priority( mrsp, executing, initial_priority );
    243246
     
    325328  } else {
    326329    MRSP_Rival *rival = (MRSP_Rival *) _Chain_First( &mrsp->Rivals );
    327     Resource_Node *new_owner = &rival->thread->Resource_node;
    328 
    329     _Resource_Node_extract( new_owner );
    330     _Resource_Node_set_dependency( new_owner, NULL );
    331     _Resource_Node_add_resource( new_owner, &mrsp->Resource );
    332     _Resource_Set_owner( &mrsp->Resource, new_owner );
    333     _MRSP_Set_root( new_owner, new_owner );
     330    Thread_Control *new_owner = rival->thread;
     331
     332    _Resource_Node_extract( &new_owner->Resource_node );
     333    _Resource_Node_set_dependency( &new_owner->Resource_node, NULL );
     334    _Resource_Node_add_resource( &new_owner->Resource_node, &mrsp->Resource );
     335    _Resource_Set_owner( &mrsp->Resource, &new_owner->Resource_node );
     336    _Scheduler_Thread_change_help_state( new_owner, SCHEDULER_HELP_ACTIVE_OWNER );
     337    _MRSP_Set_root( &new_owner->Resource_node, &new_owner->Resource_node );
    334338    _MRSP_Add_state( rival, MRSP_RIVAL_STATE_NEW_OWNER );
     339  }
     340
     341  if ( !_Resource_Node_owns_resources( &executing->Resource_node ) ) {
     342    _Scheduler_Thread_change_help_state( executing, SCHEDULER_HELP_YOURSELF );
    335343  }
    336344
  • cpukit/score/include/rtems/score/scheduler.h

    r08d9760 rac532f3  
    162162};
    163163
     164#if defined(RTEMS_SMP)
     165/**
     166 * @brief State to indicate potential help for other threads.
     167 *
     168 * @dot
     169 * digraph state {
     170 *   y [label="HELP YOURSELF"];
     171 *   ao [label="HELP ACTIVE OWNER"];
     172 *   ar [label="HELP ACTIVE RIVAL"];
     173 *
     174 *   y -> ao [label="obtain"];
     175 *   y -> ar [label="wait for obtain"];
     176 *   ao -> y [label="last release"];
     177 *   ao -> r [label="wait for obtain"];
     178 *   ar -> r [label="timeout"];
     179 *   ar -> ao [label="timeout"];
     180 * }
     181 * @enddot
     182 */
     183typedef enum {
     184  /**
     185   * @brief This scheduler node is solely used by the owner thread.
     186   *
     187   * This thread owns no resources using a helping protocol and thus does not
     188   * take part in the scheduler helping protocol.  No help will be provided for
     189   * other thread.
     190   */
     191  SCHEDULER_HELP_YOURSELF,
     192
     193  /**
     194   * @brief This scheduler node is owned by a thread actively owning a resource.
     195   *
     196   * This scheduler node can be used to help out threads.
     197   *
     198   * In case this scheduler node changes its state from ready to scheduled and
     199   * the thread executes using another node, then an idle thread will be
     200   * provided as a user of this node to temporarily execute on behalf of the
     201   * owner thread.  Thus lower priority threads are denied access to the
     202   * processors of this scheduler instance.
     203   *
     204   * In case a thread actively owning a resource performs a blocking operation,
     205   * then an idle thread will be used also in case this node is in the
     206   * scheduled state.
     207   */
     208  SCHEDULER_HELP_ACTIVE_OWNER,
     209
     210  /**
     211   * @brief This scheduler node is owned by a thread actively obtaining a
     212   * resource currently owned by another thread.
     213   *
     214   * This scheduler node can be used to help out threads.
     215   *
     216   * The thread owning this node is ready and will give away its processor in
     217   * case the thread owning the resource asks for help.
     218   */
     219  SCHEDULER_HELP_ACTIVE_RIVAL,
     220
     221  /**
     222   * @brief This scheduler node is owned by a thread obtaining a
     223   * resource currently owned by another thread.
     224   *
     225   * This scheduler node can be used to help out threads.
     226   *
     227   * The thread owning this node is blocked.
     228   */
     229  SCHEDULER_HELP_PASSIVE
     230} Scheduler_Help_state;
     231#endif
     232
    164233/**
    165234 * @brief Scheduler node for per-thread data.
     
    180249
    181250  /**
     251   * @brief The thread using this node.
     252   */
     253  Thread_Control *user;
     254
     255  /**
     256   * @brief The help state of this node.
     257   */
     258  Scheduler_Help_state help_state;
     259
     260  /**
    182261   * @brief The thread owning this node.
    183262   */
    184263  Thread_Control *owner;
     264
     265  /**
     266   * @brief The idle thread claimed by this node in case the help state is
     267   * SCHEDULER_HELP_ACTIVE_OWNER.
     268   *
     269   * Active owners will lend their own node to an idle thread in case they
     270   * execute currently using another node or in case they perform a blocking
     271   * operation.  This is necessary to ensure the priority ceiling protocols
     272   * work across scheduler boundaries.
     273   */
     274  Thread_Control *idle;
     275
     276  /**
     277   * @brief The thread accepting help by this node in case the help state is
     278   * not SCHEDULER_HELP_YOURSELF.
     279   */
     280  Thread_Control *accepts_help;
    185281#endif
    186282};
  • cpukit/score/include/rtems/score/schedulerimpl.h

    r08d9760 rac532f3  
    7777  return _Scheduler_Get_by_CPU_index( cpu_index );
    7878}
     79
     80#if defined(RTEMS_SMP)
     81RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_user(
     82  const Scheduler_Node *node
     83)
     84{
     85  return node->user;
     86}
     87#endif
    7988
    8089/**
     
    659668{
    660669#if defined(RTEMS_SMP)
     670  node->user = the_thread;
     671  node->help_state = SCHEDULER_HELP_YOURSELF;
    661672  node->owner = the_thread;
     673  node->idle = NULL;
     674  node->accepts_help = the_thread;
    662675#else
    663676  (void) node;
     
    673686  return node->owner;
    674687}
     688
     689RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_idle(
     690  const Scheduler_Node *node
     691)
     692{
     693  return node->idle;
     694}
     695
     696/**
     697 * @brief Changes the scheduler help state of a thread.
     698 *
     699 * @param[in] the_thread The thread.
     700 * @param[in] new_help_state The new help state.
     701 *
     702 * @return The previous help state.
     703 */
     704RTEMS_INLINE_ROUTINE Scheduler_Help_state _Scheduler_Thread_change_help_state(
     705  Thread_Control       *the_thread,
     706  Scheduler_Help_state  new_help_state
     707)
     708{
     709  Scheduler_Node *node = _Scheduler_Thread_get_node( the_thread );
     710  Scheduler_Help_state previous_help_state = node->help_state;
     711
     712  node->help_state = new_help_state;
     713
     714  return previous_help_state;
     715}
    675716#endif
    676717
  • cpukit/score/include/rtems/score/schedulersmpimpl.h

    r08d9760 rac532f3  
    456456)
    457457{
    458   Thread_Control *scheduled_thread = _Scheduler_Node_get_owner( scheduled );
    459   Thread_Control *victim_thread = _Scheduler_Node_get_owner( victim );
     458  Thread_Control *scheduled_thread = _Scheduler_Node_get_user( scheduled );
     459  Thread_Control *victim_thread = _Scheduler_Node_get_user( victim );
    460460
    461461  _Scheduler_SMP_Node_change_state(
Note: See TracChangeset for help on using the changeset viewer.