Changeset dafa5d88 in rtems


Ignore:
Timestamp:
Sep 3, 2015, 8:27:16 AM (4 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
e1769f27
Parents:
3995e6d
git-author:
Sebastian Huber <sebastian.huber@…> (09/03/15 08:27:16)
git-committer:
Sebastian Huber <sebastian.huber@…> (09/04/15 11:26:17)
Message:

score: Implement priority boosting

Files:
11 edited

Legend:

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

    r3995e6d rdafa5d88  
    436436  Priority_Control  new_priority
    437437);
     438
     439/**
     440 * @brief Inherit the priority of a thread.
     441 *
     442 * It changes the current priority of the inheritor thread to the current priority
     443 * of the ancestor thread if it is higher than the current priority of the inheritor
     444 * thread.  In this case the inheritor thread is appended to its new priority group
     445 * in its scheduler instance.
     446 *
     447 * On SMP configurations, the priority is changed to PRIORITY_PSEUDO_ISR in
     448 * case the own schedulers of the inheritor and ancestor thread differ (priority
     449 * boosting).
     450 *
     451 * @param[in] inheritor The thread to inherit the priority.
     452 * @param[in] ancestor The thread to bequeath its priority to the inheritor
     453 *   thread.
     454 */
     455#if defined(RTEMS_SMP)
     456void _Thread_Inherit_priority(
     457  Thread_Control *inheritor,
     458  Thread_Control *ancestor
     459);
     460#else
     461RTEMS_INLINE_ROUTINE void _Thread_Inherit_priority(
     462  Thread_Control *inheritor,
     463  Thread_Control *ancestor
     464)
     465{
     466  _Thread_Raise_priority( inheritor, ancestor->current_priority );
     467}
     468#endif
    438469
    439470/**
  • cpukit/score/include/rtems/score/threadqimpl.h

    r3995e6d rdafa5d88  
    523523
    524524/**
     525 * @brief Boosts the priority of the thread if threads of another scheduler
     526 * instance are enqueued on the thread queue.
     527 *
     528 * The thread queue must use the priority waiting discipline.
     529 *
     530 * @param[in] queue The actual thread queue.
     531 * @param[in] the_thread The thread to boost the priority if necessary.
     532 */
     533#if defined(RTEMS_SMP)
     534void _Thread_queue_Boost_priority(
     535  Thread_queue_Queue *queue,
     536  Thread_Control     *the_thread
     537);
     538#else
     539RTEMS_INLINE_ROUTINE void _Thread_queue_Boost_priority(
     540  Thread_queue_Queue *queue,
     541  Thread_Control     *the_thread
     542)
     543{
     544  (void) queue;
     545  (void) the_thread;
     546}
     547#endif
     548
     549/**
    525550 * @brief Compare two thread's priority for RBTree Insertion.
    526551 *
  • cpukit/score/src/coremutexseize.c

    r3995e6d rdafa5d88  
    7676#endif
    7777
    78     _Thread_Raise_priority( holder, executing->current_priority );
     78    _Thread_Inherit_priority( holder, executing );
    7979
    8080#if !defined(RTEMS_SMP)
  • cpukit/score/src/coremutexsurrender.c

    r3995e6d rdafa5d88  
    210210          _CORE_mutex_Push_priority( the_mutex, the_thread );
    211211          the_thread->resource_count++;
     212          _Thread_queue_Boost_priority( &the_mutex->Wait_queue.Queue, the_thread );
    212213          break;
    213214        case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
  • cpukit/score/src/mutex.c

    r3995e6d rdafa5d88  
    113113)
    114114{
    115   /* Priority inheritance */
    116   _Thread_Raise_priority( owner, executing->current_priority );
    117 
     115  _Thread_Inherit_priority( owner, executing );
    118116  _Thread_queue_Enqueue_critical(
    119117    &mutex->Queue.Queue,
     
    137135  if (heads != NULL) {
    138136    const Thread_queue_Operations *operations;
    139     Thread_Control *first;
     137    Thread_Control                *first;
     138    bool                           unblock;
    140139
    141140    operations = MUTEX_TQ_OPERATIONS;
     
    143142
    144143    mutex->owner = first;
    145     _Thread_queue_Extract_critical(
     144    unblock = _Thread_queue_Extract_locked(
    146145      &mutex->Queue.Queue,
    147146      operations,
     147      first
     148    );
     149    _Thread_queue_Boost_priority( &mutex->Queue.Queue, first );
     150    _Thread_queue_Unblock_critical(
     151      unblock,
     152      &mutex->Queue.Queue,
    148153      first,
    149154      lock_context
  • cpukit/score/src/threadchangepriority.c

    r3995e6d rdafa5d88  
    111111}
    112112
     113#if defined(RTEMS_SMP)
     114static bool _Thread_Inherit_priority_filter(
     115  Thread_Control   *inheritor,
     116  Priority_Control *new_priority,
     117  void             *arg
     118)
     119{
     120  Thread_Control *ancestor = arg;
     121
     122  if ( _Scheduler_Get_own( inheritor ) == _Scheduler_Get_own( ancestor ) ) {
     123    *new_priority = ancestor->current_priority;
     124  }
     125
     126  return _Thread_Priority_less_than(
     127    inheritor->current_priority,
     128    *new_priority
     129  );
     130}
     131
     132void _Thread_Inherit_priority(
     133  Thread_Control *inheritor,
     134  Thread_Control *ancestor
     135)
     136{
     137  _Thread_Change_priority(
     138    inheritor,
     139    PRIORITY_PSEUDO_ISR,
     140    ancestor,
     141    _Thread_Inherit_priority_filter,
     142    false
     143  );
     144}
     145#endif
     146
    113147static bool _Thread_Restore_priority_filter(
    114148  Thread_Control   *the_thread,
  • cpukit/score/src/threadqops.c

    r3995e6d rdafa5d88  
    294294}
    295295
     296#if defined(RTEMS_SMP)
     297void _Thread_queue_Boost_priority(
     298  Thread_queue_Queue *queue,
     299  Thread_Control     *the_thread
     300)
     301{
     302  Thread_queue_Heads *heads = queue->heads;
     303
     304  if (
     305    heads != NULL
     306      && (
     307        !_Chain_Has_only_one_node( &heads->Heads.Fifo )
     308          || _RBTree_Is_empty(
     309            &_Thread_queue_Priority_queue( heads, the_thread )->Queue
     310          )
     311      )
     312  ) {
     313    _Thread_Raise_priority( the_thread, PRIORITY_PSEUDO_ISR );
     314  }
     315}
     316#endif
     317
    296318const Thread_queue_Operations _Thread_queue_Operations_default = {
    297319  .priority_change = _Thread_queue_Do_nothing_priority_change,
  • doc/user/glossary.texi

    r3995e6d rdafa5d88  
    505505importance of an element in a set of items.  RTEMS uses priority
    506506to determine which task should execute.
     507
     508@item priority boosting
     509A simple approach to extend the priority inheritance protocol for clustered
     510scheduling is @dfn{priority boosting}.  In case a mutex is owned by a task of
     511another cluster, then the priority of the owner task is raised to an
     512artificially high priority, the pseudo-interrupt priority.
    507513
    508514@item priority inheritance
  • doc/user/sem.t

    r3995e6d rdafa5d88  
    115115the resource, the task holding the resource may have its
    116116priority increased.
     117
     118On SMP configurations, in case the task holding the resource and the task that
     119blocks attempting to obtain the resource are in different scheduler instances,
     120the priority of the holder is raised to the pseudo-interrupt priority (priority
     121boosting).  The pseudo-interrupt priority is the highest priority.
    117122
    118123RTEMS supports priority inheritance for local, binary
  • doc/user/smp.t

    r3995e6d rdafa5d88  
    165165traffic.  It is easy to implement.  The problem is to provide synchronization
    166166primitives for inter-cluster synchronization (more than one cluster is involved
    167 in the synchronization process). In RTEMS there are currently three means
     167in the synchronization process). In RTEMS there are currently four means
    168168available
    169169
    170170@itemize @bullet
    171171@item events,
    172 @item message queues, and
     172@item message queues,
     173@item semaphores using the @ref{Semaphore Manager Priority Inheritance}
     174protocol (priority boosting), and
    173175@item semaphores using the @ref{Semaphore Manager Multiprocessor Resource
    174176Sharing Protocol} (MrsP).
  • testsuites/smptests/smpmutex01/init.c

    r3995e6d rdafa5d88  
    2727#define PART_COUNT 2
    2828
    29 #define TASK_COUNT 8
     29#define TASK_COUNT 9
    3030
    3131typedef enum {
     
    4444  B_5_0,
    4545  B_5_1,
    46   H,
     46  H_A,
     47  H_B,
    4748  NONE
    4849} task_id;
     
    112113}
    113114
    114 static void sync_with_helper(test_context *ctx)
     115static void sync_with_helper_by_id(test_context *ctx, task_id id)
    115116{
    116117  rtems_event_set events;
    117118
    118   send_event(ctx, H, REQ_WAKE_UP_HELPER);
     119  send_event(ctx, id, REQ_WAKE_UP_HELPER);
    119120  events = wait_for_events();
    120121  rtems_test_assert(events == REQ_WAKE_UP_MASTER);
    121122}
    122123
     124static void sync_with_helper(test_context *ctx)
     125{
     126  sync_with_helper_by_id(ctx, H_A);
     127  sync_with_helper_by_id(ctx, H_B);
     128}
     129
    123130static void request(test_context *ctx, task_id id, request_id req)
    124131{
     
    158165    rtems_test_assert(ctx->generation[i] == ctx->expected_generation[i]);
    159166  }
     167}
     168
     169static void assert_prio(
     170  test_context *ctx,
     171  task_id id,
     172  rtems_task_priority expected
     173)
     174{
     175  rtems_task_priority actual;
     176  rtems_status_code sc;
     177
     178  sc = rtems_task_set_priority(
     179    ctx->tasks[id],
     180    RTEMS_CURRENT_PRIORITY,
     181    &actual
     182  );
     183  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     184  rtems_test_assert(expected == actual);
    160185}
    161186
     
    203228  start_task(ctx, B_5_0, worker, 5, SCHED_B);
    204229  start_task(ctx, B_5_1, worker, 5, SCHED_B);
    205   start_task(ctx, H, helper, 6, SCHED_B);
     230  start_task(ctx, H_A, helper, 3, SCHED_A);
     231  start_task(ctx, H_B, helper, 6, SCHED_B);
    206232
    207233  sc = rtems_semaphore_create(
     
    217243  request(ctx, A_1, REQ_MTX_OBTAIN);
    218244  check_generations(ctx, NONE, NONE);
     245  assert_prio(ctx, M, 1);
    219246  release(ctx);
    220247  check_generations(ctx, A_1, NONE);
     248  assert_prio(ctx, M, 3);
    221249  request(ctx, A_1, REQ_MTX_RELEASE);
    222250  check_generations(ctx, A_1, NONE);
     
    227255  request(ctx, A_2_1, REQ_MTX_OBTAIN);
    228256  check_generations(ctx, NONE, NONE);
     257  assert_prio(ctx, M, 1);
    229258  release(ctx);
    230259  check_generations(ctx, A_1, NONE);
     260  assert_prio(ctx, M, 3);
     261  assert_prio(ctx, A_1, 1);
    231262  request(ctx, A_1, REQ_MTX_RELEASE);
    232263  check_generations(ctx, A_1, A_2_0);
     
    241272  request(ctx, B_5_1, REQ_MTX_OBTAIN);
    242273  check_generations(ctx, NONE, NONE);
     274  assert_prio(ctx, M, 0);
    243275  release(ctx);
    244276  sync_with_helper(ctx);
     277  assert_prio(ctx, M, 3);
    245278  check_generations(ctx, B_4, NONE);
    246279  request(ctx, B_4, REQ_MTX_RELEASE);
     
    253286  obtain(ctx);
    254287  request(ctx, A_2_0, REQ_MTX_OBTAIN);
     288  check_generations(ctx, NONE, NONE);
     289  assert_prio(ctx, M, 2);
    255290  request(ctx, B_5_0, REQ_MTX_OBTAIN);
     291  check_generations(ctx, NONE, NONE);
     292  assert_prio(ctx, M, 0);
    256293  request(ctx, B_5_1, REQ_MTX_OBTAIN);
    257294  request(ctx, B_4, REQ_MTX_OBTAIN);
     
    260297  check_generations(ctx, NONE, NONE);
    261298  release(ctx);
     299  sync_with_helper(ctx);
    262300  check_generations(ctx, A_1, NONE);
     301  assert_prio(ctx, M, 3);
     302  assert_prio(ctx, A_1, 0);
    263303  request(ctx, A_1, REQ_MTX_RELEASE);
    264304  check_generations(ctx, A_1, B_4);
     305  assert_prio(ctx, A_1, 1);
     306  assert_prio(ctx, B_4, 0);
    265307  request(ctx, B_4, REQ_MTX_RELEASE);
    266308  check_generations(ctx, B_4, A_2_0);
     309  assert_prio(ctx, B_4, 4);
     310  assert_prio(ctx, A_2_0, 0);
    267311  request(ctx, A_2_0, REQ_MTX_RELEASE);
    268312  check_generations(ctx, A_2_0, B_5_0);
     313  assert_prio(ctx, A_2_0, 2);
     314  assert_prio(ctx, B_5_0, 0);
    269315  request(ctx, B_5_0, REQ_MTX_RELEASE);
    270316  check_generations(ctx, B_5_0, A_2_1);
     317  assert_prio(ctx, B_5_0, 5);
     318  assert_prio(ctx, A_2_1, 0);
    271319  request(ctx, A_2_1, REQ_MTX_RELEASE);
    272320  check_generations(ctx, A_2_1, B_5_1);
     321  assert_prio(ctx, A_2_1, 2);
     322  assert_prio(ctx, B_5_1, 5);
    273323  request(ctx, B_5_1, REQ_MTX_RELEASE);
    274324  check_generations(ctx, B_5_1, NONE);
     325  assert_prio(ctx, B_5_1, 5);
    275326}
    276327
Note: See TracChangeset for help on using the changeset viewer.