Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (c) 2018 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 <rtems.h>
0033 #include <rtems/thread.h>
0034 #include <rtems/score/threadimpl.h>
0035 
0036 #include <tmacros.h>
0037 
0038 const char rtems_test_name[] = "SMPTHREADPIN 1";
0039 
0040 #define CPU_COUNT 2
0041 
0042 #define SCHED_A rtems_build_name(' ', ' ', ' ', 'A')
0043 
0044 #define SCHED_B rtems_build_name(' ', ' ', ' ', 'B')
0045 
0046 #define EVENT_WAKEUP_MASTER RTEMS_EVENT_0
0047 
0048 #define EVENT_MTX_LOCK RTEMS_EVENT_1
0049 
0050 #define EVENT_MTX_UNLOCK RTEMS_EVENT_2
0051 
0052 #define EVENT_MOVE_BUSY_TO_CPU_0 RTEMS_EVENT_3
0053 
0054 #define EVENT_MOVE_BUSY_TO_CPU_1 RTEMS_EVENT_4
0055 
0056 #define EVENT_MOVE_SELF_TO_CPU_0 RTEMS_EVENT_5
0057 
0058 #define EVENT_MOVE_SELF_TO_CPU_1 RTEMS_EVENT_6
0059 
0060 #define EVENT_SET_SELF_PRIO_TO_LOW RTEMS_EVENT_7
0061 
0062 #define EVENT_SET_BUSY_PRIO_TO_IDLE RTEMS_EVENT_8
0063 
0064 #define EVENT_SET_FLAG RTEMS_EVENT_9
0065 
0066 #define PRIO_IDLE 6
0067 
0068 #define PRIO_VERY_LOW 5
0069 
0070 #define PRIO_LOW 4
0071 
0072 #define PRIO_MIDDLE 3
0073 
0074 #define PRIO_HIGH 2
0075 
0076 #define PRIO_VERY_HIGH 1
0077 
0078 typedef struct {
0079   rtems_id master;
0080   rtems_id event;
0081   rtems_id event_2;
0082   rtems_id busy;
0083   rtems_id sched_a;
0084   rtems_id sched_b;
0085   rtems_mutex mtx;
0086   volatile bool flag;
0087 } test_context;
0088 
0089 static test_context test_instance;
0090 
0091 static rtems_task_priority set_prio(rtems_id id, rtems_task_priority prio)
0092 {
0093   rtems_status_code sc;
0094   rtems_task_priority old_prio;
0095 
0096   old_prio = 0xffffffff;
0097   sc = rtems_task_set_priority(id, prio, &old_prio);
0098   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0099 
0100   return old_prio;
0101 }
0102 
0103 static void set_affinity(rtems_id task, uint32_t cpu_index)
0104 {
0105   rtems_status_code sc;
0106   rtems_id sched_cpu;
0107   rtems_id sched_task;
0108   cpu_set_t set;
0109 
0110   sc = rtems_scheduler_ident_by_processor(cpu_index, &sched_cpu);
0111   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0112 
0113   sc = rtems_task_get_scheduler(task, &sched_task);
0114   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0115 
0116   if (sched_task != sched_cpu) {
0117     rtems_task_priority prio;
0118 
0119     CPU_FILL(&set);
0120     sc = rtems_task_set_affinity(task, sizeof(set), &set);
0121     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0122 
0123     prio = set_prio(task, RTEMS_CURRENT_PRIORITY);
0124     sc = rtems_task_set_scheduler(task, sched_cpu, prio);
0125     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0126   }
0127 
0128   CPU_ZERO(&set);
0129   CPU_SET((int) cpu_index, &set);
0130   sc = rtems_task_set_affinity(task, sizeof(set), &set);
0131   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0132 }
0133 
0134 static void send_events(rtems_id task, rtems_event_set events)
0135 {
0136   rtems_status_code sc;
0137 
0138   sc = rtems_event_send(task, events);
0139   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0140 }
0141 
0142 static rtems_event_set wait_for_events(void)
0143 {
0144   rtems_event_set events;
0145   rtems_status_code sc;
0146 
0147   sc = rtems_event_receive(
0148     RTEMS_ALL_EVENTS,
0149     RTEMS_EVENT_ANY | RTEMS_WAIT,
0150     RTEMS_NO_TIMEOUT,
0151     &events
0152   );
0153   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0154 
0155   return events;
0156 }
0157 
0158 static void pin(bool blocked)
0159 {
0160   Per_CPU_Control *cpu_self;
0161   Thread_Control *executing;
0162 
0163   cpu_self = _Thread_Dispatch_disable();
0164   executing = _Per_CPU_Get_executing(cpu_self);
0165 
0166   if (blocked) {
0167     _Thread_Set_state(executing, STATES_SUSPENDED);
0168   }
0169 
0170   _Thread_Pin(executing);
0171 
0172   if (blocked) {
0173     _Thread_Clear_state(executing, STATES_SUSPENDED);
0174   }
0175 
0176   _Thread_Dispatch_enable(cpu_self);
0177 }
0178 
0179 static void unpin(bool blocked)
0180 {
0181   Per_CPU_Control *cpu_self;
0182   Thread_Control *executing;
0183 
0184   cpu_self = _Thread_Dispatch_disable();
0185   executing = _Per_CPU_Get_executing(cpu_self);
0186 
0187   if (blocked) {
0188     _Thread_Set_state(executing, STATES_SUSPENDED);
0189   }
0190 
0191   _Thread_Unpin(executing, cpu_self);
0192 
0193   if (blocked) {
0194     _Thread_Clear_state(executing, STATES_SUSPENDED);
0195   }
0196 
0197   _Thread_Dispatch_enable(cpu_self);
0198 }
0199 
0200 static void event_task(rtems_task_argument arg)
0201 {
0202   test_context *ctx;
0203 
0204   ctx = (test_context *) arg;
0205 
0206   while (true) {
0207     rtems_event_set events;
0208 
0209     events = wait_for_events();
0210 
0211     /*
0212      * The order of event processing is important!
0213      */
0214 
0215     if ((events & EVENT_MTX_LOCK) != 0) {
0216       rtems_mutex_lock(&ctx->mtx);
0217     }
0218 
0219     if ((events & EVENT_MTX_UNLOCK) != 0) {
0220       rtems_mutex_unlock(&ctx->mtx);
0221     }
0222 
0223     if ((events & EVENT_MOVE_BUSY_TO_CPU_0) != 0) {
0224       set_affinity(ctx->busy, 0);
0225     }
0226 
0227     if ((events & EVENT_MOVE_BUSY_TO_CPU_1) != 0) {
0228       set_affinity(ctx->busy, 1);
0229     }
0230 
0231     if ((events & EVENT_MOVE_SELF_TO_CPU_0) != 0) {
0232       set_affinity(RTEMS_SELF, 0);
0233     }
0234 
0235     if ((events & EVENT_MOVE_SELF_TO_CPU_1) != 0) {
0236       set_affinity(RTEMS_SELF, 1);
0237     }
0238 
0239     if ((events & EVENT_SET_SELF_PRIO_TO_LOW) != 0) {
0240       set_prio(RTEMS_SELF, PRIO_LOW);
0241     }
0242 
0243     if ((events & EVENT_SET_BUSY_PRIO_TO_IDLE) != 0) {
0244       set_prio(ctx->busy, PRIO_IDLE);
0245     }
0246 
0247     if ((events & EVENT_SET_FLAG) != 0) {
0248       ctx->flag = true;
0249     }
0250 
0251     if ((events & EVENT_WAKEUP_MASTER) != 0) {
0252       send_events(ctx->master, EVENT_WAKEUP_MASTER);
0253     }
0254   }
0255 }
0256 
0257 static void busy_task(rtems_task_argument arg)
0258 {
0259   (void) arg;
0260 
0261   _CPU_Thread_Idle_body(0);
0262 }
0263 
0264 static const char *blocked_or_ready(bool blocked)
0265 {
0266   return blocked ? "blocked" : "ready";
0267 }
0268 
0269 static void reconfigure_scheduler(test_context *ctx)
0270 {
0271   rtems_status_code sc;
0272 
0273   puts("reconfigure scheduler");
0274 
0275   set_prio(ctx->master, PRIO_MIDDLE);
0276   set_prio(ctx->event, PRIO_LOW);
0277   set_prio(ctx->event_2, PRIO_VERY_LOW);
0278   set_prio(ctx->busy, PRIO_IDLE);
0279 
0280   set_affinity(ctx->master, 0);
0281   set_affinity(ctx->event, 0);
0282   set_affinity(ctx->event_2, 0);
0283   set_affinity(ctx->busy, 0);
0284 
0285   sc = rtems_scheduler_remove_processor(ctx->sched_a, 1);
0286   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0287 
0288   sc = rtems_scheduler_add_processor(ctx->sched_b, 1);
0289   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0290 }
0291 
0292 static void test_simple_pin_unpin(test_context *ctx, int run)
0293 {
0294   Per_CPU_Control *cpu_self;
0295   Thread_Control *executing;
0296 
0297   printf("test simple wait unpin (run %i)\n", run);
0298 
0299   set_affinity(ctx->busy, 0);
0300   set_prio(ctx->busy, PRIO_IDLE);
0301   set_prio(RTEMS_SELF, PRIO_MIDDLE);
0302   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0303 
0304   cpu_self = _Thread_Dispatch_disable();
0305   executing = _Per_CPU_Get_executing(cpu_self);
0306   _Thread_Pin(executing);
0307 
0308   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0309 
0310   _Thread_Unpin(executing, cpu_self);
0311   _Thread_Dispatch_enable(cpu_self);
0312 
0313   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0314 }
0315 
0316 static void test_pin_wait_unpin(test_context *ctx, bool blocked, int run)
0317 {
0318   printf("test pin wait unpin (%s, run %i)\n", blocked_or_ready(blocked), run);
0319 
0320   set_affinity(ctx->busy, 0);
0321   set_prio(ctx->busy, PRIO_IDLE);
0322   set_prio(RTEMS_SELF, PRIO_MIDDLE);
0323   set_prio(ctx->event, PRIO_LOW);
0324   set_affinity(ctx->event, 1);
0325   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0326 
0327   pin(blocked);
0328   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0329 
0330   send_events(ctx->event, EVENT_WAKEUP_MASTER);
0331   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0332   wait_for_events();
0333   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0334 
0335   set_prio(ctx->busy, PRIO_HIGH);
0336   set_affinity(ctx->busy, 0);
0337   unpin(blocked);
0338   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0339 }
0340 
0341 static void test_pin_preempt_unpin(test_context *ctx, bool blocked, int run)
0342 {
0343   printf(
0344     "test pin preempt unpin (%s, run %i)\n",
0345     blocked_or_ready(blocked),
0346     run
0347   );
0348 
0349   set_prio(RTEMS_SELF, PRIO_MIDDLE);
0350   set_prio(ctx->event, PRIO_VERY_HIGH);
0351   set_prio(ctx->busy, PRIO_HIGH);
0352   set_affinity(ctx->event, 0);
0353   set_affinity(ctx->busy, 0);
0354   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0355 
0356   pin(blocked);
0357   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0358 
0359   ctx->flag = false;
0360   send_events(
0361     ctx->event,
0362     EVENT_MOVE_BUSY_TO_CPU_1 | EVENT_SET_SELF_PRIO_TO_LOW
0363       | EVENT_SET_BUSY_PRIO_TO_IDLE | EVENT_SET_FLAG
0364   );
0365 
0366   while (!ctx->flag) {
0367     rtems_test_assert(rtems_scheduler_get_processor() == 1);
0368   }
0369 
0370   set_affinity(ctx->busy, 0);
0371   unpin(blocked);
0372   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0373 }
0374 
0375 static void test_pin_home_no_help_unpin(
0376   test_context *ctx,
0377   bool blocked,
0378   int run
0379 )
0380 {
0381   rtems_status_code sc;
0382 
0383   printf(
0384     "test pin home no help unpin (%s, run %i)\n",
0385     blocked_or_ready(blocked),
0386     run
0387   );
0388 
0389   set_affinity(ctx->busy, 1);
0390   set_prio(ctx->busy, PRIO_IDLE);
0391   set_prio(RTEMS_SELF, PRIO_MIDDLE);
0392   rtems_test_assert(rtems_scheduler_get_processor() == 0);
0393 
0394   pin(blocked);
0395   rtems_test_assert(rtems_scheduler_get_processor() == 0);
0396 
0397   sc = rtems_task_set_scheduler(RTEMS_SELF, ctx->sched_b, 1);
0398   rtems_test_assert(sc == RTEMS_RESOURCE_IN_USE);
0399 
0400   rtems_mutex_lock(&ctx->mtx);
0401   rtems_test_assert(rtems_scheduler_get_processor() == 0);
0402 
0403   set_affinity(ctx->event, 1);
0404   set_prio(ctx->event, PRIO_MIDDLE);
0405 
0406   send_events(ctx->event, EVENT_MTX_LOCK);
0407   set_prio(ctx->event_2, PRIO_LOW);
0408   set_affinity(ctx->event_2, 1);
0409   send_events(ctx->event_2, EVENT_WAKEUP_MASTER);
0410   wait_for_events();
0411 
0412   /* Now the event task can help us */
0413   rtems_test_assert(ctx->mtx._Queue._heads != NULL);
0414   rtems_test_assert(rtems_scheduler_get_processor() == 0);
0415 
0416   set_affinity(ctx->event_2, 0);
0417   set_affinity(ctx->busy, 1);
0418   set_prio(ctx->busy, PRIO_HIGH);
0419   send_events(
0420     ctx->event_2,
0421     EVENT_MOVE_BUSY_TO_CPU_0 | EVENT_MOVE_SELF_TO_CPU_1
0422       | EVENT_SET_SELF_PRIO_TO_LOW | EVENT_SET_BUSY_PRIO_TO_IDLE
0423   );
0424   set_prio(ctx->event_2, PRIO_VERY_HIGH);
0425   rtems_test_assert(rtems_scheduler_get_processor() == 0);
0426 
0427   rtems_mutex_unlock(&ctx->mtx);
0428   rtems_test_assert(rtems_scheduler_get_processor() == 0);
0429 
0430   send_events(ctx->event, EVENT_WAKEUP_MASTER | EVENT_MTX_UNLOCK);
0431   wait_for_events();
0432   rtems_test_assert(rtems_scheduler_get_processor() == 0);
0433 
0434   unpin(blocked);
0435   rtems_test_assert(rtems_scheduler_get_processor() == 0);
0436 }
0437 
0438 static void test_pin_foreign_no_help_unpin(
0439   test_context *ctx,
0440   bool blocked,
0441   int run
0442 )
0443 {
0444   printf(
0445     "test pin foreign no help unpin (%s, run %i)\n",
0446     blocked_or_ready(blocked),
0447     run
0448   );
0449 
0450   set_affinity(ctx->busy, 1);
0451   set_prio(ctx->busy, PRIO_IDLE);
0452   set_prio(RTEMS_SELF, PRIO_MIDDLE);
0453   rtems_test_assert(rtems_scheduler_get_processor() == 0);
0454 
0455   rtems_mutex_lock(&ctx->mtx);
0456   rtems_test_assert(rtems_scheduler_get_processor() == 0);
0457 
0458   set_affinity(ctx->event, 1);
0459   set_prio(ctx->event, PRIO_MIDDLE);
0460   send_events(ctx->event, EVENT_MTX_LOCK);
0461   set_prio(ctx->event_2, PRIO_LOW);
0462   set_affinity(ctx->event_2, 1);
0463   send_events(ctx->event_2, EVENT_WAKEUP_MASTER);
0464   wait_for_events();
0465 
0466   /* Now the event task can help us */
0467   rtems_test_assert(ctx->mtx._Queue._heads != NULL);
0468   rtems_test_assert(rtems_scheduler_get_processor() == 0);
0469 
0470   /* Request help */
0471   set_affinity(ctx->busy, 0);
0472   set_prio(ctx->busy, PRIO_HIGH);
0473   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0474 
0475   /* Pin while using foreign scheduler */
0476   pin(blocked);
0477   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0478 
0479   set_affinity(ctx->event_2, 1);
0480   send_events(
0481     ctx->event_2,
0482     EVENT_MOVE_BUSY_TO_CPU_1 | EVENT_MOVE_SELF_TO_CPU_0
0483       | EVENT_SET_SELF_PRIO_TO_LOW | EVENT_SET_BUSY_PRIO_TO_IDLE
0484   );
0485   set_prio(ctx->event_2, PRIO_VERY_HIGH);
0486   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0487 
0488   unpin(blocked);
0489   rtems_test_assert(rtems_scheduler_get_processor() == 0);
0490 
0491   set_prio(ctx->busy, PRIO_IDLE);
0492   rtems_mutex_unlock(&ctx->mtx);
0493   rtems_test_assert(rtems_scheduler_get_processor() == 0);
0494 
0495   send_events(ctx->event, EVENT_WAKEUP_MASTER | EVENT_MTX_UNLOCK);
0496   wait_for_events();
0497   rtems_test_assert(rtems_scheduler_get_processor() == 0);
0498 }
0499 
0500 static void test(test_context *ctx)
0501 {
0502   rtems_status_code sc;
0503   int run;
0504 
0505   ctx->master = rtems_task_self();
0506 
0507   rtems_mutex_init(&ctx->mtx, "test");
0508 
0509   sc = rtems_scheduler_ident(SCHED_A, &ctx->sched_a);
0510   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0511 
0512   sc = rtems_scheduler_ident(SCHED_B, &ctx->sched_b);
0513   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0514 
0515   sc = rtems_task_create(
0516     rtems_build_name('B', 'U', 'S', 'Y'),
0517     PRIO_HIGH,
0518     RTEMS_MINIMUM_STACK_SIZE,
0519     RTEMS_DEFAULT_MODES,
0520     RTEMS_DEFAULT_ATTRIBUTES,
0521     &ctx->busy
0522   );
0523   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0524 
0525   sc = rtems_task_start(ctx->busy, busy_task, (rtems_task_argument) ctx);
0526   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0527 
0528   set_affinity(ctx->busy, 0);
0529   set_prio(ctx->busy, PRIO_IDLE);
0530   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0531 
0532   sc = rtems_task_create(
0533     rtems_build_name('E', 'V', 'T', '1'),
0534     PRIO_LOW,
0535     RTEMS_MINIMUM_STACK_SIZE,
0536     RTEMS_DEFAULT_MODES,
0537     RTEMS_DEFAULT_ATTRIBUTES,
0538     &ctx->event
0539   );
0540   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0541 
0542   sc = rtems_task_start(ctx->event, event_task, (rtems_task_argument) ctx);
0543   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0544 
0545   send_events(ctx->event, EVENT_WAKEUP_MASTER);
0546   wait_for_events();
0547 
0548   sc = rtems_task_create(
0549     rtems_build_name('E', 'V', 'T', '2'),
0550     PRIO_LOW,
0551     RTEMS_MINIMUM_STACK_SIZE,
0552     RTEMS_DEFAULT_MODES,
0553     RTEMS_DEFAULT_ATTRIBUTES,
0554     &ctx->event_2
0555   );
0556   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0557 
0558   sc = rtems_task_start(ctx->event_2, event_task, (rtems_task_argument) ctx);
0559   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0560 
0561   send_events(ctx->event_2, EVENT_WAKEUP_MASTER);
0562   wait_for_events();
0563 
0564   for (run = 1; run <= 3; ++run) {
0565     test_simple_pin_unpin(ctx, run);
0566     test_pin_wait_unpin(ctx, true, run);
0567     test_pin_wait_unpin(ctx, false, run);
0568     test_pin_preempt_unpin(ctx, true, run);
0569     test_pin_preempt_unpin(ctx, false, run);
0570   }
0571 
0572   reconfigure_scheduler(ctx);
0573 
0574   for (run = 1; run <= 3; ++run) {
0575     test_pin_home_no_help_unpin(ctx, true, run);
0576     test_pin_home_no_help_unpin(ctx, false, run);
0577     test_pin_foreign_no_help_unpin(ctx, true, run);
0578     test_pin_foreign_no_help_unpin(ctx, false, run);
0579   }
0580 }
0581 
0582 static void Init(rtems_task_argument arg)
0583 {
0584   TEST_BEGIN();
0585 
0586   if (rtems_scheduler_get_processor_maximum() == CPU_COUNT) {
0587     test(&test_instance);
0588   } else {
0589     puts("warning: wrong processor count to run the test");
0590   }
0591 
0592   TEST_END();
0593   rtems_test_exit(0);
0594 }
0595 
0596 #define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
0597 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0598 
0599 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0600 
0601 #define CONFIGURE_MAXIMUM_PROCESSORS CPU_COUNT
0602 
0603 #define CONFIGURE_MAXIMUM_TASKS 4
0604 
0605 #define CONFIGURE_INIT_TASK_PRIORITY PRIO_MIDDLE
0606 
0607 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0608 
0609 #define CONFIGURE_SCHEDULER_EDF_SMP
0610 
0611 #include <rtems/scheduler.h>
0612 
0613 RTEMS_SCHEDULER_EDF_SMP(a);
0614 
0615 RTEMS_SCHEDULER_EDF_SMP(b);
0616 
0617 #define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
0618   RTEMS_SCHEDULER_TABLE_EDF_SMP(a, SCHED_A), \
0619   RTEMS_SCHEDULER_TABLE_EDF_SMP(b, SCHED_B)  \
0620 
0621 #define CONFIGURE_SCHEDULER_ASSIGNMENTS \
0622   RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
0623   RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
0624 
0625 #define CONFIGURE_INIT
0626 
0627 #include <rtems/confdefs.h>