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 RtemsTaskReqSuspend
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 
0057 #include "tx-support.h"
0058 
0059 #include <rtems/test.h>
0060 
0061 /**
0062  * @defgroup RtemsTaskReqSuspend spec:/rtems/task/req/suspend
0063  *
0064  * @ingroup TestsuitesValidationNoClock0
0065  *
0066  * @{
0067  */
0068 
0069 typedef enum {
0070   RtemsTaskReqSuspend_Pre_Id_Invalid,
0071   RtemsTaskReqSuspend_Pre_Id_Task,
0072   RtemsTaskReqSuspend_Pre_Id_NA
0073 } RtemsTaskReqSuspend_Pre_Id;
0074 
0075 typedef enum {
0076   RtemsTaskReqSuspend_Pre_Suspended_Yes,
0077   RtemsTaskReqSuspend_Pre_Suspended_No,
0078   RtemsTaskReqSuspend_Pre_Suspended_NA
0079 } RtemsTaskReqSuspend_Pre_Suspended;
0080 
0081 typedef enum {
0082   RtemsTaskReqSuspend_Post_Status_Ok,
0083   RtemsTaskReqSuspend_Post_Status_InvId,
0084   RtemsTaskReqSuspend_Post_Status_AlrdySus,
0085   RtemsTaskReqSuspend_Post_Status_NA
0086 } RtemsTaskReqSuspend_Post_Status;
0087 
0088 typedef struct {
0089   uint8_t Skip : 1;
0090   uint8_t Pre_Id_NA : 1;
0091   uint8_t Pre_Suspended_NA : 1;
0092   uint8_t Post_Status : 2;
0093 } RtemsTaskReqSuspend_Entry;
0094 
0095 /**
0096  * @brief Test context for spec:/rtems/task/req/suspend test case.
0097  */
0098 typedef struct {
0099   /**
0100    * @brief This member contains the identifier of a task.
0101    */
0102   rtems_id worker_id;
0103 
0104   /**
0105    * @brief If this member is true, then the worker is suspended before the
0106    *   rtems_task_suspend() call.
0107    */
0108   bool suspend;
0109 
0110   /**
0111    * @brief This member contains the return value of the rtems_task_suspend()
0112    *   call.
0113    */
0114   rtems_status_code status;
0115 
0116   /**
0117    * @brief This member specifies if the ``id`` parameter value.
0118    */
0119   rtems_id id;
0120 
0121   struct {
0122     /**
0123      * @brief This member defines the pre-condition indices for the next
0124      *   action.
0125      */
0126     size_t pci[ 2 ];
0127 
0128     /**
0129      * @brief This member defines the pre-condition states for the next action.
0130      */
0131     size_t pcs[ 2 ];
0132 
0133     /**
0134      * @brief If this member is true, then the test action loop is executed.
0135      */
0136     bool in_action_loop;
0137 
0138     /**
0139      * @brief This member contains the next transition map index.
0140      */
0141     size_t index;
0142 
0143     /**
0144      * @brief This member contains the current transition map entry.
0145      */
0146     RtemsTaskReqSuspend_Entry entry;
0147 
0148     /**
0149      * @brief If this member is true, then the current transition variant
0150      *   should be skipped.
0151      */
0152     bool skip;
0153   } Map;
0154 } RtemsTaskReqSuspend_Context;
0155 
0156 static RtemsTaskReqSuspend_Context
0157   RtemsTaskReqSuspend_Instance;
0158 
0159 static const char * const RtemsTaskReqSuspend_PreDesc_Id[] = {
0160   "Invalid",
0161   "Task",
0162   "NA"
0163 };
0164 
0165 static const char * const RtemsTaskReqSuspend_PreDesc_Suspended[] = {
0166   "Yes",
0167   "No",
0168   "NA"
0169 };
0170 
0171 static const char * const * const RtemsTaskReqSuspend_PreDesc[] = {
0172   RtemsTaskReqSuspend_PreDesc_Id,
0173   RtemsTaskReqSuspend_PreDesc_Suspended,
0174   NULL
0175 };
0176 
0177 static void Worker( rtems_task_argument arg )
0178 {
0179   while ( true ) {
0180     /* Do nothing */
0181   }
0182 }
0183 
0184 static void RtemsTaskReqSuspend_Pre_Id_Prepare(
0185   RtemsTaskReqSuspend_Context *ctx,
0186   RtemsTaskReqSuspend_Pre_Id   state
0187 )
0188 {
0189   switch ( state ) {
0190     case RtemsTaskReqSuspend_Pre_Id_Invalid: {
0191       /*
0192        * While the ``id`` parameter is not associated with a task.
0193        */
0194       ctx->id = INVALID_ID;
0195       break;
0196     }
0197 
0198     case RtemsTaskReqSuspend_Pre_Id_Task: {
0199       /*
0200        * While the ``id`` parameter is associated with a task.
0201        */
0202       ctx->id = ctx->worker_id;
0203       break;
0204     }
0205 
0206     case RtemsTaskReqSuspend_Pre_Id_NA:
0207       break;
0208   }
0209 }
0210 
0211 static void RtemsTaskReqSuspend_Pre_Suspended_Prepare(
0212   RtemsTaskReqSuspend_Context      *ctx,
0213   RtemsTaskReqSuspend_Pre_Suspended state
0214 )
0215 {
0216   switch ( state ) {
0217     case RtemsTaskReqSuspend_Pre_Suspended_Yes: {
0218       /*
0219        * While the task specified by the ``id`` parameter is suspended.
0220        */
0221       ctx->suspend = true;
0222       break;
0223     }
0224 
0225     case RtemsTaskReqSuspend_Pre_Suspended_No: {
0226       /*
0227        * While the task specified by the ``id`` parameter is not suspended.
0228        */
0229       ctx->suspend = false;
0230       break;
0231     }
0232 
0233     case RtemsTaskReqSuspend_Pre_Suspended_NA:
0234       break;
0235   }
0236 }
0237 
0238 static void RtemsTaskReqSuspend_Post_Status_Check(
0239   RtemsTaskReqSuspend_Context    *ctx,
0240   RtemsTaskReqSuspend_Post_Status state
0241 )
0242 {
0243   switch ( state ) {
0244     case RtemsTaskReqSuspend_Post_Status_Ok: {
0245       /*
0246        * The return status of rtems_task_suspend() shall be RTEMS_SUCCESSFUL.
0247        */
0248       T_rsc_success( ctx->status );
0249       break;
0250     }
0251 
0252     case RtemsTaskReqSuspend_Post_Status_InvId: {
0253       /*
0254        * The return status of rtems_task_suspend() shall be RTEMS_INVALID_ID.
0255        */
0256       T_rsc( ctx->status, RTEMS_INVALID_ID );
0257       break;
0258     }
0259 
0260     case RtemsTaskReqSuspend_Post_Status_AlrdySus: {
0261       /*
0262        * The return status of rtems_task_suspend() shall be
0263        * RTEMS_ALREADY_SUSPENDED.
0264        */
0265       T_rsc( ctx->status, RTEMS_ALREADY_SUSPENDED );
0266       break;
0267     }
0268 
0269     case RtemsTaskReqSuspend_Post_Status_NA:
0270       break;
0271   }
0272 }
0273 
0274 static void RtemsTaskReqSuspend_Setup( RtemsTaskReqSuspend_Context *ctx )
0275 {
0276   ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
0277   StartTask( ctx->worker_id, Worker, ctx );
0278 }
0279 
0280 static void RtemsTaskReqSuspend_Setup_Wrap( void *arg )
0281 {
0282   RtemsTaskReqSuspend_Context *ctx;
0283 
0284   ctx = arg;
0285   ctx->Map.in_action_loop = false;
0286   RtemsTaskReqSuspend_Setup( ctx );
0287 }
0288 
0289 static void RtemsTaskReqSuspend_Teardown( RtemsTaskReqSuspend_Context *ctx )
0290 {
0291   DeleteTask( ctx->worker_id );
0292 }
0293 
0294 static void RtemsTaskReqSuspend_Teardown_Wrap( void *arg )
0295 {
0296   RtemsTaskReqSuspend_Context *ctx;
0297 
0298   ctx = arg;
0299   ctx->Map.in_action_loop = false;
0300   RtemsTaskReqSuspend_Teardown( ctx );
0301 }
0302 
0303 static void RtemsTaskReqSuspend_Action( RtemsTaskReqSuspend_Context *ctx )
0304 {
0305   if ( ctx->suspend ) {
0306     SuspendTask( ctx->worker_id );
0307   }
0308 
0309   ctx->status = rtems_task_suspend( ctx->id );
0310 
0311   if ( ctx->suspend ) {
0312     ResumeTask( ctx->worker_id );
0313   }
0314 }
0315 
0316 static const RtemsTaskReqSuspend_Entry
0317 RtemsTaskReqSuspend_Entries[] = {
0318   { 0, 0, 1, RtemsTaskReqSuspend_Post_Status_InvId },
0319   { 0, 0, 0, RtemsTaskReqSuspend_Post_Status_AlrdySus },
0320   { 0, 0, 0, RtemsTaskReqSuspend_Post_Status_Ok }
0321 };
0322 
0323 static const uint8_t
0324 RtemsTaskReqSuspend_Map[] = {
0325   0, 0, 1, 2
0326 };
0327 
0328 static size_t RtemsTaskReqSuspend_Scope( void *arg, char *buf, size_t n )
0329 {
0330   RtemsTaskReqSuspend_Context *ctx;
0331 
0332   ctx = arg;
0333 
0334   if ( ctx->Map.in_action_loop ) {
0335     return T_get_scope( RtemsTaskReqSuspend_PreDesc, buf, n, ctx->Map.pcs );
0336   }
0337 
0338   return 0;
0339 }
0340 
0341 static T_fixture RtemsTaskReqSuspend_Fixture = {
0342   .setup = RtemsTaskReqSuspend_Setup_Wrap,
0343   .stop = NULL,
0344   .teardown = RtemsTaskReqSuspend_Teardown_Wrap,
0345   .scope = RtemsTaskReqSuspend_Scope,
0346   .initial_context = &RtemsTaskReqSuspend_Instance
0347 };
0348 
0349 static inline RtemsTaskReqSuspend_Entry RtemsTaskReqSuspend_PopEntry(
0350   RtemsTaskReqSuspend_Context *ctx
0351 )
0352 {
0353   size_t index;
0354 
0355   index = ctx->Map.index;
0356   ctx->Map.index = index + 1;
0357   return RtemsTaskReqSuspend_Entries[
0358     RtemsTaskReqSuspend_Map[ index ]
0359   ];
0360 }
0361 
0362 static void RtemsTaskReqSuspend_SetPreConditionStates(
0363   RtemsTaskReqSuspend_Context *ctx
0364 )
0365 {
0366   ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
0367 
0368   if ( ctx->Map.entry.Pre_Suspended_NA ) {
0369     ctx->Map.pcs[ 1 ] = RtemsTaskReqSuspend_Pre_Suspended_NA;
0370   } else {
0371     ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
0372   }
0373 }
0374 
0375 static void RtemsTaskReqSuspend_TestVariant( RtemsTaskReqSuspend_Context *ctx )
0376 {
0377   RtemsTaskReqSuspend_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0378   RtemsTaskReqSuspend_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0379   RtemsTaskReqSuspend_Action( ctx );
0380   RtemsTaskReqSuspend_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
0381 }
0382 
0383 /**
0384  * @fn void T_case_body_RtemsTaskReqSuspend( void )
0385  */
0386 T_TEST_CASE_FIXTURE( RtemsTaskReqSuspend, &RtemsTaskReqSuspend_Fixture )
0387 {
0388   RtemsTaskReqSuspend_Context *ctx;
0389 
0390   ctx = T_fixture_context();
0391   ctx->Map.in_action_loop = true;
0392   ctx->Map.index = 0;
0393 
0394   for (
0395     ctx->Map.pci[ 0 ] = RtemsTaskReqSuspend_Pre_Id_Invalid;
0396     ctx->Map.pci[ 0 ] < RtemsTaskReqSuspend_Pre_Id_NA;
0397     ++ctx->Map.pci[ 0 ]
0398   ) {
0399     for (
0400       ctx->Map.pci[ 1 ] = RtemsTaskReqSuspend_Pre_Suspended_Yes;
0401       ctx->Map.pci[ 1 ] < RtemsTaskReqSuspend_Pre_Suspended_NA;
0402       ++ctx->Map.pci[ 1 ]
0403     ) {
0404       ctx->Map.entry = RtemsTaskReqSuspend_PopEntry( ctx );
0405       RtemsTaskReqSuspend_SetPreConditionStates( ctx );
0406       RtemsTaskReqSuspend_TestVariant( ctx );
0407     }
0408   }
0409 }
0410 
0411 /** @} */