Ignore:
Timestamp:
Dec 17, 2014, 2:11:00 PM (5 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
8ce00eaf
Parents:
481054e0
git-author:
Sebastian Huber <sebastian.huber@…> (12/17/14 14:11:00)
git-committer:
Sebastian Huber <sebastian.huber@…> (12/18/14 07:33:29)
Message:

smp: Fix timeout for MrsP semaphores

The previous timeout handling was flawed. In case a waiting thread
helped out the owner could use the scheduler node indefinitely long.
Update the resource tree in _MRSP_Timeout() to avoid this issue.

Bug reported by Luca Bonato.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • testsuites/smptests/smpmrsp01/init.c

    r481054e0 r864d3475  
    209209}
    210210
     211static void run_task(rtems_task_argument arg)
     212{
     213  volatile bool *run = (volatile bool *) arg;
     214
     215  while (true) {
     216    *run = true;
     217  }
     218}
     219
    211220static void obtain_and_release_worker(rtems_task_argument arg)
    212221{
     
    217226  ctx->worker_task = _Thread_Get_executing();
    218227
    219   assert_prio(RTEMS_SELF, 3);
     228  assert_prio(RTEMS_SELF, 4);
    220229
    221230  /* Obtain with timeout (A) */
     
    225234  rtems_test_assert(sc == RTEMS_TIMEOUT);
    226235
    227   assert_prio(RTEMS_SELF, 3);
     236  assert_prio(RTEMS_SELF, 4);
    228237
    229238  /* Obtain with priority change and timeout (B) */
     
    233242  rtems_test_assert(sc == RTEMS_TIMEOUT);
    234243
    235   assert_prio(RTEMS_SELF, 1);
     244  assert_prio(RTEMS_SELF, 2);
    236245
    237246  /* Restore priority (C) */
     
    244253  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    245254
    246   assert_prio(RTEMS_SELF, 2);
     255  assert_prio(RTEMS_SELF, 3);
    247256
    248257  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
    249258  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    250259
    251   assert_prio(RTEMS_SELF, 3);
    252 
    253   /* Worker done (E) */
     260  assert_prio(RTEMS_SELF, 4);
     261
     262  /* Obtain and help with timeout (E) */
     263  barrier(ctx, &barrier_state);
     264
     265  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, 4);
     266  rtems_test_assert(sc == RTEMS_TIMEOUT);
     267
     268  assert_prio(RTEMS_SELF, 4);
     269
     270  sc = rtems_task_suspend(ctx->high_task_id[0]);
     271  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     272
     273  /* Worker done (H) */
    254274  barrier(ctx, &barrier_state);
    255275
     
    267287  puts("test MrsP obtain and release");
    268288
    269   change_prio(RTEMS_SELF, 2);
     289  change_prio(RTEMS_SELF, 3);
     290
     291  reset_switch_events(ctx);
     292
     293  ctx->high_run[0] = false;
     294
     295  sc = rtems_task_create(
     296    rtems_build_name('H', 'I', 'G', '0'),
     297    1,
     298    RTEMS_MINIMUM_STACK_SIZE,
     299    RTEMS_DEFAULT_MODES,
     300    RTEMS_DEFAULT_ATTRIBUTES,
     301    &ctx->high_task_id[0]
     302  );
     303  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    270304
    271305  /* Check executing task parameters */
     
    283317    RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
    284318      | RTEMS_BINARY_SEMAPHORE,
    285     1,
     319    2,
    286320    &ctx->mrsp_ids[0]
    287321  );
    288322  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    289323
     324  assert_prio(RTEMS_SELF, 3);
     325
     326  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
     327  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     328
    290329  assert_prio(RTEMS_SELF, 2);
    291 
    292   sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
    293   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    294 
    295   assert_prio(RTEMS_SELF, 1);
    296330
    297331  /*
     
    308342  );
    309343  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    310   rtems_test_assert(prio == 1);
     344  rtems_test_assert(prio == 2);
    311345
    312346  /* Check the old value and set a new ceiling priority for scheduler B */
    313347
    314   prio = 2;
     348  prio = 3;
    315349  sc = rtems_semaphore_set_priority(
    316350    ctx->mrsp_ids[0],
     
    320354  );
    321355  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    322   rtems_test_assert(prio == 1);
     356  rtems_test_assert(prio == 2);
    323357
    324358  /* Check the ceiling priority values */
     
    332366  );
    333367  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    334   rtems_test_assert(prio == 1);
     368  rtems_test_assert(prio == 2);
    335369
    336370  prio = RTEMS_CURRENT_PRIORITY;
     
    342376  );
    343377  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    344   rtems_test_assert(prio == 2);
     378  rtems_test_assert(prio == 3);
    345379
    346380  /* Check that a thread waiting to get ownership remains executing */
     
    348382  sc = rtems_task_create(
    349383    rtems_build_name('W', 'O', 'R', 'K'),
    350     3,
     384    4,
    351385    RTEMS_MINIMUM_STACK_SIZE,
    352386    RTEMS_DEFAULT_MODES,
     
    365399  barrier_and_delay(ctx, &barrier_state);
    366400
    367   assert_prio(ctx->worker_ids[0], 2);
     401  assert_prio(ctx->worker_ids[0], 3);
    368402  assert_executing_worker(ctx);
    369403
     
    371405  barrier_and_delay(ctx, &barrier_state);
    372406
    373   assert_prio(ctx->worker_ids[0], 2);
    374   change_prio(ctx->worker_ids[0], 1);
     407  assert_prio(ctx->worker_ids[0], 3);
     408  change_prio(ctx->worker_ids[0], 2);
    375409  assert_executing_worker(ctx);
    376410
     
    378412  barrier(ctx, &barrier_state);
    379413
    380   assert_prio(ctx->worker_ids[0], 1);
    381   change_prio(ctx->worker_ids[0], 3);
     414  assert_prio(ctx->worker_ids[0], 2);
     415  change_prio(ctx->worker_ids[0], 4);
    382416
    383417  /* Obtain without timeout (D) */
    384418  barrier_and_delay(ctx, &barrier_state);
    385419
    386   assert_prio(ctx->worker_ids[0], 2);
     420  assert_prio(ctx->worker_ids[0], 3);
    387421  assert_executing_worker(ctx);
    388422
     
    390424  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    391425
    392   /* Worker done (E) */
     426  /* Check that a timeout works in case the waiting thread actually helps */
     427
     428  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
     429  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     430
     431  /* Obtain and help with timeout (E) */
     432  barrier_and_delay(ctx, &barrier_state);
     433
     434  sc = rtems_task_start(
     435    ctx->high_task_id[0],
     436    run_task,
     437    (rtems_task_argument) &ctx->high_run[0]
     438  );
     439  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     440
     441  rtems_test_assert(rtems_get_current_processor() == 1);
     442
     443  while (rtems_get_current_processor() != 0) {
     444    /* Wait */
     445  }
     446
     447  rtems_test_assert(ctx->high_run[0]);
     448
     449  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
     450  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     451
     452  print_switch_events(ctx);
     453
     454  /* Worker done (H) */
    393455  barrier(ctx, &barrier_state);
    394456
    395457  sc = rtems_task_delete(ctx->worker_ids[0]);
     458  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     459
     460  sc = rtems_task_delete(ctx->high_task_id[0]);
    396461  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    397462
     
    726791  sc = rtems_semaphore_delete(sem_c_id);
    727792  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    728 }
    729 
    730 static void run_task(rtems_task_argument arg)
    731 {
    732   volatile bool *run = (volatile bool *) arg;
    733 
    734   while (true) {
    735     *run = true;
    736   }
    737793}
    738794
Note: See TracChangeset for help on using the changeset viewer.