Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:43

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (C) 2014, 2015 embedded brains GmbH & Co. KG
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031 
0032 #include <sys/param.h>
0033 
0034 #include <stdio.h>
0035 #include <inttypes.h>
0036 
0037 #include <rtems.h>
0038 #include <rtems/libcsupport.h>
0039 #include <rtems/score/schedulersmpimpl.h>
0040 #include <rtems/score/smpbarrier.h>
0041 #include <rtems/score/smplock.h>
0042 
0043 #include "tmacros.h"
0044 
0045 const char rtems_test_name[] = "SMPMRSP 1";
0046 
0047 #define CPU_COUNT 32
0048 
0049 #define MRSP_COUNT 32
0050 
0051 #define SWITCH_EVENT_COUNT 32
0052 
0053 typedef struct {
0054   uint32_t sleep;
0055   uint32_t timeout;
0056   uint32_t obtain[MRSP_COUNT];
0057   uint32_t cpu[CPU_COUNT];
0058 } counter;
0059 
0060 typedef struct {
0061   uint32_t cpu_index;
0062   const Thread_Control *executing;
0063   const Thread_Control *heir;
0064   const Thread_Control *heir_node;
0065   Priority_Control heir_priority;
0066 } switch_event;
0067 
0068 typedef struct {
0069   rtems_id main_task_id;
0070   rtems_id migration_task_id;
0071   rtems_id low_task_id[2];
0072   rtems_id high_task_id[2];
0073   rtems_id timer_id;
0074   rtems_id counting_sem_id;
0075   rtems_id mrsp_ids[MRSP_COUNT];
0076   rtems_id scheduler_ids[CPU_COUNT];
0077   rtems_id worker_ids[2 * CPU_COUNT];
0078   volatile bool stop_worker[2 * CPU_COUNT];
0079   counter counters[2 * CPU_COUNT];
0080   uint32_t migration_counters[CPU_COUNT];
0081   Thread_Control *worker_task;
0082   SMP_barrier_Control barrier;
0083   SMP_lock_Control switch_lock;
0084   size_t switch_index;
0085   switch_event switch_events[32];
0086   volatile bool high_run[2];
0087   volatile bool low_run[2];
0088 } test_context;
0089 
0090 static test_context test_instance = {
0091   .switch_lock = SMP_LOCK_INITIALIZER("test instance switch lock")
0092 };
0093 
0094 static void busy_wait(void)
0095 {
0096   rtems_interval later = rtems_clock_tick_later(2);
0097 
0098   while (rtems_clock_tick_before(later)) {
0099     /* Wait */
0100   }
0101 }
0102 
0103 static void barrier_init(test_context *ctx)
0104 {
0105   _SMP_barrier_Control_initialize(&ctx->barrier);
0106 }
0107 
0108 static void barrier(test_context *ctx, SMP_barrier_State *bs)
0109 {
0110   _SMP_barrier_Wait(&ctx->barrier, bs, 2);
0111 }
0112 
0113 static void barrier_and_delay(test_context *ctx, SMP_barrier_State *bs)
0114 {
0115   barrier(ctx, bs);
0116   busy_wait();
0117 }
0118 
0119 static rtems_task_priority get_prio(rtems_id task_id)
0120 {
0121   rtems_status_code sc;
0122   rtems_task_priority prio;
0123 
0124   sc = rtems_task_set_priority(task_id, RTEMS_CURRENT_PRIORITY, &prio);
0125   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0126 
0127   return prio;
0128 }
0129 
0130 static void wait_for_prio(rtems_id task_id, rtems_task_priority prio)
0131 {
0132   while (get_prio(task_id) != prio) {
0133     /* Wait */
0134   }
0135 }
0136 
0137 static void assert_prio(rtems_id task_id, rtems_task_priority expected_prio)
0138 {
0139   rtems_test_assert(get_prio(task_id) == expected_prio);
0140 }
0141 
0142 static void change_prio(rtems_id task_id, rtems_task_priority prio)
0143 {
0144   rtems_status_code sc;
0145 
0146   sc = rtems_task_set_priority(task_id, prio, &prio);
0147   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0148 }
0149 
0150 static void assert_executing_worker(test_context *ctx)
0151 {
0152   rtems_test_assert(
0153     _CPU_Context_Get_is_executing(&ctx->worker_task->Registers)
0154   );
0155 }
0156 
0157 static void switch_extension(Thread_Control *executing, Thread_Control *heir)
0158 {
0159   test_context *ctx = &test_instance;
0160   SMP_lock_Context lock_context;
0161   size_t i;
0162 
0163   _SMP_lock_ISR_disable_and_acquire(&ctx->switch_lock, &lock_context);
0164 
0165   i = ctx->switch_index;
0166   if (i < SWITCH_EVENT_COUNT) {
0167     switch_event *e = &ctx->switch_events[i];
0168     Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_node(heir);
0169 
0170     e->cpu_index = rtems_scheduler_get_processor();
0171     e->executing = executing;
0172     e->heir = heir;
0173     e->heir_node = _Scheduler_Node_get_owner(&node->Base);
0174     e->heir_priority = node->priority;
0175 
0176     ctx->switch_index = i + 1;
0177   }
0178 
0179   _SMP_lock_Release_and_ISR_enable(&ctx->switch_lock, &lock_context);
0180 }
0181 
0182 static void reset_switch_events(test_context *ctx)
0183 {
0184   SMP_lock_Context lock_context;
0185 
0186   _SMP_lock_ISR_disable_and_acquire(&ctx->switch_lock, &lock_context);
0187   ctx->switch_index = 0;
0188   _SMP_lock_Release_and_ISR_enable(&ctx->switch_lock, &lock_context);
0189 }
0190 
0191 static size_t get_switch_events(test_context *ctx)
0192 {
0193   SMP_lock_Context lock_context;
0194   size_t events;
0195 
0196   _SMP_lock_ISR_disable_and_acquire(&ctx->switch_lock, &lock_context);
0197   events = ctx->switch_index;
0198   _SMP_lock_Release_and_ISR_enable(&ctx->switch_lock, &lock_context);
0199 
0200   return events;
0201 }
0202 
0203 static void print_switch_events(test_context *ctx)
0204 {
0205   size_t n = get_switch_events(ctx);
0206   size_t i;
0207 
0208   for (i = 0; i < n; ++i) {
0209     switch_event *e = &ctx->switch_events[i];
0210     char ex[5];
0211     char hr[5];
0212     char hn[5];
0213 
0214     rtems_object_get_name(e->executing->Object.id, sizeof(ex), &ex[0]);
0215     rtems_object_get_name(e->heir->Object.id, sizeof(hr), &hr[0]);
0216     rtems_object_get_name(e->heir_node->Object.id, sizeof(hn), &hn[0]);
0217 
0218     printf(
0219       "[%" PRIu32 "] %4s -> %4s (prio %3" PRIu64 ", node %4s)\n",
0220       e->cpu_index,
0221       &ex[0],
0222       &hr[0],
0223       e->heir_priority,
0224       &hn[0]
0225     );
0226   }
0227 }
0228 
0229 static void create_timer(test_context *ctx)
0230 {
0231   rtems_status_code sc;
0232 
0233   sc = rtems_timer_create(
0234     rtems_build_name('T', 'I', 'M', 'R'),
0235     &ctx->timer_id
0236   );
0237   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0238 }
0239 
0240 static void delete_timer(test_context *ctx)
0241 {
0242   rtems_status_code sc;
0243 
0244   sc = rtems_timer_delete(ctx->timer_id);
0245   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0246 }
0247 
0248 static void fire_timer(
0249   test_context *ctx,
0250   rtems_interval interval,
0251   rtems_timer_service_routine_entry routine
0252 )
0253 {
0254   rtems_status_code sc;
0255 
0256   sc = rtems_timer_fire_after(ctx->timer_id, interval, routine, ctx);
0257   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0258 }
0259 
0260 static void create_mrsp_sema(
0261   test_context *ctx,
0262   rtems_id *id,
0263   rtems_task_priority prio
0264 )
0265 {
0266   uint32_t cpu_count = rtems_scheduler_get_processor_maximum();
0267   uint32_t index;
0268   rtems_status_code sc;
0269 
0270   sc = rtems_semaphore_create(
0271     rtems_build_name('M', 'R', 'S', 'P'),
0272     1,
0273     RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
0274       RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
0275     prio,
0276     id
0277   );
0278   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0279 
0280   for (index = 1; index < cpu_count; index = ((index + 2) & ~UINT32_C(1))) {
0281     rtems_task_priority old_prio;
0282 
0283     old_prio = 1;
0284     sc = rtems_semaphore_set_priority(
0285       *id,
0286       ctx->scheduler_ids[index],
0287       prio,
0288       &old_prio
0289     );
0290     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0291     rtems_test_assert(old_prio == 0);
0292   }
0293 }
0294 
0295 static void run_task(rtems_task_argument arg)
0296 {
0297   volatile bool *run = (volatile bool *) arg;
0298 
0299   *run = true;
0300 
0301   while (true) {
0302     /* Do nothing */
0303   }
0304 }
0305 
0306 static void obtain_and_release_worker(rtems_task_argument arg)
0307 {
0308   test_context *ctx = &test_instance;
0309   rtems_status_code sc;
0310   SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
0311 
0312   ctx->worker_task = _Thread_Get_executing();
0313 
0314   assert_prio(RTEMS_SELF, 4);
0315 
0316   /* Obtain with timeout (A) */
0317   barrier(ctx, &barrier_state);
0318 
0319   sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, 4);
0320   rtems_test_assert(sc == RTEMS_TIMEOUT);
0321 
0322   assert_prio(RTEMS_SELF, 4);
0323 
0324   /* Obtain with priority change and timeout (B) */
0325   barrier(ctx, &barrier_state);
0326 
0327   sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, 4);
0328   rtems_test_assert(sc == RTEMS_TIMEOUT);
0329 
0330   assert_prio(RTEMS_SELF, 2);
0331 
0332   /* Restore priority (C) */
0333   barrier(ctx, &barrier_state);
0334 
0335   /* Obtain without timeout (D) */
0336   barrier(ctx, &barrier_state);
0337 
0338   sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0339   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0340 
0341   assert_prio(RTEMS_SELF, 3);
0342 
0343   sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
0344   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0345 
0346   assert_prio(RTEMS_SELF, 4);
0347 
0348   /* Obtain and help with timeout (E) */
0349   barrier(ctx, &barrier_state);
0350 
0351   sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, 4);
0352   rtems_test_assert(sc == RTEMS_TIMEOUT);
0353 
0354   assert_prio(RTEMS_SELF, 4);
0355 
0356   sc = rtems_task_suspend(ctx->high_task_id[0]);
0357   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0358 
0359   /* Worker done (H) */
0360   barrier(ctx, &barrier_state);
0361 
0362   while (true) {
0363     /* Wait for termination */
0364   }
0365 }
0366 
0367 static void test_mrsp_obtain_and_release(test_context *ctx)
0368 {
0369   rtems_status_code sc;
0370   rtems_task_priority prio;
0371   rtems_id scheduler_id;
0372   SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
0373 
0374   puts("test MrsP obtain and release");
0375 
0376   change_prio(RTEMS_SELF, 3);
0377 
0378   barrier_init(ctx);
0379   reset_switch_events(ctx);
0380 
0381   ctx->high_run[0] = false;
0382 
0383   sc = rtems_task_create(
0384     rtems_build_name('H', 'I', 'G', '0'),
0385     1,
0386     RTEMS_MINIMUM_STACK_SIZE,
0387     RTEMS_DEFAULT_MODES,
0388     RTEMS_DEFAULT_ATTRIBUTES,
0389     &ctx->high_task_id[0]
0390   );
0391   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0392 
0393   /* Check executing task parameters */
0394 
0395   sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id);
0396   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0397 
0398   rtems_test_assert(ctx->scheduler_ids[0] == scheduler_id);
0399 
0400   /* Create a MrsP semaphore object and lock it */
0401 
0402   create_mrsp_sema(ctx, &ctx->mrsp_ids[0], 2);
0403 
0404   assert_prio(RTEMS_SELF, 3);
0405 
0406   sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0407   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0408 
0409   assert_prio(RTEMS_SELF, 2);
0410 
0411   /*
0412    * The ceiling priority values per scheduler are equal to the value specified
0413    * for object creation.
0414    */
0415 
0416   prio = RTEMS_CURRENT_PRIORITY;
0417   sc = rtems_semaphore_set_priority(
0418     ctx->mrsp_ids[0],
0419     ctx->scheduler_ids[0],
0420     prio,
0421     &prio
0422   );
0423   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0424   rtems_test_assert(prio == 2);
0425 
0426   /* Check the old value and set a new ceiling priority for scheduler B */
0427 
0428   prio = 3;
0429   sc = rtems_semaphore_set_priority(
0430     ctx->mrsp_ids[0],
0431     ctx->scheduler_ids[1],
0432     prio,
0433     &prio
0434   );
0435   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0436   rtems_test_assert(prio == 2);
0437 
0438   /* Check the ceiling priority values */
0439 
0440   prio = RTEMS_CURRENT_PRIORITY;
0441   sc = rtems_semaphore_set_priority(
0442     ctx->mrsp_ids[0],
0443     ctx->scheduler_ids[0],
0444     prio,
0445     &prio
0446   );
0447   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0448   rtems_test_assert(prio == 2);
0449 
0450   prio = RTEMS_CURRENT_PRIORITY;
0451   sc = rtems_semaphore_set_priority(
0452     ctx->mrsp_ids[0],
0453     ctx->scheduler_ids[1],
0454     prio,
0455     &prio
0456   );
0457   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0458   rtems_test_assert(prio == 3);
0459 
0460   /* Check that a thread waiting to get ownership remains executing */
0461 
0462   sc = rtems_task_create(
0463     rtems_build_name('W', 'O', 'R', 'K'),
0464     255,
0465     RTEMS_MINIMUM_STACK_SIZE,
0466     RTEMS_DEFAULT_MODES,
0467     RTEMS_DEFAULT_ATTRIBUTES,
0468     &ctx->worker_ids[0]
0469   );
0470   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0471 
0472   sc = rtems_task_set_scheduler(ctx->worker_ids[0], ctx->scheduler_ids[1], 4);
0473   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0474 
0475   sc = rtems_task_start(ctx->worker_ids[0], obtain_and_release_worker, 0);
0476   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0477 
0478   /* Obtain with timeout (A) */
0479   barrier_and_delay(ctx, &barrier_state);
0480 
0481   assert_prio(ctx->worker_ids[0], 3);
0482   assert_executing_worker(ctx);
0483 
0484   /* Obtain with priority change and timeout (B) */
0485   barrier_and_delay(ctx, &barrier_state);
0486 
0487   assert_prio(ctx->worker_ids[0], 3);
0488   change_prio(ctx->worker_ids[0], 2);
0489   assert_executing_worker(ctx);
0490 
0491   /* Restore priority (C) */
0492   barrier(ctx, &barrier_state);
0493 
0494   assert_prio(ctx->worker_ids[0], 2);
0495   change_prio(ctx->worker_ids[0], 4);
0496 
0497   /* Obtain without timeout (D) */
0498   barrier_and_delay(ctx, &barrier_state);
0499 
0500   assert_prio(ctx->worker_ids[0], 3);
0501   assert_executing_worker(ctx);
0502 
0503   sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
0504   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0505 
0506   /* Check that a timeout works in case the waiting thread actually helps */
0507 
0508   sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0509   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0510 
0511   /* Obtain and help with timeout (E) */
0512   barrier_and_delay(ctx, &barrier_state);
0513 
0514   sc = rtems_task_start(
0515     ctx->high_task_id[0],
0516     run_task,
0517     (rtems_task_argument) &ctx->high_run[0]
0518   );
0519   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0520 
0521   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0522 
0523   while (rtems_scheduler_get_processor() != 0) {
0524     /* Wait */
0525   }
0526 
0527   rtems_test_assert(ctx->high_run[0]);
0528 
0529   sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
0530   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0531 
0532   print_switch_events(ctx);
0533 
0534   /* Worker done (H) */
0535   barrier(ctx, &barrier_state);
0536 
0537   sc = rtems_task_delete(ctx->worker_ids[0]);
0538   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0539 
0540   sc = rtems_task_delete(ctx->high_task_id[0]);
0541   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0542 
0543   sc = rtems_semaphore_delete(ctx->mrsp_ids[0]);
0544   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0545 }
0546 
0547 static void obtain_after_migration_worker(rtems_task_argument arg)
0548 {
0549   test_context *ctx = &test_instance;
0550   rtems_status_code sc;
0551   SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
0552 
0553   assert_prio(RTEMS_SELF, 3);
0554 
0555   sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0556   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0557 
0558   sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
0559   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0560 
0561   /* Worker done (K) */
0562   barrier(ctx, &barrier_state);
0563 
0564   while (true) {
0565     /* Wait for termination */
0566   }
0567 }
0568 
0569 static void obtain_after_migration_high(rtems_task_argument arg)
0570 {
0571   test_context *ctx = &test_instance;
0572   rtems_status_code sc;
0573   SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
0574 
0575   assert_prio(RTEMS_SELF, 2);
0576 
0577   sc = rtems_semaphore_obtain(ctx->mrsp_ids[1], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0578   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0579 
0580   /* Obtain done (I) */
0581   barrier(ctx, &barrier_state);
0582 
0583   /* Ready to release (J) */
0584   barrier(ctx, &barrier_state);
0585 
0586   sc = rtems_semaphore_release(ctx->mrsp_ids[1]);
0587   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0588 
0589   rtems_task_suspend(RTEMS_SELF);
0590   rtems_test_assert(0);
0591 }
0592 
0593 static void test_mrsp_obtain_after_migration(test_context *ctx)
0594 {
0595   rtems_status_code sc;
0596   rtems_task_priority prio;
0597   rtems_id scheduler_id;
0598   SMP_barrier_State barrier_state;
0599 
0600   puts("test MrsP obtain after migration");
0601 
0602   change_prio(RTEMS_SELF, 3);
0603 
0604   barrier_init(ctx);
0605   reset_switch_events(ctx);
0606 
0607   /* Create tasks */
0608 
0609   sc = rtems_task_create(
0610     rtems_build_name('H', 'I', 'G', '0'),
0611     2,
0612     RTEMS_MINIMUM_STACK_SIZE,
0613     RTEMS_DEFAULT_MODES,
0614     RTEMS_DEFAULT_ATTRIBUTES,
0615     &ctx->high_task_id[0]
0616   );
0617   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0618 
0619   sc = rtems_task_create(
0620     rtems_build_name('W', 'O', 'R', 'K'),
0621     255,
0622     RTEMS_MINIMUM_STACK_SIZE,
0623     RTEMS_DEFAULT_MODES,
0624     RTEMS_DEFAULT_ATTRIBUTES,
0625     &ctx->worker_ids[0]
0626   );
0627   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0628 
0629   sc = rtems_task_set_scheduler(ctx->worker_ids[0], ctx->scheduler_ids[1], 3);
0630   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0631 
0632   /* Create a MrsP semaphore objects */
0633 
0634   create_mrsp_sema(ctx, &ctx->mrsp_ids[0], 3);
0635   create_mrsp_sema(ctx, &ctx->mrsp_ids[1], 2);
0636   create_mrsp_sema(ctx, &ctx->mrsp_ids[2], 1);
0637 
0638   prio = 4;
0639   sc = rtems_semaphore_set_priority(
0640     ctx->mrsp_ids[2],
0641     ctx->scheduler_ids[1],
0642     prio,
0643     &prio
0644   );
0645   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0646   rtems_test_assert(prio == 1);
0647 
0648   /* Check executing task parameters */
0649 
0650   sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id);
0651   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0652 
0653   rtems_test_assert(ctx->scheduler_ids[0] == scheduler_id);
0654 
0655   assert_prio(RTEMS_SELF, 3);
0656 
0657   sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0658   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0659 
0660   assert_prio(RTEMS_SELF, 3);
0661 
0662   /* Start other tasks */
0663 
0664   sc = rtems_task_start(ctx->worker_ids[0], obtain_after_migration_worker, 0);
0665   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0666 
0667   sc = rtems_task_start(ctx->high_task_id[0], obtain_after_migration_high, 0);
0668   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0669 
0670   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0671 
0672   /* Obtain done (I) */
0673   _SMP_barrier_State_initialize(&barrier_state);
0674   barrier(ctx, &barrier_state);
0675 
0676   sc = rtems_task_suspend(ctx->high_task_id[0]);
0677   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0678 
0679   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0680 
0681   /*
0682    * Obtain second MrsP semaphore and ensure that we change the priority of our
0683    * own scheduler node and not the one we are currently using.
0684    */
0685 
0686   sc = rtems_semaphore_obtain(ctx->mrsp_ids[2], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0687   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0688 
0689   assert_prio(RTEMS_SELF, 1);
0690 
0691   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0692 
0693   sc = rtems_semaphore_release(ctx->mrsp_ids[2]);
0694   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0695 
0696   sc = rtems_task_resume(ctx->high_task_id[0]);
0697   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0698 
0699   /* Ready to release (J) */
0700   barrier(ctx, &barrier_state);
0701 
0702   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0703 
0704   /* Prepare barrier for worker */
0705   barrier_init(ctx);
0706   _SMP_barrier_State_initialize(&barrier_state);
0707 
0708   sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
0709   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0710 
0711   rtems_test_assert(rtems_scheduler_get_processor() == 0);
0712 
0713   print_switch_events(ctx);
0714 
0715   /* Worker done (K) */
0716   barrier(ctx, &barrier_state);
0717 
0718   sc = rtems_task_delete(ctx->worker_ids[0]);
0719   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0720 
0721   sc = rtems_task_delete(ctx->high_task_id[0]);
0722   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0723 
0724   sc = rtems_semaphore_delete(ctx->mrsp_ids[0]);
0725   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0726 
0727   sc = rtems_semaphore_delete(ctx->mrsp_ids[1]);
0728   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0729 
0730   sc = rtems_semaphore_delete(ctx->mrsp_ids[2]);
0731   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0732 }
0733 
0734 static void test_mrsp_flush_error(test_context *ctx)
0735 {
0736   rtems_status_code sc;
0737   rtems_id id;
0738 
0739   puts("test MrsP flush error");
0740 
0741   create_mrsp_sema(ctx, &id, 1);
0742 
0743   sc = rtems_semaphore_flush(id);
0744   rtems_test_assert(sc == RTEMS_NOT_DEFINED);
0745 
0746   sc = rtems_semaphore_delete(id);
0747   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0748 }
0749 
0750 static void test_mrsp_initially_locked(void)
0751 {
0752   rtems_status_code sc;
0753   rtems_id id;
0754 
0755   puts("test MrsP initially locked");
0756 
0757   sc = rtems_semaphore_create(
0758     rtems_build_name('M', 'R', 'S', 'P'),
0759     0,
0760     RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
0761       RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
0762     1,
0763     &id
0764   );
0765   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0766 
0767   sc = rtems_semaphore_release(id);
0768   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0769 
0770   sc = rtems_semaphore_delete(id);
0771   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0772 }
0773 
0774 static void test_mrsp_nested_obtain_error(test_context *ctx)
0775 {
0776   rtems_status_code sc;
0777   rtems_id id;
0778 
0779   puts("test MrsP nested obtain error");
0780 
0781   create_mrsp_sema(ctx, &id, 1);
0782 
0783   sc = rtems_semaphore_obtain(id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0784   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0785 
0786   sc = rtems_semaphore_obtain(id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0787   rtems_test_assert(sc == RTEMS_INCORRECT_STATE);
0788 
0789   sc = rtems_semaphore_release(id);
0790   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0791 
0792   sc = rtems_semaphore_delete(id);
0793   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0794 }
0795 
0796 static void deadlock_timer(rtems_id timer_id, void *arg)
0797 {
0798   test_context *ctx = arg;
0799 
0800   change_prio(ctx->main_task_id, 1);
0801 }
0802 
0803 static void deadlock_worker(rtems_task_argument arg)
0804 {
0805   test_context *ctx = &test_instance;
0806   rtems_status_code sc;
0807 
0808   sc = rtems_semaphore_obtain(ctx->mrsp_ids[1], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0809   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0810 
0811   fire_timer(ctx, 2, deadlock_timer);
0812 
0813   sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0814   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0815 
0816   sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
0817   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0818 
0819   sc = rtems_semaphore_release(ctx->mrsp_ids[1]);
0820   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0821 
0822   sc = rtems_event_transient_send(ctx->main_task_id);
0823   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0824 
0825   rtems_task_suspend(RTEMS_SELF);
0826   rtems_test_assert(0);
0827 }
0828 
0829 static void test_mrsp_deadlock_error(test_context *ctx)
0830 {
0831   rtems_status_code sc;
0832   rtems_task_priority prio = 2;
0833 
0834   puts("test MrsP deadlock error");
0835 
0836   change_prio(RTEMS_SELF, prio);
0837 
0838   create_timer(ctx);
0839   create_mrsp_sema(ctx, &ctx->mrsp_ids[0], prio);
0840   create_mrsp_sema(ctx, &ctx->mrsp_ids[1], prio);
0841 
0842   sc = rtems_task_create(
0843     rtems_build_name('W', 'O', 'R', 'K'),
0844     prio,
0845     RTEMS_MINIMUM_STACK_SIZE,
0846     RTEMS_DEFAULT_MODES,
0847     RTEMS_DEFAULT_ATTRIBUTES,
0848     &ctx->worker_ids[0]
0849   );
0850   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0851 
0852   sc = rtems_task_start(ctx->worker_ids[0], deadlock_worker, 0);
0853   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0854 
0855   sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0856   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0857 
0858   sc = rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
0859   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0860 
0861   prio = 1;
0862   sc = rtems_semaphore_set_priority(
0863     ctx->mrsp_ids[1],
0864     ctx->scheduler_ids[0],
0865     prio,
0866     &prio
0867   );
0868   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0869   rtems_test_assert(prio == 2);
0870 
0871   sc = rtems_semaphore_obtain(ctx->mrsp_ids[1], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0872   rtems_test_assert(sc == RTEMS_INCORRECT_STATE);
0873 
0874   sc = rtems_semaphore_set_priority(
0875     ctx->mrsp_ids[1],
0876     ctx->scheduler_ids[0],
0877     prio,
0878     &prio
0879   );
0880   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0881 
0882   sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
0883   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0884 
0885   sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0886   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0887 
0888   sc = rtems_task_delete(ctx->worker_ids[0]);
0889   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0890 
0891   sc = rtems_semaphore_delete(ctx->mrsp_ids[0]);
0892   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0893 
0894   sc = rtems_semaphore_delete(ctx->mrsp_ids[1]);
0895   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0896 
0897   delete_timer(ctx);
0898 }
0899 
0900 static void test_mrsp_multiple_obtain(test_context *ctx)
0901 {
0902   rtems_status_code sc;
0903   rtems_id sem_a_id;
0904   rtems_id sem_b_id;
0905   rtems_id sem_c_id;
0906 
0907   puts("test MrsP multiple obtain");
0908 
0909   change_prio(RTEMS_SELF, 4);
0910 
0911   create_mrsp_sema(ctx, &sem_a_id, 3);
0912   create_mrsp_sema(ctx, &sem_b_id, 2);
0913   create_mrsp_sema(ctx, &sem_c_id, 1);
0914 
0915   assert_prio(RTEMS_SELF, 4);
0916 
0917   sc = rtems_semaphore_obtain(sem_a_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0918   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0919 
0920   assert_prio(RTEMS_SELF, 3);
0921 
0922   sc = rtems_semaphore_obtain(sem_b_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0923   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0924 
0925   assert_prio(RTEMS_SELF, 2);
0926 
0927   sc = rtems_semaphore_obtain(sem_c_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0928   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0929 
0930   assert_prio(RTEMS_SELF, 1);
0931 
0932   sc = rtems_semaphore_release(sem_c_id);
0933   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0934 
0935   assert_prio(RTEMS_SELF, 2);
0936 
0937   sc = rtems_semaphore_release(sem_b_id);
0938   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0939 
0940   assert_prio(RTEMS_SELF, 3);
0941 
0942   sc = rtems_semaphore_release(sem_a_id);
0943   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0944 
0945   assert_prio(RTEMS_SELF, 4);
0946 
0947   sc = rtems_semaphore_obtain(sem_a_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0948   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0949 
0950   assert_prio(RTEMS_SELF, 3);
0951 
0952   sc = rtems_semaphore_obtain(sem_b_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0953   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0954 
0955   assert_prio(RTEMS_SELF, 2);
0956 
0957   sc = rtems_semaphore_obtain(sem_c_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0958   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0959 
0960   assert_prio(RTEMS_SELF, 1);
0961   change_prio(RTEMS_SELF, 3);
0962   assert_prio(RTEMS_SELF, 1);
0963 
0964   sc = rtems_semaphore_release(sem_c_id);
0965   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0966 
0967   assert_prio(RTEMS_SELF, 2);
0968 
0969   sc = rtems_semaphore_release(sem_b_id);
0970   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0971 
0972   assert_prio(RTEMS_SELF, 3);
0973 
0974   sc = rtems_semaphore_release(sem_a_id);
0975   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0976 
0977   assert_prio(RTEMS_SELF, 3);
0978 
0979   sc = rtems_semaphore_delete(sem_a_id);
0980   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0981 
0982   sc = rtems_semaphore_delete(sem_b_id);
0983   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0984 
0985   sc = rtems_semaphore_delete(sem_c_id);
0986   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0987 }
0988 
0989 static void ready_unlock_worker(rtems_task_argument arg)
0990 {
0991   test_context *ctx = &test_instance;
0992   rtems_status_code sc;
0993   SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
0994 
0995   assert_prio(RTEMS_SELF, 4);
0996 
0997   /* Obtain (F) */
0998   barrier(ctx, &barrier_state);
0999 
1000   sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1001   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1002 
1003   sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
1004   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1005 
1006   assert_prio(RTEMS_SELF, 4);
1007 
1008   /* Done (G) */
1009   barrier(ctx, &barrier_state);
1010 
1011   while (true) {
1012     /* Do nothing */
1013   }
1014 }
1015 
1016 static void unblock_ready_timer(rtems_id timer_id, void *arg)
1017 {
1018   test_context *ctx = arg;
1019   rtems_status_code sc;
1020 
1021   sc = rtems_task_start(
1022     ctx->high_task_id[0],
1023     run_task,
1024     (rtems_task_argument) &ctx->high_run[0]
1025   );
1026   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1027 
1028   sc = rtems_task_suspend(ctx->high_task_id[0]);
1029   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1030 
1031   sc = rtems_task_resume(ctx->high_task_id[0]);
1032   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1033 
1034   /*
1035    * At this point the scheduler node of the main thread is in the
1036    * SCHEDULER_SMP_NODE_READY state and a _Scheduler_SMP_Unblock() operation is
1037    * performed.
1038    */
1039   sc = rtems_event_transient_send(ctx->main_task_id);
1040   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1041 
1042   sc = rtems_task_suspend(ctx->high_task_id[0]);
1043   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1044 }
1045 
1046 static void unblock_ready_owner(test_context *ctx)
1047 {
1048   rtems_status_code sc;
1049 
1050   sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1051   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1052 
1053   assert_prio(RTEMS_SELF, 3);
1054 
1055   fire_timer(ctx, 2, unblock_ready_timer);
1056 
1057   sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1058   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1059 
1060   rtems_test_assert(!ctx->high_run[0]);
1061 }
1062 
1063 static void unblock_owner_before_rival_timer(rtems_id timer_id, void *arg)
1064 {
1065   test_context *ctx = arg;
1066   rtems_status_code sc;
1067 
1068   sc = rtems_task_suspend(ctx->high_task_id[0]);
1069   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1070 
1071   sc = rtems_task_suspend(ctx->high_task_id[1]);
1072   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1073 }
1074 
1075 static void unblock_owner_after_rival_timer(rtems_id timer_id, void *arg)
1076 {
1077   test_context *ctx = arg;
1078   rtems_status_code sc;
1079 
1080   sc = rtems_task_suspend(ctx->high_task_id[1]);
1081   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1082 
1083   sc = rtems_task_suspend(ctx->high_task_id[0]);
1084   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1085 }
1086 
1087 static void various_block_unblock(test_context *ctx)
1088 {
1089   rtems_status_code sc;
1090   SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
1091 
1092   /* Worker obtain (F) */
1093   barrier_and_delay(ctx, &barrier_state);
1094 
1095   sc = rtems_task_suspend(ctx->worker_ids[0]);
1096   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1097 
1098   busy_wait();
1099 
1100   sc = rtems_task_start(
1101     ctx->high_task_id[1],
1102     run_task,
1103     (rtems_task_argument) &ctx->high_run[1]
1104   );
1105   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1106 
1107   while (!ctx->high_run[1]) {
1108     /* Do noting */
1109   }
1110 
1111   sc = rtems_task_resume(ctx->worker_ids[0]);
1112   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1113 
1114   /* Try to schedule a blocked active rival */
1115 
1116   sc = rtems_task_suspend(ctx->worker_ids[0]);
1117   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1118 
1119   sc = rtems_task_suspend(ctx->high_task_id[1]);
1120   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1121 
1122   sc = rtems_task_resume(ctx->high_task_id[1]);
1123   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1124 
1125   sc = rtems_task_resume(ctx->worker_ids[0]);
1126   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1127 
1128   rtems_test_assert(rtems_scheduler_get_processor() == 0);
1129 
1130   /* Use node of the active rival */
1131 
1132   sc = rtems_task_suspend(ctx->high_task_id[1]);
1133   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1134 
1135   sc = rtems_task_resume(ctx->high_task_id[0]);
1136   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1137 
1138   rtems_test_assert(rtems_scheduler_get_processor() == 1);
1139 
1140   sc = rtems_task_suspend(ctx->worker_ids[0]);
1141   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1142 
1143   sc = rtems_task_resume(ctx->worker_ids[0]);
1144   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1145 
1146   /*
1147    * Try to schedule an active rival with an already scheduled active owner
1148    * user.
1149    */
1150 
1151   fire_timer(ctx, 2, unblock_owner_before_rival_timer);
1152 
1153   /* This will take the processor away from us, the timer will help later */
1154   sc = rtems_task_resume(ctx->high_task_id[1]);
1155   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1156 
1157   /*
1158    * Try to schedule an active owner with an already scheduled active rival
1159    * user.
1160    */
1161 
1162   sc = rtems_task_resume(ctx->high_task_id[0]);
1163   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1164 
1165   fire_timer(ctx, 2, unblock_owner_after_rival_timer);
1166 
1167   /* This will take the processor away from us, the timer will help later */
1168   sc = rtems_task_resume(ctx->high_task_id[1]);
1169   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1170 
1171   sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
1172   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1173 
1174   rtems_test_assert(rtems_scheduler_get_processor() == 0);
1175 
1176   assert_prio(RTEMS_SELF, 4);
1177 
1178   /* Worker done (G) */
1179   barrier(ctx, &barrier_state);
1180 }
1181 
1182 static void start_low_task(test_context *ctx, size_t i)
1183 {
1184   rtems_status_code sc;
1185 
1186   sc = rtems_task_create(
1187     rtems_build_name('L', 'O', 'W', '0' + i),
1188     255,
1189     RTEMS_MINIMUM_STACK_SIZE,
1190     RTEMS_DEFAULT_MODES,
1191     RTEMS_DEFAULT_ATTRIBUTES,
1192     &ctx->low_task_id[i]
1193   );
1194   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1195 
1196   sc = rtems_task_set_scheduler(ctx->low_task_id[i], ctx->scheduler_ids[i], 5);
1197   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1198 
1199   sc = rtems_task_start(
1200     ctx->low_task_id[i],
1201     run_task,
1202     (rtems_task_argument) &ctx->low_run[i]
1203   );
1204   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1205 }
1206 
1207 static void test_mrsp_various_block_and_unblock(test_context *ctx)
1208 {
1209   rtems_status_code sc;
1210 
1211   puts("test MrsP various block and unblock");
1212 
1213   change_prio(RTEMS_SELF, 4);
1214 
1215   barrier_init(ctx);
1216   reset_switch_events(ctx);
1217 
1218   ctx->low_run[0] = false;
1219   ctx->low_run[1] = false;
1220   ctx->high_run[0] = false;
1221   ctx->high_run[1] = false;
1222 
1223   create_mrsp_sema(ctx, &ctx->mrsp_ids[0], 3);
1224   assert_prio(RTEMS_SELF, 4);
1225 
1226   sc = rtems_task_create(
1227     rtems_build_name('H', 'I', 'G', '0'),
1228     2,
1229     RTEMS_MINIMUM_STACK_SIZE,
1230     RTEMS_DEFAULT_MODES,
1231     RTEMS_DEFAULT_ATTRIBUTES,
1232     &ctx->high_task_id[0]
1233   );
1234   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1235 
1236   sc = rtems_task_create(
1237     rtems_build_name('H', 'I', 'G', '1'),
1238     255,
1239     RTEMS_MINIMUM_STACK_SIZE,
1240     RTEMS_DEFAULT_MODES,
1241     RTEMS_DEFAULT_ATTRIBUTES,
1242     &ctx->high_task_id[1]
1243   );
1244   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1245 
1246   sc = rtems_task_set_scheduler(ctx->high_task_id[1], ctx->scheduler_ids[1], 2);
1247   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1248 
1249   sc = rtems_task_create(
1250     rtems_build_name('W', 'O', 'R', 'K'),
1251     255,
1252     RTEMS_MINIMUM_STACK_SIZE,
1253     RTEMS_DEFAULT_MODES,
1254     RTEMS_DEFAULT_ATTRIBUTES,
1255     &ctx->worker_ids[0]
1256   );
1257   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1258 
1259   sc = rtems_task_set_scheduler(ctx->worker_ids[0], ctx->scheduler_ids[1], 4);
1260   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1261 
1262   sc = rtems_task_start(ctx->worker_ids[0], ready_unlock_worker, 0);
1263   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1264 
1265   create_timer(ctx);
1266 
1267   /* In case these tasks run, then we have a MrsP protocol violation */
1268   start_low_task(ctx, 0);
1269   start_low_task(ctx, 1);
1270 
1271   unblock_ready_owner(ctx);
1272   various_block_unblock(ctx);
1273 
1274   rtems_test_assert(!ctx->low_run[0]);
1275   rtems_test_assert(!ctx->low_run[1]);
1276 
1277   print_switch_events(ctx);
1278   delete_timer(ctx);
1279 
1280   sc = rtems_task_delete(ctx->high_task_id[0]);
1281   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1282 
1283   sc = rtems_task_delete(ctx->high_task_id[1]);
1284   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1285 
1286   sc = rtems_task_delete(ctx->worker_ids[0]);
1287   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1288 
1289   sc = rtems_task_delete(ctx->low_task_id[0]);
1290   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1291 
1292   sc = rtems_task_delete(ctx->low_task_id[1]);
1293   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1294 
1295   sc = rtems_semaphore_delete(ctx->mrsp_ids[0]);
1296   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1297 }
1298 
1299 static void test_mrsp_obtain_and_sleep_and_release(test_context *ctx)
1300 {
1301   rtems_status_code sc;
1302   rtems_id sem_id;
1303   rtems_id run_task_id;
1304   volatile bool run = false;
1305 
1306   puts("test MrsP obtain and sleep and release");
1307 
1308   change_prio(RTEMS_SELF, 1);
1309 
1310   reset_switch_events(ctx);
1311 
1312   sc = rtems_task_create(
1313     rtems_build_name(' ', 'R', 'U', 'N'),
1314     2,
1315     RTEMS_MINIMUM_STACK_SIZE,
1316     RTEMS_DEFAULT_MODES,
1317     RTEMS_DEFAULT_ATTRIBUTES,
1318     &run_task_id
1319   );
1320   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1321 
1322   sc = rtems_task_start(run_task_id, run_task, (rtems_task_argument) &run);
1323   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1324 
1325   create_mrsp_sema(ctx, &sem_id, 1);
1326 
1327   rtems_test_assert(!run);
1328 
1329   sc = rtems_task_wake_after(2);
1330   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1331 
1332   rtems_test_assert(run);
1333   run = false;
1334 
1335   sc = rtems_semaphore_obtain(sem_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1336   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1337 
1338   rtems_test_assert(!run);
1339 
1340   sc = rtems_task_wake_after(2);
1341   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1342 
1343   rtems_test_assert(!run);
1344 
1345   sc = rtems_semaphore_release(sem_id);
1346   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1347 
1348   print_switch_events(ctx);
1349 
1350   sc = rtems_semaphore_delete(sem_id);
1351   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1352 
1353   sc = rtems_task_delete(run_task_id);
1354   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1355 }
1356 
1357 static void help_task(rtems_task_argument arg)
1358 {
1359   test_context *ctx = &test_instance;
1360   rtems_status_code sc;
1361 
1362   sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1363   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1364 
1365   sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
1366   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1367 
1368   while (true) {
1369     /* Do nothing */
1370   }
1371 }
1372 
1373 static void test_mrsp_obtain_and_release_with_help(test_context *ctx)
1374 {
1375   rtems_status_code sc;
1376   rtems_id help_task_id;
1377   rtems_id run_task_id;
1378   volatile bool run = false;
1379 
1380   puts("test MrsP obtain and release with help");
1381 
1382   change_prio(RTEMS_SELF, 3);
1383 
1384   reset_switch_events(ctx);
1385 
1386   create_mrsp_sema(ctx, &ctx->mrsp_ids[0], 2);
1387 
1388   sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1389   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1390 
1391   assert_prio(RTEMS_SELF, 2);
1392 
1393   sc = rtems_task_create(
1394     rtems_build_name('H', 'E', 'L', 'P'),
1395     255,
1396     RTEMS_MINIMUM_STACK_SIZE,
1397     RTEMS_DEFAULT_MODES,
1398     RTEMS_DEFAULT_ATTRIBUTES,
1399     &help_task_id
1400   );
1401   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1402 
1403   sc = rtems_task_set_scheduler(
1404     help_task_id,
1405     ctx->scheduler_ids[1],
1406     3
1407   );
1408   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1409 
1410   sc = rtems_task_start(help_task_id, help_task, 0);
1411   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1412 
1413   sc = rtems_task_create(
1414     rtems_build_name(' ', 'R', 'U', 'N'),
1415     4,
1416     RTEMS_MINIMUM_STACK_SIZE,
1417     RTEMS_DEFAULT_MODES,
1418     RTEMS_DEFAULT_ATTRIBUTES,
1419     &run_task_id
1420   );
1421   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1422 
1423   sc = rtems_task_start(run_task_id, run_task, (rtems_task_argument) &run);
1424   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1425 
1426   wait_for_prio(help_task_id, 2);
1427 
1428   sc = rtems_task_wake_after(2);
1429   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1430 
1431   rtems_test_assert(rtems_scheduler_get_processor() == 0);
1432   rtems_test_assert(!run);
1433 
1434   change_prio(run_task_id, 1);
1435 
1436   rtems_test_assert(rtems_scheduler_get_processor() == 1);
1437 
1438   while (!run) {
1439     /* Wait */
1440   }
1441 
1442   sc = rtems_task_wake_after(2);
1443   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1444 
1445   rtems_test_assert(rtems_scheduler_get_processor() == 1);
1446 
1447   change_prio(run_task_id, 4);
1448 
1449   rtems_test_assert(rtems_scheduler_get_processor() == 1);
1450 
1451   /*
1452    * With this operation the scheduler instance 0 has now only the main and the
1453    * idle threads in the ready set.
1454    */
1455   sc = rtems_task_suspend(run_task_id);
1456   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1457 
1458   rtems_test_assert(rtems_scheduler_get_processor() == 1);
1459 
1460   change_prio(RTEMS_SELF, 1);
1461   change_prio(RTEMS_SELF, 3);
1462 
1463   sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
1464   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1465 
1466   rtems_test_assert(rtems_scheduler_get_processor() == 0);
1467 
1468   assert_prio(RTEMS_SELF, 3);
1469 
1470   wait_for_prio(help_task_id, 3);
1471 
1472   print_switch_events(ctx);
1473 
1474   sc = rtems_semaphore_delete(ctx->mrsp_ids[0]);
1475   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1476 
1477   sc = rtems_task_delete(help_task_id);
1478   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1479 
1480   sc = rtems_task_delete(run_task_id);
1481   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1482 }
1483 
1484 static uint32_t simple_random(uint32_t v)
1485 {
1486   v *= 1664525;
1487   v += 1013904223;
1488 
1489   return v;
1490 }
1491 
1492 static rtems_interval timeout(uint32_t v)
1493 {
1494   return (v >> 23) % 4;
1495 }
1496 
1497 static void load_worker(rtems_task_argument index)
1498 {
1499   test_context *ctx = &test_instance;
1500   rtems_status_code sc;
1501   uint32_t v = index;
1502 
1503   while (!ctx->stop_worker[index]) {
1504     uint32_t i = (v >> 13) % MRSP_COUNT;
1505 
1506     assert_prio(RTEMS_SELF, 3 + CPU_COUNT + index);
1507 
1508     if ((v >> 7) % 1024 == 0) {
1509       /* Give some time to the lower priority tasks */
1510 
1511       ++ctx->counters[index].sleep;
1512 
1513       sc = rtems_task_wake_after(1);
1514       rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1515 
1516       ++ctx->counters[index].cpu[rtems_scheduler_get_processor()];
1517     } else {
1518       uint32_t n = (v >> 17) % (i + 1);
1519       uint32_t s;
1520       uint32_t t;
1521 
1522       /* Nested obtain */
1523       for (s = 0; s <= n; ++s) {
1524         uint32_t k = i - s;
1525 
1526         sc = rtems_semaphore_obtain(ctx->mrsp_ids[k], RTEMS_WAIT, timeout(v));
1527         if (sc == RTEMS_SUCCESSFUL) {
1528           ++ctx->counters[index].obtain[n];
1529 
1530           assert_prio(RTEMS_SELF, 3 + k);
1531         } else {
1532           rtems_test_assert(sc == RTEMS_TIMEOUT);
1533 
1534           ++ctx->counters[index].timeout;
1535 
1536           break;
1537         }
1538 
1539         ++ctx->counters[index].cpu[rtems_scheduler_get_processor()];
1540 
1541         v = simple_random(v);
1542       }
1543 
1544       /* Release in reverse obtain order */
1545       for (t = 0; t < s; ++t) {
1546         uint32_t k = i + t - s + 1;
1547 
1548         sc = rtems_semaphore_release(ctx->mrsp_ids[k]);
1549         rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1550 
1551         ++ctx->counters[index].cpu[rtems_scheduler_get_processor()];
1552       }
1553     }
1554 
1555     v = simple_random(v);
1556   }
1557 
1558   sc = rtems_semaphore_release(ctx->counting_sem_id);
1559   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1560 
1561   rtems_task_suspend(RTEMS_SELF);
1562   rtems_test_assert(0);
1563 }
1564 
1565 static void migration_task(rtems_task_argument arg)
1566 {
1567   test_context *ctx = &test_instance;
1568   rtems_status_code sc;
1569   uint32_t cpu_count = rtems_scheduler_get_processor_maximum();
1570   uint32_t v = 0xdeadbeef;
1571 
1572   while (true) {
1573     uint32_t cpu_index = (v >> 5) % cpu_count;
1574 
1575     sc = rtems_task_set_scheduler(RTEMS_SELF, ctx->scheduler_ids[cpu_index], 2);
1576     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1577 
1578     ++ctx->migration_counters[rtems_scheduler_get_processor()];
1579 
1580     v = simple_random(v);
1581   }
1582 }
1583 
1584 static void test_mrsp_load(test_context *ctx)
1585 {
1586   rtems_status_code sc;
1587   uint32_t cpu_count = rtems_scheduler_get_processor_maximum();
1588   uint32_t index;
1589 
1590   puts("test MrsP load");
1591 
1592   change_prio(RTEMS_SELF, 2);
1593 
1594   sc = rtems_task_create(
1595     rtems_build_name('M', 'I', 'G', 'R'),
1596     2,
1597     RTEMS_MINIMUM_STACK_SIZE,
1598     RTEMS_DEFAULT_MODES,
1599     RTEMS_DEFAULT_ATTRIBUTES,
1600     &ctx->migration_task_id
1601   );
1602   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1603 
1604   sc = rtems_task_start(ctx->migration_task_id, migration_task, 0);
1605   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1606 
1607   sc = rtems_semaphore_create(
1608     rtems_build_name('S', 'Y', 'N', 'C'),
1609     0,
1610     RTEMS_COUNTING_SEMAPHORE,
1611     0,
1612     &ctx->counting_sem_id
1613   );
1614   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1615 
1616   for (index = 0; index < MRSP_COUNT; ++index) {
1617     create_mrsp_sema(ctx, &ctx->mrsp_ids[index], 3 + index);
1618   }
1619 
1620   for (index = 0; index < cpu_count; ++index) {
1621     uint32_t a = 2 * index;
1622     uint32_t b = a + 1;
1623 
1624     sc = rtems_task_create(
1625       'A' + a,
1626       255,
1627       RTEMS_MINIMUM_STACK_SIZE,
1628       RTEMS_DEFAULT_MODES,
1629       RTEMS_DEFAULT_ATTRIBUTES,
1630       &ctx->worker_ids[a]
1631     );
1632     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1633 
1634     sc = rtems_task_set_scheduler(
1635       ctx->worker_ids[a],
1636       ctx->scheduler_ids[index],
1637       3 + MRSP_COUNT + a
1638     );
1639     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1640 
1641     sc = rtems_task_start(
1642       ctx->worker_ids[a],
1643       load_worker,
1644       (rtems_task_argument) a
1645     );
1646     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1647 
1648     sc = rtems_task_create(
1649       'A' + b,
1650       255,
1651       RTEMS_MINIMUM_STACK_SIZE,
1652       RTEMS_DEFAULT_MODES,
1653       RTEMS_DEFAULT_ATTRIBUTES,
1654       &ctx->worker_ids[b]
1655     );
1656     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1657 
1658     sc = rtems_task_set_scheduler(
1659       ctx->worker_ids[b],
1660       ctx->scheduler_ids[index],
1661       3 + MRSP_COUNT + b
1662     );
1663     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1664 
1665     sc = rtems_task_start(
1666       ctx->worker_ids[b],
1667       load_worker,
1668       (rtems_task_argument) b
1669     );
1670     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1671   }
1672 
1673   sc = rtems_task_wake_after(30 * rtems_clock_get_ticks_per_second());
1674   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1675 
1676   for (index = 0; index < 2 * cpu_count; ++index) {
1677     ctx->stop_worker[index] = true;
1678   }
1679 
1680   for (index = 0; index < 2 * cpu_count; ++index) {
1681     sc = rtems_semaphore_obtain(
1682       ctx->counting_sem_id,
1683       RTEMS_WAIT,
1684       RTEMS_NO_TIMEOUT
1685     );
1686     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1687   }
1688 
1689   for (index = 0; index < 2 * cpu_count; ++index) {
1690     sc = rtems_task_delete(ctx->worker_ids[index]);
1691     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1692   }
1693 
1694   for (index = 0; index < MRSP_COUNT; ++index) {
1695     sc = rtems_semaphore_delete(ctx->mrsp_ids[index]);
1696     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1697   }
1698 
1699   sc = rtems_semaphore_delete(ctx->counting_sem_id);
1700   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1701 
1702   sc = rtems_task_delete(ctx->migration_task_id);
1703   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1704 
1705   for (index = 0; index < 2 * cpu_count; ++index) {
1706     uint32_t nest_level;
1707     uint32_t cpu_index;
1708 
1709     printf(
1710       "worker[%" PRIu32 "]\n"
1711         "  sleep = %" PRIu32 "\n"
1712         "  timeout = %" PRIu32 "\n",
1713       index,
1714       ctx->counters[index].sleep,
1715       ctx->counters[index].timeout
1716     );
1717 
1718     for (nest_level = 0; nest_level < MRSP_COUNT; ++nest_level) {
1719       printf(
1720         "  obtain[%" PRIu32 "] = %" PRIu32 "\n",
1721         nest_level,
1722         ctx->counters[index].obtain[nest_level]
1723       );
1724     }
1725 
1726     for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
1727       printf(
1728         "  cpu[%" PRIu32 "] = %" PRIu32 "\n",
1729         cpu_index,
1730         ctx->counters[index].cpu[cpu_index]
1731       );
1732     }
1733   }
1734 
1735   for (index = 0; index < cpu_count; ++index) {
1736     printf(
1737       "migrations[%" PRIu32 "] = %" PRIu32 "\n",
1738       index,
1739       ctx->migration_counters[index]
1740     );
1741   }
1742 }
1743 
1744 static void Init(rtems_task_argument arg)
1745 {
1746   test_context *ctx = &test_instance;
1747   rtems_status_code sc;
1748   rtems_resource_snapshot snapshot;
1749   uint32_t cpu_count = rtems_scheduler_get_processor_maximum();
1750   uint32_t cpu_index;
1751 
1752   TEST_BEGIN();
1753 
1754   rtems_resource_snapshot_take(&snapshot);
1755 
1756   ctx->main_task_id = rtems_task_self();
1757 
1758   for (cpu_index = 0; cpu_index < MIN(2, cpu_count); ++cpu_index) {
1759     sc = rtems_scheduler_ident(cpu_index, &ctx->scheduler_ids[cpu_index]);
1760     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1761   }
1762 
1763   for (cpu_index = 2; cpu_index < cpu_count; ++cpu_index) {
1764     sc = rtems_scheduler_ident(
1765       cpu_index / 2 + 1,
1766       &ctx->scheduler_ids[cpu_index]
1767     );
1768     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1769   }
1770 
1771   test_mrsp_flush_error(ctx);
1772   test_mrsp_initially_locked();
1773   test_mrsp_nested_obtain_error(ctx);
1774   test_mrsp_deadlock_error(ctx);
1775   test_mrsp_multiple_obtain(ctx);
1776 
1777   if (cpu_count > 1) {
1778     test_mrsp_various_block_and_unblock(ctx);
1779     test_mrsp_obtain_after_migration(ctx);
1780     test_mrsp_obtain_and_sleep_and_release(ctx);
1781     test_mrsp_obtain_and_release_with_help(ctx);
1782     test_mrsp_obtain_and_release(ctx);
1783     test_mrsp_load(ctx);
1784   }
1785 
1786   rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
1787 
1788   TEST_END();
1789   rtems_test_exit(0);
1790 }
1791 
1792 #define CONFIGURE_MICROSECONDS_PER_TICK 1000
1793 
1794 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
1795 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
1796 
1797 #define CONFIGURE_MAXIMUM_TASKS (2 * CPU_COUNT + 2)
1798 #define CONFIGURE_MAXIMUM_SEMAPHORES (MRSP_COUNT + 1)
1799 #define CONFIGURE_MAXIMUM_TIMERS 1
1800 
1801 #define CONFIGURE_MAXIMUM_PROCESSORS CPU_COUNT
1802 
1803 #define CONFIGURE_SCHEDULER_SIMPLE_SMP
1804 
1805 #include <rtems/scheduler.h>
1806 
1807 RTEMS_SCHEDULER_SIMPLE_SMP(0);
1808 RTEMS_SCHEDULER_SIMPLE_SMP(1);
1809 RTEMS_SCHEDULER_SIMPLE_SMP(2);
1810 RTEMS_SCHEDULER_SIMPLE_SMP(3);
1811 RTEMS_SCHEDULER_SIMPLE_SMP(4);
1812 RTEMS_SCHEDULER_SIMPLE_SMP(5);
1813 RTEMS_SCHEDULER_SIMPLE_SMP(6);
1814 RTEMS_SCHEDULER_SIMPLE_SMP(7);
1815 RTEMS_SCHEDULER_SIMPLE_SMP(8);
1816 RTEMS_SCHEDULER_SIMPLE_SMP(9);
1817 RTEMS_SCHEDULER_SIMPLE_SMP(10);
1818 RTEMS_SCHEDULER_SIMPLE_SMP(11);
1819 RTEMS_SCHEDULER_SIMPLE_SMP(12);
1820 RTEMS_SCHEDULER_SIMPLE_SMP(13);
1821 RTEMS_SCHEDULER_SIMPLE_SMP(14);
1822 RTEMS_SCHEDULER_SIMPLE_SMP(15);
1823 RTEMS_SCHEDULER_SIMPLE_SMP(16);
1824 
1825 #define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
1826   RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(0, 0), \
1827   RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(1, 1), \
1828   RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(2, 2), \
1829   RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(3, 3), \
1830   RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(4, 4), \
1831   RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(5, 5), \
1832   RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(6, 6), \
1833   RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(7, 7), \
1834   RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(8, 8), \
1835   RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(9, 9), \
1836   RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(10, 10), \
1837   RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(11, 11), \
1838   RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(12, 12), \
1839   RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(13, 13), \
1840   RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(14, 14), \
1841   RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(15, 15), \
1842   RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(16, 16)
1843 
1844 #define CONFIGURE_SCHEDULER_ASSIGNMENTS \
1845   RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
1846   RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1847   RTEMS_SCHEDULER_ASSIGN(2, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1848   RTEMS_SCHEDULER_ASSIGN(2, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1849   RTEMS_SCHEDULER_ASSIGN(3, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1850   RTEMS_SCHEDULER_ASSIGN(3, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1851   RTEMS_SCHEDULER_ASSIGN(4, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1852   RTEMS_SCHEDULER_ASSIGN(4, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1853   RTEMS_SCHEDULER_ASSIGN(5, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1854   RTEMS_SCHEDULER_ASSIGN(5, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1855   RTEMS_SCHEDULER_ASSIGN(6, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1856   RTEMS_SCHEDULER_ASSIGN(6, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1857   RTEMS_SCHEDULER_ASSIGN(7, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1858   RTEMS_SCHEDULER_ASSIGN(7, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1859   RTEMS_SCHEDULER_ASSIGN(8, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1860   RTEMS_SCHEDULER_ASSIGN(8, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1861   RTEMS_SCHEDULER_ASSIGN(9, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1862   RTEMS_SCHEDULER_ASSIGN(9, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1863   RTEMS_SCHEDULER_ASSIGN(10, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1864   RTEMS_SCHEDULER_ASSIGN(10, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1865   RTEMS_SCHEDULER_ASSIGN(11, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1866   RTEMS_SCHEDULER_ASSIGN(11, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1867   RTEMS_SCHEDULER_ASSIGN(12, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1868   RTEMS_SCHEDULER_ASSIGN(12, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1869   RTEMS_SCHEDULER_ASSIGN(13, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1870   RTEMS_SCHEDULER_ASSIGN(13, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1871   RTEMS_SCHEDULER_ASSIGN(14, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1872   RTEMS_SCHEDULER_ASSIGN(14, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1873   RTEMS_SCHEDULER_ASSIGN(15, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1874   RTEMS_SCHEDULER_ASSIGN(15, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1875   RTEMS_SCHEDULER_ASSIGN(16, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1876   RTEMS_SCHEDULER_ASSIGN(16, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
1877 
1878 #define CONFIGURE_INITIAL_EXTENSIONS \
1879   { .thread_switch = switch_extension }, \
1880   RTEMS_TEST_INITIAL_EXTENSION
1881 
1882 #define CONFIGURE_INIT_TASK_NAME rtems_build_name('M', 'A', 'I', 'N')
1883 #define CONFIGURE_INIT_TASK_PRIORITY 2
1884 
1885 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
1886 
1887 #define CONFIGURE_INIT
1888 
1889 #include <rtems/confdefs.h>