Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RtemsTaskReqSetScheduler
0007  */
0008 
0009 /*
0010  * Copyright (C) 2021 embedded brains GmbH & Co. KG
0011  *
0012  * Redistribution and use in source and binary forms, with or without
0013  * modification, are permitted provided that the following conditions
0014  * are met:
0015  * 1. Redistributions of source code must retain the above copyright
0016  *    notice, this list of conditions and the following disclaimer.
0017  * 2. Redistributions in binary form must reproduce the above copyright
0018  *    notice, this list of conditions and the following disclaimer in the
0019  *    documentation and/or other materials provided with the distribution.
0020  *
0021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0025  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0026  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0027  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0030  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0031  * POSSIBILITY OF SUCH DAMAGE.
0032  */
0033 
0034 /*
0035  * This file is part of the RTEMS quality process and was automatically
0036  * generated.  If you find something that needs to be fixed or
0037  * worded better please post a report or patch to an RTEMS mailing list
0038  * or raise a bug report:
0039  *
0040  * https://www.rtems.org/bugs.html
0041  *
0042  * For information on updating and regenerating please refer to the How-To
0043  * section in the Software Requirements Engineering chapter of the
0044  * RTEMS Software Engineering manual.  The manual is provided as a part of
0045  * a release.  For development sources please refer to the online
0046  * documentation at:
0047  *
0048  * https://docs.rtems.org
0049  */
0050 
0051 #ifdef HAVE_CONFIG_H
0052 #include "config.h"
0053 #endif
0054 
0055 #include <rtems.h>
0056 #include <rtems/score/threadimpl.h>
0057 
0058 #include "ts-config.h"
0059 #include "tx-support.h"
0060 
0061 #include <rtems/test.h>
0062 
0063 /**
0064  * @defgroup RtemsTaskReqSetScheduler spec:/rtems/task/req/set-scheduler
0065  *
0066  * @ingroup TestsuitesValidationNoClock0
0067  *
0068  * @{
0069  */
0070 
0071 typedef enum {
0072   RtemsTaskReqSetScheduler_Pre_TaskId_Task,
0073   RtemsTaskReqSetScheduler_Pre_TaskId_Invalid,
0074   RtemsTaskReqSetScheduler_Pre_TaskId_NA
0075 } RtemsTaskReqSetScheduler_Pre_TaskId;
0076 
0077 typedef enum {
0078   RtemsTaskReqSetScheduler_Pre_Scheduler_Home,
0079   RtemsTaskReqSetScheduler_Pre_Scheduler_Other,
0080   RtemsTaskReqSetScheduler_Pre_Scheduler_NA
0081 } RtemsTaskReqSetScheduler_Pre_Scheduler;
0082 
0083 typedef enum {
0084   RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_Yes,
0085   RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_No,
0086   RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_NA
0087 } RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU;
0088 
0089 typedef enum {
0090   RtemsTaskReqSetScheduler_Pre_SchedulerId_Scheduler,
0091   RtemsTaskReqSetScheduler_Pre_SchedulerId_Invalid,
0092   RtemsTaskReqSetScheduler_Pre_SchedulerId_NA
0093 } RtemsTaskReqSetScheduler_Pre_SchedulerId;
0094 
0095 typedef enum {
0096   RtemsTaskReqSetScheduler_Pre_Priority_Valid,
0097   RtemsTaskReqSetScheduler_Pre_Priority_Invalid,
0098   RtemsTaskReqSetScheduler_Pre_Priority_NA
0099 } RtemsTaskReqSetScheduler_Pre_Priority;
0100 
0101 typedef enum {
0102   RtemsTaskReqSetScheduler_Pre_HomePriority_Real,
0103   RtemsTaskReqSetScheduler_Pre_HomePriority_More,
0104   RtemsTaskReqSetScheduler_Pre_HomePriority_NA
0105 } RtemsTaskReqSetScheduler_Pre_HomePriority;
0106 
0107 typedef enum {
0108   RtemsTaskReqSetScheduler_Pre_EligiblePriorities_OnlyOne,
0109   RtemsTaskReqSetScheduler_Pre_EligiblePriorities_More,
0110   RtemsTaskReqSetScheduler_Pre_EligiblePriorities_NA
0111 } RtemsTaskReqSetScheduler_Pre_EligiblePriorities;
0112 
0113 typedef enum {
0114   RtemsTaskReqSetScheduler_Pre_Pinned_Yes,
0115   RtemsTaskReqSetScheduler_Pre_Pinned_No,
0116   RtemsTaskReqSetScheduler_Pre_Pinned_NA
0117 } RtemsTaskReqSetScheduler_Pre_Pinned;
0118 
0119 typedef enum {
0120   RtemsTaskReqSetScheduler_Pre_TaskState_Ready,
0121   RtemsTaskReqSetScheduler_Pre_TaskState_Blocked,
0122   RtemsTaskReqSetScheduler_Pre_TaskState_Enqueued,
0123   RtemsTaskReqSetScheduler_Pre_TaskState_NA
0124 } RtemsTaskReqSetScheduler_Pre_TaskState;
0125 
0126 typedef enum {
0127   RtemsTaskReqSetScheduler_Pre_AffinitySupported_Yes,
0128   RtemsTaskReqSetScheduler_Pre_AffinitySupported_No,
0129   RtemsTaskReqSetScheduler_Pre_AffinitySupported_NA
0130 } RtemsTaskReqSetScheduler_Pre_AffinitySupported;
0131 
0132 typedef enum {
0133   RtemsTaskReqSetScheduler_Post_Status_Ok,
0134   RtemsTaskReqSetScheduler_Post_Status_InvAddr,
0135   RtemsTaskReqSetScheduler_Post_Status_InvId,
0136   RtemsTaskReqSetScheduler_Post_Status_InvPrio,
0137   RtemsTaskReqSetScheduler_Post_Status_InUse,
0138   RtemsTaskReqSetScheduler_Post_Status_Unsat,
0139   RtemsTaskReqSetScheduler_Post_Status_NA
0140 } RtemsTaskReqSetScheduler_Post_Status;
0141 
0142 typedef enum {
0143   RtemsTaskReqSetScheduler_Post_Scheduler_Set,
0144   RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
0145   RtemsTaskReqSetScheduler_Post_Scheduler_NA
0146 } RtemsTaskReqSetScheduler_Post_Scheduler;
0147 
0148 typedef enum {
0149   RtemsTaskReqSetScheduler_Post_Priority_Set,
0150   RtemsTaskReqSetScheduler_Post_Priority_Nop,
0151   RtemsTaskReqSetScheduler_Post_Priority_NA
0152 } RtemsTaskReqSetScheduler_Post_Priority;
0153 
0154 typedef struct {
0155   uint32_t Skip : 1;
0156   uint32_t Pre_TaskId_NA : 1;
0157   uint32_t Pre_Scheduler_NA : 1;
0158   uint32_t Pre_SchedulerHasCPU_NA : 1;
0159   uint32_t Pre_SchedulerId_NA : 1;
0160   uint32_t Pre_Priority_NA : 1;
0161   uint32_t Pre_HomePriority_NA : 1;
0162   uint32_t Pre_EligiblePriorities_NA : 1;
0163   uint32_t Pre_Pinned_NA : 1;
0164   uint32_t Pre_TaskState_NA : 1;
0165   uint32_t Pre_AffinitySupported_NA : 1;
0166   uint32_t Post_Status : 3;
0167   uint32_t Post_Scheduler : 2;
0168   uint32_t Post_Priority : 2;
0169 } RtemsTaskReqSetScheduler_Entry;
0170 
0171 /**
0172  * @brief Test context for spec:/rtems/task/req/set-scheduler test case.
0173  */
0174 typedef struct {
0175   /**
0176    * @brief This member contains the runner task identifier.
0177    */
0178   rtems_id runner_id;
0179 
0180   /**
0181    * @brief This member contains the scheduler A identifier.
0182    */
0183   rtems_id scheduler_a_id;
0184 
0185   /**
0186    * @brief This member contains the scheduler B identifier.
0187    */
0188   rtems_id scheduler_b_id;
0189 
0190   /**
0191    * @brief This member contains the scheduler D identifier.
0192    */
0193   rtems_id scheduler_d_id;
0194 
0195   /**
0196    * @brief This member contains the worker task identifiers.
0197    */
0198   rtems_id worker_id[ 3 ];
0199 
0200   /**
0201    * @brief This member contains the mutex identifiers.
0202    */
0203   rtems_id mutex_id[ 2 ];
0204 
0205   /**
0206    * @brief If this member is true, then the task shall have an additional
0207    *   priority for the home scheduler.
0208    */
0209   bool additional_home_priority;
0210 
0211   /**
0212    * @brief If this member is true, then the task shall have a second eligible
0213    *   scheduler.
0214    */
0215   bool second_eligible_scheduler;
0216 
0217   /**
0218    * @brief If this member is true, then the task shall be pinned to a
0219    *   processor.
0220    */
0221   bool pinned;
0222 
0223   /**
0224    * @brief If this member is true, then the task shall be blocked.
0225    */
0226   bool blocked;
0227 
0228   /**
0229    * @brief If this member is true, then the task shall be enqueued on a thread
0230    *   queue.
0231    */
0232   bool enqueued;
0233 
0234   /**
0235    * @brief This member specifies the scheduler identifier to set.
0236    */
0237   rtems_id scheduler_to_set_id;
0238 
0239   /**
0240    * @brief If this member is true, then the affinity of the task shall be
0241    *   supported by the scheduler.
0242    */
0243   bool affinity_supported;
0244 
0245   /**
0246    * @brief This member contains the return value of the
0247    *   rtems_task_set_scheduler() call.
0248    */
0249   rtems_status_code status;
0250 
0251   /**
0252    * @brief This member specifies if the ``task_id`` parameter value.
0253    */
0254   rtems_id task_id;
0255 
0256   /**
0257    * @brief This member specifies if the ``scheduler_id`` parameter value.
0258    */
0259   rtems_id scheduler_id;
0260 
0261   /**
0262    * @brief This member specifies if the ``priority`` parameter value.
0263    */
0264   rtems_task_priority priority;
0265 
0266   /**
0267    * @brief This member contains the identifier of the new scheduler.
0268    */
0269   rtems_id new_scheduler;
0270 
0271   /**
0272    * @brief This member contains the new priorities of the task.
0273    */
0274   rtems_task_priority new_priority[ 2 ];
0275 
0276   struct {
0277     /**
0278      * @brief This member defines the pre-condition indices for the next
0279      *   action.
0280      */
0281     size_t pci[ 10 ];
0282 
0283     /**
0284      * @brief This member defines the pre-condition states for the next action.
0285      */
0286     size_t pcs[ 10 ];
0287 
0288     /**
0289      * @brief If this member is true, then the test action loop is executed.
0290      */
0291     bool in_action_loop;
0292 
0293     /**
0294      * @brief This member contains the next transition map index.
0295      */
0296     size_t index;
0297 
0298     /**
0299      * @brief This member contains the current transition map entry.
0300      */
0301     RtemsTaskReqSetScheduler_Entry entry;
0302 
0303     /**
0304      * @brief If this member is true, then the current transition variant
0305      *   should be skipped.
0306      */
0307     bool skip;
0308   } Map;
0309 } RtemsTaskReqSetScheduler_Context;
0310 
0311 static RtemsTaskReqSetScheduler_Context
0312   RtemsTaskReqSetScheduler_Instance;
0313 
0314 static const char * const RtemsTaskReqSetScheduler_PreDesc_TaskId[] = {
0315   "Task",
0316   "Invalid",
0317   "NA"
0318 };
0319 
0320 static const char * const RtemsTaskReqSetScheduler_PreDesc_Scheduler[] = {
0321   "Home",
0322   "Other",
0323   "NA"
0324 };
0325 
0326 static const char * const RtemsTaskReqSetScheduler_PreDesc_SchedulerHasCPU[] = {
0327   "Yes",
0328   "No",
0329   "NA"
0330 };
0331 
0332 static const char * const RtemsTaskReqSetScheduler_PreDesc_SchedulerId[] = {
0333   "Scheduler",
0334   "Invalid",
0335   "NA"
0336 };
0337 
0338 static const char * const RtemsTaskReqSetScheduler_PreDesc_Priority[] = {
0339   "Valid",
0340   "Invalid",
0341   "NA"
0342 };
0343 
0344 static const char * const RtemsTaskReqSetScheduler_PreDesc_HomePriority[] = {
0345   "Real",
0346   "More",
0347   "NA"
0348 };
0349 
0350 static const char * const RtemsTaskReqSetScheduler_PreDesc_EligiblePriorities[] = {
0351   "OnlyOne",
0352   "More",
0353   "NA"
0354 };
0355 
0356 static const char * const RtemsTaskReqSetScheduler_PreDesc_Pinned[] = {
0357   "Yes",
0358   "No",
0359   "NA"
0360 };
0361 
0362 static const char * const RtemsTaskReqSetScheduler_PreDesc_TaskState[] = {
0363   "Ready",
0364   "Blocked",
0365   "Enqueued",
0366   "NA"
0367 };
0368 
0369 static const char * const RtemsTaskReqSetScheduler_PreDesc_AffinitySupported[] = {
0370   "Yes",
0371   "No",
0372   "NA"
0373 };
0374 
0375 static const char * const * const RtemsTaskReqSetScheduler_PreDesc[] = {
0376   RtemsTaskReqSetScheduler_PreDesc_TaskId,
0377   RtemsTaskReqSetScheduler_PreDesc_Scheduler,
0378   RtemsTaskReqSetScheduler_PreDesc_SchedulerHasCPU,
0379   RtemsTaskReqSetScheduler_PreDesc_SchedulerId,
0380   RtemsTaskReqSetScheduler_PreDesc_Priority,
0381   RtemsTaskReqSetScheduler_PreDesc_HomePriority,
0382   RtemsTaskReqSetScheduler_PreDesc_EligiblePriorities,
0383   RtemsTaskReqSetScheduler_PreDesc_Pinned,
0384   RtemsTaskReqSetScheduler_PreDesc_TaskState,
0385   RtemsTaskReqSetScheduler_PreDesc_AffinitySupported,
0386   NULL
0387 };
0388 
0389 typedef RtemsTaskReqSetScheduler_Context Context;
0390 
0391 #define EVENT_OBTAIN_MUTEX_A RTEMS_EVENT_0
0392 
0393 #define EVENT_RELEASE_MUTEX_A RTEMS_EVENT_1
0394 
0395 #define EVENT_OBTAIN_MUTEX_B RTEMS_EVENT_2
0396 
0397 #define EVENT_RELEASE_MUTEX_B RTEMS_EVENT_3
0398 
0399 #define EVENT_PIN RTEMS_EVENT_4
0400 
0401 #define EVENT_UNPIN RTEMS_EVENT_5
0402 
0403 #define EVENT_SET_LOW_PRIO RTEMS_EVENT_6
0404 
0405 #define EVENT_RUNNER_SYNC_0 RTEMS_EVENT_7
0406 
0407 #define EVENT_RUNNER_SYNC_1 RTEMS_EVENT_8
0408 
0409 static void Worker( rtems_task_argument arg )
0410 {
0411   Context        *ctx;
0412   Thread_Control *executing;
0413 
0414   ctx = (Context *) arg;
0415   executing = _Thread_Get_executing();
0416 
0417   while ( true ) {
0418     rtems_event_set events;
0419 
0420     events = ReceiveAnyEvents();
0421 
0422     if ( ( events & EVENT_RUNNER_SYNC_0 ) != 0 ) {
0423       SendEvents( ctx->runner_id, EVENT_RUNNER_SYNC_0 );
0424     }
0425 
0426     if ( ( events & EVENT_OBTAIN_MUTEX_A ) != 0 ) {
0427       ObtainMutex( ctx->mutex_id[ 0 ] );
0428     }
0429 
0430     if ( ( events & EVENT_RELEASE_MUTEX_A ) != 0 ) {
0431       ReleaseMutex( ctx->mutex_id[ 0 ] );
0432     }
0433 
0434     if ( ( events & EVENT_OBTAIN_MUTEX_B ) != 0 ) {
0435       ObtainMutex( ctx->mutex_id[ 1 ] );
0436     }
0437 
0438     if ( ( events & EVENT_RELEASE_MUTEX_B ) != 0 ) {
0439       ReleaseMutex( ctx->mutex_id[ 1 ] );
0440     }
0441 
0442     if ( ( events & EVENT_PIN ) != 0 ) {
0443       _Thread_Pin( executing );
0444     }
0445 
0446     if ( ( events & EVENT_UNPIN ) != 0 ) {
0447       _Thread_Unpin( executing, _Per_CPU_Get_snapshot() );
0448     }
0449 
0450     if ( ( events & EVENT_SET_LOW_PRIO ) != 0 ) {
0451       SetSelfPriority( PRIO_LOW );
0452     }
0453 
0454     if ( ( events & EVENT_RUNNER_SYNC_1 ) != 0 ) {
0455       SendEvents( ctx->runner_id, EVENT_RUNNER_SYNC_1 );
0456     }
0457   }
0458 }
0459 
0460 static void RtemsTaskReqSetScheduler_Pre_TaskId_Prepare(
0461   RtemsTaskReqSetScheduler_Context   *ctx,
0462   RtemsTaskReqSetScheduler_Pre_TaskId state
0463 )
0464 {
0465   switch ( state ) {
0466     case RtemsTaskReqSetScheduler_Pre_TaskId_Task: {
0467       /*
0468        * While the ``task_id`` parameter is associated with a task.
0469        */
0470       ctx->task_id = ctx->worker_id[ 0 ];
0471       break;
0472     }
0473 
0474     case RtemsTaskReqSetScheduler_Pre_TaskId_Invalid: {
0475       /*
0476        * While the ``task_id`` parameter is not associated with a task.
0477        */
0478       ctx->task_id = INVALID_ID;
0479       break;
0480     }
0481 
0482     case RtemsTaskReqSetScheduler_Pre_TaskId_NA:
0483       break;
0484   }
0485 }
0486 
0487 static void RtemsTaskReqSetScheduler_Pre_Scheduler_Prepare(
0488   RtemsTaskReqSetScheduler_Context      *ctx,
0489   RtemsTaskReqSetScheduler_Pre_Scheduler state
0490 )
0491 {
0492   switch ( state ) {
0493     case RtemsTaskReqSetScheduler_Pre_Scheduler_Home: {
0494       /*
0495        * While the scheduler specified by the ``scheduler_id`` parameter is the
0496        * home scheduler of the task specified by the ``task_id`` parameter.
0497        */
0498       ctx->scheduler_to_set_id = ctx->scheduler_a_id;
0499       break;
0500     }
0501 
0502     case RtemsTaskReqSetScheduler_Pre_Scheduler_Other: {
0503       /*
0504        * While the scheduler specified by the ``scheduler_id`` parameter is not
0505        * the home scheduler of the task specified by the ``task_id`` parameter.
0506        */
0507       ctx->scheduler_to_set_id = ctx->scheduler_b_id;
0508       break;
0509     }
0510 
0511     case RtemsTaskReqSetScheduler_Pre_Scheduler_NA:
0512       break;
0513   }
0514 }
0515 
0516 static void RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_Prepare(
0517   RtemsTaskReqSetScheduler_Context            *ctx,
0518   RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU state
0519 )
0520 {
0521   switch ( state ) {
0522     case RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_Yes: {
0523       /*
0524        * While the scheduler specified by the ``scheduler_id`` parameter owns
0525        * at least one processor.
0526        */
0527       /* Already set by Scheduler pre-condition */
0528       break;
0529     }
0530 
0531     case RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_No: {
0532       /*
0533        * While the scheduler specified by the ``scheduler_id`` parameter owns
0534        * no processor.
0535        */
0536       ctx->scheduler_to_set_id = ctx->scheduler_d_id;
0537       break;
0538     }
0539 
0540     case RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_NA:
0541       break;
0542   }
0543 }
0544 
0545 static void RtemsTaskReqSetScheduler_Pre_SchedulerId_Prepare(
0546   RtemsTaskReqSetScheduler_Context        *ctx,
0547   RtemsTaskReqSetScheduler_Pre_SchedulerId state
0548 )
0549 {
0550   switch ( state ) {
0551     case RtemsTaskReqSetScheduler_Pre_SchedulerId_Scheduler: {
0552       /*
0553        * While the ``scheduler_id`` parameter is associated with a scheduler.
0554        */
0555       ctx->scheduler_id = ctx->scheduler_to_set_id;
0556       break;
0557     }
0558 
0559     case RtemsTaskReqSetScheduler_Pre_SchedulerId_Invalid: {
0560       /*
0561        * While the ``scheduler_id`` parameter is not associated with a
0562        * scheduler.
0563        */
0564       ctx->scheduler_id = INVALID_ID;
0565       break;
0566     }
0567 
0568     case RtemsTaskReqSetScheduler_Pre_SchedulerId_NA:
0569       break;
0570   }
0571 }
0572 
0573 static void RtemsTaskReqSetScheduler_Pre_Priority_Prepare(
0574   RtemsTaskReqSetScheduler_Context     *ctx,
0575   RtemsTaskReqSetScheduler_Pre_Priority state
0576 )
0577 {
0578   switch ( state ) {
0579     case RtemsTaskReqSetScheduler_Pre_Priority_Valid: {
0580       /*
0581        * While the task priority specified by the ``priority`` parameter is
0582        * valid with respect to the scheduler specified by the ``scheduler_id``
0583        * parameter.
0584        */
0585       ctx->priority = PRIO_VERY_LOW;
0586       break;
0587     }
0588 
0589     case RtemsTaskReqSetScheduler_Pre_Priority_Invalid: {
0590       /*
0591        * While the task priority specified by the ``priority`` parameter is
0592        * invalid with respect to the scheduler specified by the
0593        * ``scheduler_id`` parameter.
0594        */
0595       ctx->priority = PRIO_INVALID;
0596       break;
0597     }
0598 
0599     case RtemsTaskReqSetScheduler_Pre_Priority_NA:
0600       break;
0601   }
0602 }
0603 
0604 static void RtemsTaskReqSetScheduler_Pre_HomePriority_Prepare(
0605   RtemsTaskReqSetScheduler_Context         *ctx,
0606   RtemsTaskReqSetScheduler_Pre_HomePriority state
0607 )
0608 {
0609   switch ( state ) {
0610     case RtemsTaskReqSetScheduler_Pre_HomePriority_Real: {
0611       /*
0612        * While the current priority of the task specified by the ``task_id``
0613        * parameter consists only of the real priority.
0614        */
0615       ctx->additional_home_priority = false;
0616       break;
0617     }
0618 
0619     case RtemsTaskReqSetScheduler_Pre_HomePriority_More: {
0620       /*
0621        * While the current priority of the task specified by the ``task_id``
0622        * parameter consists of more than the real priority.
0623        */
0624       ctx->additional_home_priority = true;
0625       break;
0626     }
0627 
0628     case RtemsTaskReqSetScheduler_Pre_HomePriority_NA:
0629       break;
0630   }
0631 }
0632 
0633 static void RtemsTaskReqSetScheduler_Pre_EligiblePriorities_Prepare(
0634   RtemsTaskReqSetScheduler_Context               *ctx,
0635   RtemsTaskReqSetScheduler_Pre_EligiblePriorities state
0636 )
0637 {
0638   switch ( state ) {
0639     case RtemsTaskReqSetScheduler_Pre_EligiblePriorities_OnlyOne: {
0640       /*
0641        * While the set of eligible priorities of the task specified by the
0642        * ``task_id`` parameter consists of exactly the current priority.
0643        */
0644       ctx->second_eligible_scheduler = false;
0645       break;
0646     }
0647 
0648     case RtemsTaskReqSetScheduler_Pre_EligiblePriorities_More: {
0649       /*
0650        * While the set of eligible priorities of the task specified by the
0651        * ``task_id`` parameter consists of more than the current priority.
0652        */
0653       ctx->second_eligible_scheduler = true;
0654       break;
0655     }
0656 
0657     case RtemsTaskReqSetScheduler_Pre_EligiblePriorities_NA:
0658       break;
0659   }
0660 }
0661 
0662 static void RtemsTaskReqSetScheduler_Pre_Pinned_Prepare(
0663   RtemsTaskReqSetScheduler_Context   *ctx,
0664   RtemsTaskReqSetScheduler_Pre_Pinned state
0665 )
0666 {
0667   switch ( state ) {
0668     case RtemsTaskReqSetScheduler_Pre_Pinned_Yes: {
0669       /*
0670        * While the task specified by the ``task_id`` parameter is pinned.
0671        */
0672       ctx->pinned = true;
0673       break;
0674     }
0675 
0676     case RtemsTaskReqSetScheduler_Pre_Pinned_No: {
0677       /*
0678        * While the task specified by the ``task_id`` parameter is not pinned.
0679        */
0680       ctx->pinned = false;
0681       break;
0682     }
0683 
0684     case RtemsTaskReqSetScheduler_Pre_Pinned_NA:
0685       break;
0686   }
0687 }
0688 
0689 static void RtemsTaskReqSetScheduler_Pre_TaskState_Prepare(
0690   RtemsTaskReqSetScheduler_Context      *ctx,
0691   RtemsTaskReqSetScheduler_Pre_TaskState state
0692 )
0693 {
0694   switch ( state ) {
0695     case RtemsTaskReqSetScheduler_Pre_TaskState_Ready: {
0696       /*
0697        * While the task specified by the ``task_id`` parameter is ready.
0698        */
0699       ctx->blocked = false;
0700       ctx->enqueued = false;
0701       break;
0702     }
0703 
0704     case RtemsTaskReqSetScheduler_Pre_TaskState_Blocked: {
0705       /*
0706        * While the task specified by the ``task_id`` parameter is blocked,
0707        * while the task specified by the ``task_id`` parameter is not enqueued
0708        * on a wait queue.
0709        */
0710       ctx->blocked = true;
0711       ctx->enqueued = false;
0712       break;
0713     }
0714 
0715     case RtemsTaskReqSetScheduler_Pre_TaskState_Enqueued: {
0716       /*
0717        * While the task specified by the ``task_id`` parameter is blocked,
0718        * while the task specified by the ``task_id`` parameter is enqueued on a
0719        * wait queue.
0720        */
0721       ctx->blocked = true;
0722       ctx->enqueued = true;
0723       break;
0724     }
0725 
0726     case RtemsTaskReqSetScheduler_Pre_TaskState_NA:
0727       break;
0728   }
0729 }
0730 
0731 static void RtemsTaskReqSetScheduler_Pre_AffinitySupported_Prepare(
0732   RtemsTaskReqSetScheduler_Context              *ctx,
0733   RtemsTaskReqSetScheduler_Pre_AffinitySupported state
0734 )
0735 {
0736   switch ( state ) {
0737     case RtemsTaskReqSetScheduler_Pre_AffinitySupported_Yes: {
0738       /*
0739        * While the affinity set of the task specified by the ``task_id``
0740        * parameter is supported by the scheduler specified by the
0741        * ``scheduler_id`` parameter.
0742        */
0743       ctx->affinity_supported = true;
0744       break;
0745     }
0746 
0747     case RtemsTaskReqSetScheduler_Pre_AffinitySupported_No: {
0748       /*
0749        * While the affinity set of the task specified by the ``task_id``
0750        * parameter is not supported by the scheduler specified by the
0751        * ``scheduler_id`` parameter.
0752        */
0753       ctx->affinity_supported = false;
0754       break;
0755     }
0756 
0757     case RtemsTaskReqSetScheduler_Pre_AffinitySupported_NA:
0758       break;
0759   }
0760 }
0761 
0762 static void RtemsTaskReqSetScheduler_Post_Status_Check(
0763   RtemsTaskReqSetScheduler_Context    *ctx,
0764   RtemsTaskReqSetScheduler_Post_Status state
0765 )
0766 {
0767   switch ( state ) {
0768     case RtemsTaskReqSetScheduler_Post_Status_Ok: {
0769       /*
0770        * The return status of rtems_task_set_scheduler() shall be
0771        * RTEMS_SUCCESSFUL.
0772        */
0773       T_rsc_success( ctx->status );
0774       break;
0775     }
0776 
0777     case RtemsTaskReqSetScheduler_Post_Status_InvAddr: {
0778       /*
0779        * The return status of rtems_task_set_scheduler() shall be
0780        * RTEMS_INVALID_ADDRESS.
0781        */
0782       T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
0783       break;
0784     }
0785 
0786     case RtemsTaskReqSetScheduler_Post_Status_InvId: {
0787       /*
0788        * The return status of rtems_task_set_scheduler() shall be
0789        * RTEMS_INVALID_ID.
0790        */
0791       T_rsc( ctx->status, RTEMS_INVALID_ID );
0792       break;
0793     }
0794 
0795     case RtemsTaskReqSetScheduler_Post_Status_InvPrio: {
0796       /*
0797        * The return status of rtems_task_set_scheduler() shall be
0798        * RTEMS_INVALID_PRIORITY.
0799        */
0800       T_rsc( ctx->status, RTEMS_INVALID_PRIORITY );
0801       break;
0802     }
0803 
0804     case RtemsTaskReqSetScheduler_Post_Status_InUse: {
0805       /*
0806        * The return status of rtems_task_set_scheduler() shall be
0807        * RTEMS_RESOURCE_IN_USE.
0808        */
0809       T_rsc( ctx->status, RTEMS_RESOURCE_IN_USE );
0810       break;
0811     }
0812 
0813     case RtemsTaskReqSetScheduler_Post_Status_Unsat: {
0814       /*
0815        * The return status of rtems_task_set_scheduler() shall be
0816        * RTEMS_UNSATISFIED.
0817        */
0818       T_rsc( ctx->status, RTEMS_UNSATISFIED );
0819       break;
0820     }
0821 
0822     case RtemsTaskReqSetScheduler_Post_Status_NA:
0823       break;
0824   }
0825 }
0826 
0827 static void RtemsTaskReqSetScheduler_Post_Scheduler_Check(
0828   RtemsTaskReqSetScheduler_Context       *ctx,
0829   RtemsTaskReqSetScheduler_Post_Scheduler state
0830 )
0831 {
0832   switch ( state ) {
0833     case RtemsTaskReqSetScheduler_Post_Scheduler_Set: {
0834       /*
0835        * The home scheduler of the task specified by the ``task_id`` parameter
0836        * shall be set to the scheduler specified by the ``scheduler_id``
0837        * parameter at some point during the rtems_task_set_scheduler() call.
0838        */
0839       T_eq_u32( ctx->new_scheduler, ctx->scheduler_to_set_id );
0840       break;
0841     }
0842 
0843     case RtemsTaskReqSetScheduler_Post_Scheduler_Nop: {
0844       /*
0845        * No home scheduler of a task shall be modified by the
0846        * rtems_task_set_scheduler() call.
0847        */
0848       T_eq_u32( ctx->new_scheduler, ctx->scheduler_a_id );
0849       break;
0850     }
0851 
0852     case RtemsTaskReqSetScheduler_Post_Scheduler_NA:
0853       break;
0854   }
0855 }
0856 
0857 static void RtemsTaskReqSetScheduler_Post_Priority_Check(
0858   RtemsTaskReqSetScheduler_Context      *ctx,
0859   RtemsTaskReqSetScheduler_Post_Priority state
0860 )
0861 {
0862   switch ( state ) {
0863     case RtemsTaskReqSetScheduler_Post_Priority_Set: {
0864       /*
0865        * The real priority of the task specified by the ``task_id`` parameter
0866        * shall be set to the priority specified by the ``priority`` parameter
0867        * at some point during the rtems_task_set_scheduler() call.
0868        */
0869       if ( ctx->scheduler_to_set_id == ctx->scheduler_a_id ) {
0870         T_eq_u32( ctx->new_priority[ 0 ], PRIO_VERY_LOW );
0871         T_eq_u32( ctx->new_priority[ 1 ], PRIO_INVALID );
0872       } else {
0873         T_eq_u32( ctx->new_priority[ 0 ], PRIO_INVALID );
0874         T_eq_u32( ctx->new_priority[ 1 ], PRIO_VERY_LOW );
0875       }
0876       break;
0877     }
0878 
0879     case RtemsTaskReqSetScheduler_Post_Priority_Nop: {
0880       /*
0881        * No task priority shall be modified by the rtems_task_set_scheduler()
0882        * call.
0883        */
0884       if ( ctx->blocked ) {
0885         T_eq_u32( ctx->new_priority[ 0 ], PRIO_HIGH );
0886       } else {
0887         T_eq_u32( ctx->new_priority[ 0 ], PRIO_LOW );
0888       }
0889 
0890       T_eq_u32( ctx->new_priority[ 1 ], PRIO_INVALID );
0891       break;
0892     }
0893 
0894     case RtemsTaskReqSetScheduler_Post_Priority_NA:
0895       break;
0896   }
0897 }
0898 
0899 static void RtemsTaskReqSetScheduler_Setup(
0900   RtemsTaskReqSetScheduler_Context *ctx
0901 )
0902 {
0903   rtems_status_code sc;
0904   size_t            i;
0905 
0906   memset( ctx, 0, sizeof( *ctx ) );
0907   ctx->runner_id = rtems_task_self();
0908   SetSelfPriority( PRIO_NORMAL );
0909 
0910   sc = rtems_scheduler_ident(
0911     TEST_SCHEDULER_A_NAME,
0912     &ctx->scheduler_a_id
0913   );
0914   T_rsc_success( sc );
0915 
0916   for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->mutex_id ); ++i ) {
0917     ctx->mutex_id[ i ] = CreateMutex();
0918   }
0919 
0920   for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->worker_id ); ++i ) {
0921     ctx->worker_id[ i ] = CreateTask( "WORK", PRIO_HIGH - i );
0922     StartTask( ctx->worker_id[ i ], Worker, ctx );
0923   }
0924 
0925   #if defined(RTEMS_SMP)
0926   sc = rtems_scheduler_ident( TEST_SCHEDULER_B_NAME, &ctx->scheduler_b_id );
0927   T_rsc_success( sc );
0928 
0929   sc = rtems_scheduler_ident( TEST_SCHEDULER_D_NAME, &ctx->scheduler_d_id );
0930   T_rsc_success( sc );
0931 
0932   SetScheduler( ctx->worker_id[ 2 ], ctx->scheduler_b_id, PRIO_NORMAL );
0933   #else
0934   ctx->scheduler_b_id = INVALID_ID;
0935   #endif
0936 }
0937 
0938 static void RtemsTaskReqSetScheduler_Setup_Wrap( void *arg )
0939 {
0940   RtemsTaskReqSetScheduler_Context *ctx;
0941 
0942   ctx = arg;
0943   ctx->Map.in_action_loop = false;
0944   RtemsTaskReqSetScheduler_Setup( ctx );
0945 }
0946 
0947 static void RtemsTaskReqSetScheduler_Teardown(
0948   RtemsTaskReqSetScheduler_Context *ctx
0949 )
0950 {
0951   size_t i;
0952 
0953   for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->worker_id ); ++i ) {
0954     DeleteTask( ctx->worker_id[ i ] );
0955   }
0956 
0957   for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->mutex_id ); ++i ) {
0958     DeleteMutex( ctx->mutex_id[ i ] );
0959   }
0960 
0961   RestoreRunnerPriority();
0962 }
0963 
0964 static void RtemsTaskReqSetScheduler_Teardown_Wrap( void *arg )
0965 {
0966   RtemsTaskReqSetScheduler_Context *ctx;
0967 
0968   ctx = arg;
0969   ctx->Map.in_action_loop = false;
0970   RtemsTaskReqSetScheduler_Teardown( ctx );
0971 }
0972 
0973 static void RtemsTaskReqSetScheduler_Action(
0974   RtemsTaskReqSetScheduler_Context *ctx
0975 )
0976 {
0977   rtems_status_code sc;
0978 
0979   if ( ctx->additional_home_priority || ctx->second_eligible_scheduler ) {
0980     SendEvents( ctx->worker_id[ 0 ], EVENT_OBTAIN_MUTEX_A );
0981 
0982     if ( ctx->additional_home_priority ) {
0983       SendEvents( ctx->worker_id[ 1 ], EVENT_OBTAIN_MUTEX_A );
0984     }
0985 
0986     if ( ctx->second_eligible_scheduler ) {
0987       SendEvents(
0988         ctx->worker_id[ 2 ],
0989         EVENT_RUNNER_SYNC_0 | EVENT_OBTAIN_MUTEX_A
0990       );
0991       ReceiveAllEvents( EVENT_RUNNER_SYNC_0 );
0992       WaitForExecutionStop( ctx->worker_id[ 2 ] );
0993     }
0994   }
0995 
0996   if ( ctx->blocked && ctx->enqueued ) {
0997     ObtainMutex( ctx->mutex_id[ 1 ] );
0998     SendEvents( ctx->worker_id[ 0 ], EVENT_OBTAIN_MUTEX_B );
0999   }
1000 
1001   if ( !ctx->affinity_supported ) {
1002     SetAffinityOne( ctx->worker_id[ 0 ], 0 );
1003   }
1004 
1005   if ( ctx->pinned ) {
1006     SendEvents( ctx->worker_id[ 0 ], EVENT_PIN );
1007   }
1008 
1009   if ( !ctx->blocked ) {
1010     SendEvents( ctx->worker_id[ 0 ], EVENT_SET_LOW_PRIO );
1011   }
1012 
1013   ctx->status = rtems_task_set_scheduler(
1014     ctx->task_id,
1015     ctx->scheduler_id,
1016     ctx->priority
1017   );
1018 
1019   ctx->new_scheduler = GetScheduler( ctx->worker_id[ 0 ] );
1020 
1021   if ( ctx->pinned ) {
1022     SendEvents( ctx->worker_id[ 0 ], EVENT_UNPIN );
1023   }
1024 
1025   if ( !ctx->affinity_supported ) {
1026     SetAffinityAll( ctx->worker_id[ 0 ] );
1027   }
1028 
1029   if ( ctx->blocked && ctx->enqueued ) {
1030     ReleaseMutex( ctx->mutex_id[ 1 ] );
1031     SendEvents( ctx->worker_id[ 0 ], EVENT_RELEASE_MUTEX_B );
1032   }
1033 
1034   if ( ctx->additional_home_priority || ctx->second_eligible_scheduler ) {
1035     SendEvents( ctx->worker_id[ 0 ], EVENT_RELEASE_MUTEX_A );
1036 
1037     if ( ctx->additional_home_priority ) {
1038       SendEvents( ctx->worker_id[ 1 ], EVENT_RELEASE_MUTEX_A );
1039     }
1040 
1041     if ( ctx->second_eligible_scheduler ) {
1042       SendEvents(
1043         ctx->worker_id[ 2 ],
1044         EVENT_RELEASE_MUTEX_A | EVENT_RUNNER_SYNC_1
1045       );
1046       ReceiveAllEvents( EVENT_RUNNER_SYNC_1 );
1047     }
1048   }
1049 
1050   sc = rtems_task_get_priority(
1051     ctx->worker_id[ 0 ],
1052     ctx->scheduler_a_id,
1053     &ctx->new_priority[ 0 ]
1054   );
1055 
1056   if ( sc == RTEMS_NOT_DEFINED ) {
1057     ctx->new_priority[ 0 ] = PRIO_INVALID;
1058   } else {
1059     T_rsc_success( sc );
1060   }
1061 
1062   #if defined(RTEMS_SMP)
1063   sc = rtems_task_get_priority(
1064     ctx->worker_id[ 0 ],
1065     ctx->scheduler_b_id,
1066     &ctx->new_priority[ 1 ]
1067   );
1068 
1069   if ( sc == RTEMS_NOT_DEFINED ) {
1070     ctx->new_priority[ 1 ] = PRIO_INVALID;
1071   } else {
1072     T_rsc_success( sc );
1073   }
1074   #else
1075   ctx->new_priority[ 1 ] = PRIO_INVALID;
1076   #endif
1077 
1078   if ( ctx->status == RTEMS_SUCCESSFUL ) {
1079     SetScheduler( ctx->worker_id[ 0 ], ctx->scheduler_a_id, PRIO_HIGH );
1080   } else if ( !ctx->blocked ) {
1081     SetPriority( ctx->worker_id[ 0 ], PRIO_HIGH );
1082   }
1083 }
1084 
1085 static const RtemsTaskReqSetScheduler_Entry
1086 RtemsTaskReqSetScheduler_Entries[] = {
1087 #if !defined(RTEMS_SMP)
1088   { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
1089     RtemsTaskReqSetScheduler_Post_Scheduler_NA,
1090     RtemsTaskReqSetScheduler_Post_Priority_NA },
1091 #else
1092   { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
1093     RtemsTaskReqSetScheduler_Post_Scheduler_NA,
1094     RtemsTaskReqSetScheduler_Post_Priority_NA },
1095 #endif
1096 #if !defined(RTEMS_SMP)
1097   { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
1098     RtemsTaskReqSetScheduler_Post_Scheduler_NA,
1099     RtemsTaskReqSetScheduler_Post_Priority_NA },
1100 #else
1101   { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1,
1102     RtemsTaskReqSetScheduler_Post_Status_InvId,
1103     RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
1104     RtemsTaskReqSetScheduler_Post_Priority_Nop },
1105 #endif
1106 #if !defined(RTEMS_SMP)
1107   { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
1108     RtemsTaskReqSetScheduler_Post_Scheduler_NA,
1109     RtemsTaskReqSetScheduler_Post_Priority_NA },
1110 #else
1111   { 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1,
1112     RtemsTaskReqSetScheduler_Post_Status_InvId,
1113     RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
1114     RtemsTaskReqSetScheduler_Post_Priority_Nop },
1115 #endif
1116   { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
1117     RtemsTaskReqSetScheduler_Post_Scheduler_NA,
1118     RtemsTaskReqSetScheduler_Post_Priority_NA },
1119 #if !defined(RTEMS_SMP)
1120   { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
1121     RtemsTaskReqSetScheduler_Post_Scheduler_NA,
1122     RtemsTaskReqSetScheduler_Post_Priority_NA },
1123 #else
1124   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1125     RtemsTaskReqSetScheduler_Post_Status_InvPrio,
1126     RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
1127     RtemsTaskReqSetScheduler_Post_Priority_Nop },
1128 #endif
1129 #if !defined(RTEMS_SMP)
1130   { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
1131     RtemsTaskReqSetScheduler_Post_Scheduler_NA,
1132     RtemsTaskReqSetScheduler_Post_Priority_NA },
1133 #else
1134   { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
1135     RtemsTaskReqSetScheduler_Post_Status_InvId,
1136     RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
1137     RtemsTaskReqSetScheduler_Post_Priority_Nop },
1138 #endif
1139 #if !defined(RTEMS_SMP)
1140   { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
1141     RtemsTaskReqSetScheduler_Post_Scheduler_NA,
1142     RtemsTaskReqSetScheduler_Post_Priority_NA },
1143 #else
1144   { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
1145     RtemsTaskReqSetScheduler_Post_Status_InvPrio,
1146     RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
1147     RtemsTaskReqSetScheduler_Post_Priority_Nop },
1148 #endif
1149 #if !defined(RTEMS_SMP)
1150   { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
1151     RtemsTaskReqSetScheduler_Post_Scheduler_NA,
1152     RtemsTaskReqSetScheduler_Post_Priority_NA },
1153 #else
1154   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1155     RtemsTaskReqSetScheduler_Post_Status_InUse,
1156     RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
1157     RtemsTaskReqSetScheduler_Post_Priority_Nop },
1158 #endif
1159   { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1,
1160     RtemsTaskReqSetScheduler_Post_Status_InvId,
1161     RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
1162     RtemsTaskReqSetScheduler_Post_Priority_Nop },
1163   { 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1,
1164     RtemsTaskReqSetScheduler_Post_Status_InvId,
1165     RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
1166     RtemsTaskReqSetScheduler_Post_Priority_Nop },
1167   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1168     RtemsTaskReqSetScheduler_Post_Status_InvPrio,
1169     RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
1170     RtemsTaskReqSetScheduler_Post_Priority_Nop },
1171 #if !defined(RTEMS_SMP)
1172   { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
1173     RtemsTaskReqSetScheduler_Post_Scheduler_NA,
1174     RtemsTaskReqSetScheduler_Post_Priority_NA },
1175 #else
1176   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1177     RtemsTaskReqSetScheduler_Post_Status_Unsat,
1178     RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
1179     RtemsTaskReqSetScheduler_Post_Priority_Nop },
1180 #endif
1181   { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
1182     RtemsTaskReqSetScheduler_Post_Status_InvId,
1183     RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
1184     RtemsTaskReqSetScheduler_Post_Priority_Nop },
1185   { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
1186     RtemsTaskReqSetScheduler_Post_Status_InvPrio,
1187     RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
1188     RtemsTaskReqSetScheduler_Post_Priority_Nop },
1189   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1190     RtemsTaskReqSetScheduler_Post_Status_InUse,
1191     RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
1192     RtemsTaskReqSetScheduler_Post_Priority_Nop },
1193   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_Ok,
1194     RtemsTaskReqSetScheduler_Post_Scheduler_Set,
1195     RtemsTaskReqSetScheduler_Post_Priority_Set },
1196 #if !defined(RTEMS_SMP)
1197   { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
1198     RtemsTaskReqSetScheduler_Post_Scheduler_NA,
1199     RtemsTaskReqSetScheduler_Post_Priority_NA }
1200 #else
1201   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_Ok,
1202     RtemsTaskReqSetScheduler_Post_Scheduler_Set,
1203     RtemsTaskReqSetScheduler_Post_Priority_Set }
1204 #endif
1205 };
1206 
1207 static const uint8_t
1208 RtemsTaskReqSetScheduler_Map[] = {
1209   7, 0, 7, 0, 7, 0, 15, 3, 15, 3, 14, 3, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7,
1210   0, 7, 0, 7, 0, 14, 3, 14, 3, 14, 3, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 4, 0,
1211   4, 0, 4, 0, 10, 3, 10, 3, 10, 3, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4,
1212   0, 4, 0, 10, 3, 10, 3, 10, 3, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 1, 0, 1, 0,
1213   1, 0, 8, 3, 8, 3, 8, 3, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1214   8, 3, 8, 3, 8, 3, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 8, 3,
1215   8, 3, 8, 3, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 8, 3, 8, 3,
1216   8, 3, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3,
1217   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0,
1218   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0,
1219   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0,
1220   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0,
1221   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1222   0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1223   0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7,
1224   7, 7, 7, 7, 16, 11, 16, 11, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1225   7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4,
1226   4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
1227   4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1,
1228   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1229   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1230   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1231   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7, 7, 7, 7, 7, 11, 11, 11, 11, 7, 7, 7, 7,
1232   7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1233   7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
1234   4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
1235   4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1236   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1237   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1238   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 0, 5, 0,
1239   5, 0, 12, 3, 12, 3, 12, 3, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5,
1240   0, 12, 3, 12, 3, 12, 3, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 6, 0, 6, 0, 6, 0,
1241   13, 3, 13, 3, 13, 3, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0,
1242   13, 3, 13, 3, 13, 3, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 2, 0, 2, 0, 2, 0, 9,
1243   3, 9, 3, 9, 3, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 9, 3, 9,
1244   3, 9, 3, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 9, 3, 9, 3, 9,
1245   3, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 9, 3, 9, 3, 9, 3, 2,
1246   0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0,
1247   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0,
1248   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0,
1249   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1250   0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1251   0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1252   0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1253   0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5,
1254   5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
1255   5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1256   6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1257   6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1258   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1259   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1260   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1261   2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
1262   5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
1263   5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1264   6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2,
1265   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1266   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1267   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1268   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
1269 };
1270 
1271 static size_t RtemsTaskReqSetScheduler_Scope( void *arg, char *buf, size_t n )
1272 {
1273   RtemsTaskReqSetScheduler_Context *ctx;
1274 
1275   ctx = arg;
1276 
1277   if ( ctx->Map.in_action_loop ) {
1278     return T_get_scope(
1279       RtemsTaskReqSetScheduler_PreDesc,
1280       buf,
1281       n,
1282       ctx->Map.pcs
1283     );
1284   }
1285 
1286   return 0;
1287 }
1288 
1289 static T_fixture RtemsTaskReqSetScheduler_Fixture = {
1290   .setup = RtemsTaskReqSetScheduler_Setup_Wrap,
1291   .stop = NULL,
1292   .teardown = RtemsTaskReqSetScheduler_Teardown_Wrap,
1293   .scope = RtemsTaskReqSetScheduler_Scope,
1294   .initial_context = &RtemsTaskReqSetScheduler_Instance
1295 };
1296 
1297 static inline RtemsTaskReqSetScheduler_Entry RtemsTaskReqSetScheduler_PopEntry(
1298   RtemsTaskReqSetScheduler_Context *ctx
1299 )
1300 {
1301   size_t index;
1302 
1303   index = ctx->Map.index;
1304   ctx->Map.index = index + 1;
1305   return RtemsTaskReqSetScheduler_Entries[
1306     RtemsTaskReqSetScheduler_Map[ index ]
1307   ];
1308 }
1309 
1310 static void RtemsTaskReqSetScheduler_SetPreConditionStates(
1311   RtemsTaskReqSetScheduler_Context *ctx
1312 )
1313 {
1314   ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
1315 
1316   if ( ctx->Map.entry.Pre_Scheduler_NA ) {
1317     ctx->Map.pcs[ 1 ] = RtemsTaskReqSetScheduler_Pre_Scheduler_NA;
1318   } else {
1319     ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
1320   }
1321 
1322   if ( ctx->Map.entry.Pre_SchedulerHasCPU_NA ) {
1323     ctx->Map.pcs[ 2 ] = RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_NA;
1324   } else {
1325     ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
1326   }
1327 
1328   ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
1329 
1330   if ( ctx->Map.entry.Pre_Priority_NA ) {
1331     ctx->Map.pcs[ 4 ] = RtemsTaskReqSetScheduler_Pre_Priority_NA;
1332   } else {
1333     ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
1334   }
1335 
1336   if ( ctx->Map.entry.Pre_HomePriority_NA ) {
1337     ctx->Map.pcs[ 5 ] = RtemsTaskReqSetScheduler_Pre_HomePriority_NA;
1338   } else {
1339     ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
1340   }
1341 
1342   if ( ctx->Map.entry.Pre_EligiblePriorities_NA ) {
1343     ctx->Map.pcs[ 6 ] = RtemsTaskReqSetScheduler_Pre_EligiblePriorities_NA;
1344   } else {
1345     ctx->Map.pcs[ 6 ] = ctx->Map.pci[ 6 ];
1346   }
1347 
1348   if ( ctx->Map.entry.Pre_Pinned_NA ) {
1349     ctx->Map.pcs[ 7 ] = RtemsTaskReqSetScheduler_Pre_Pinned_NA;
1350   } else {
1351     ctx->Map.pcs[ 7 ] = ctx->Map.pci[ 7 ];
1352   }
1353 
1354   if ( ctx->Map.entry.Pre_TaskState_NA ) {
1355     ctx->Map.pcs[ 8 ] = RtemsTaskReqSetScheduler_Pre_TaskState_NA;
1356   } else {
1357     ctx->Map.pcs[ 8 ] = ctx->Map.pci[ 8 ];
1358   }
1359 
1360   if ( ctx->Map.entry.Pre_AffinitySupported_NA ) {
1361     ctx->Map.pcs[ 9 ] = RtemsTaskReqSetScheduler_Pre_AffinitySupported_NA;
1362   } else {
1363     ctx->Map.pcs[ 9 ] = ctx->Map.pci[ 9 ];
1364   }
1365 }
1366 
1367 static void RtemsTaskReqSetScheduler_TestVariant(
1368   RtemsTaskReqSetScheduler_Context *ctx
1369 )
1370 {
1371   RtemsTaskReqSetScheduler_Pre_TaskId_Prepare( ctx, ctx->Map.pcs[ 0 ] );
1372   RtemsTaskReqSetScheduler_Pre_Scheduler_Prepare( ctx, ctx->Map.pcs[ 1 ] );
1373   RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_Prepare(
1374     ctx,
1375     ctx->Map.pcs[ 2 ]
1376   );
1377   RtemsTaskReqSetScheduler_Pre_SchedulerId_Prepare( ctx, ctx->Map.pcs[ 3 ] );
1378   RtemsTaskReqSetScheduler_Pre_Priority_Prepare( ctx, ctx->Map.pcs[ 4 ] );
1379   RtemsTaskReqSetScheduler_Pre_HomePriority_Prepare( ctx, ctx->Map.pcs[ 5 ] );
1380   RtemsTaskReqSetScheduler_Pre_EligiblePriorities_Prepare(
1381     ctx,
1382     ctx->Map.pcs[ 6 ]
1383   );
1384   RtemsTaskReqSetScheduler_Pre_Pinned_Prepare( ctx, ctx->Map.pcs[ 7 ] );
1385   RtemsTaskReqSetScheduler_Pre_TaskState_Prepare( ctx, ctx->Map.pcs[ 8 ] );
1386   RtemsTaskReqSetScheduler_Pre_AffinitySupported_Prepare(
1387     ctx,
1388     ctx->Map.pcs[ 9 ]
1389   );
1390   RtemsTaskReqSetScheduler_Action( ctx );
1391   RtemsTaskReqSetScheduler_Post_Status_Check(
1392     ctx,
1393     ctx->Map.entry.Post_Status
1394   );
1395   RtemsTaskReqSetScheduler_Post_Scheduler_Check(
1396     ctx,
1397     ctx->Map.entry.Post_Scheduler
1398   );
1399   RtemsTaskReqSetScheduler_Post_Priority_Check(
1400     ctx,
1401     ctx->Map.entry.Post_Priority
1402   );
1403 }
1404 
1405 /**
1406  * @fn void T_case_body_RtemsTaskReqSetScheduler( void )
1407  */
1408 T_TEST_CASE_FIXTURE(
1409   RtemsTaskReqSetScheduler,
1410   &RtemsTaskReqSetScheduler_Fixture
1411 )
1412 {
1413   RtemsTaskReqSetScheduler_Context *ctx;
1414 
1415   ctx = T_fixture_context();
1416   ctx->Map.in_action_loop = true;
1417   ctx->Map.index = 0;
1418 
1419   for (
1420     ctx->Map.pci[ 0 ] = RtemsTaskReqSetScheduler_Pre_TaskId_Task;
1421     ctx->Map.pci[ 0 ] < RtemsTaskReqSetScheduler_Pre_TaskId_NA;
1422     ++ctx->Map.pci[ 0 ]
1423   ) {
1424     for (
1425       ctx->Map.pci[ 1 ] = RtemsTaskReqSetScheduler_Pre_Scheduler_Home;
1426       ctx->Map.pci[ 1 ] < RtemsTaskReqSetScheduler_Pre_Scheduler_NA;
1427       ++ctx->Map.pci[ 1 ]
1428     ) {
1429       for (
1430         ctx->Map.pci[ 2 ] = RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_Yes;
1431         ctx->Map.pci[ 2 ] < RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_NA;
1432         ++ctx->Map.pci[ 2 ]
1433       ) {
1434         for (
1435           ctx->Map.pci[ 3 ] = RtemsTaskReqSetScheduler_Pre_SchedulerId_Scheduler;
1436           ctx->Map.pci[ 3 ] < RtemsTaskReqSetScheduler_Pre_SchedulerId_NA;
1437           ++ctx->Map.pci[ 3 ]
1438         ) {
1439           for (
1440             ctx->Map.pci[ 4 ] = RtemsTaskReqSetScheduler_Pre_Priority_Valid;
1441             ctx->Map.pci[ 4 ] < RtemsTaskReqSetScheduler_Pre_Priority_NA;
1442             ++ctx->Map.pci[ 4 ]
1443           ) {
1444             for (
1445               ctx->Map.pci[ 5 ] = RtemsTaskReqSetScheduler_Pre_HomePriority_Real;
1446               ctx->Map.pci[ 5 ] < RtemsTaskReqSetScheduler_Pre_HomePriority_NA;
1447               ++ctx->Map.pci[ 5 ]
1448             ) {
1449               for (
1450                 ctx->Map.pci[ 6 ] = RtemsTaskReqSetScheduler_Pre_EligiblePriorities_OnlyOne;
1451                 ctx->Map.pci[ 6 ] < RtemsTaskReqSetScheduler_Pre_EligiblePriorities_NA;
1452                 ++ctx->Map.pci[ 6 ]
1453               ) {
1454                 for (
1455                   ctx->Map.pci[ 7 ] = RtemsTaskReqSetScheduler_Pre_Pinned_Yes;
1456                   ctx->Map.pci[ 7 ] < RtemsTaskReqSetScheduler_Pre_Pinned_NA;
1457                   ++ctx->Map.pci[ 7 ]
1458                 ) {
1459                   for (
1460                     ctx->Map.pci[ 8 ] = RtemsTaskReqSetScheduler_Pre_TaskState_Ready;
1461                     ctx->Map.pci[ 8 ] < RtemsTaskReqSetScheduler_Pre_TaskState_NA;
1462                     ++ctx->Map.pci[ 8 ]
1463                   ) {
1464                     for (
1465                       ctx->Map.pci[ 9 ] = RtemsTaskReqSetScheduler_Pre_AffinitySupported_Yes;
1466                       ctx->Map.pci[ 9 ] < RtemsTaskReqSetScheduler_Pre_AffinitySupported_NA;
1467                       ++ctx->Map.pci[ 9 ]
1468                     ) {
1469                       ctx->Map.entry = RtemsTaskReqSetScheduler_PopEntry(
1470                         ctx
1471                       );
1472 
1473                       if ( ctx->Map.entry.Skip ) {
1474                         continue;
1475                       }
1476 
1477                       RtemsTaskReqSetScheduler_SetPreConditionStates( ctx );
1478                       RtemsTaskReqSetScheduler_TestVariant( ctx );
1479                     }
1480                   }
1481                 }
1482               }
1483             }
1484           }
1485         }
1486       }
1487     }
1488   }
1489 }
1490 
1491 /** @} */