Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RtemsBarrierReqDelete
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 <string.h>
0057 
0058 #include "tx-support.h"
0059 
0060 #include <rtems/test.h>
0061 
0062 /**
0063  * @defgroup RtemsBarrierReqDelete spec:/rtems/barrier/req/delete
0064  *
0065  * @ingroup TestsuitesValidationNoClock0
0066  *
0067  * @{
0068  */
0069 
0070 typedef enum {
0071   RtemsBarrierReqDelete_Pre_Id_NoObj,
0072   RtemsBarrierReqDelete_Pre_Id_Barrier,
0073   RtemsBarrierReqDelete_Pre_Id_NA
0074 } RtemsBarrierReqDelete_Pre_Id;
0075 
0076 typedef enum {
0077   RtemsBarrierReqDelete_Post_Status_Ok,
0078   RtemsBarrierReqDelete_Post_Status_InvId,
0079   RtemsBarrierReqDelete_Post_Status_NA
0080 } RtemsBarrierReqDelete_Post_Status;
0081 
0082 typedef enum {
0083   RtemsBarrierReqDelete_Post_Name_Valid,
0084   RtemsBarrierReqDelete_Post_Name_Invalid,
0085   RtemsBarrierReqDelete_Post_Name_NA
0086 } RtemsBarrierReqDelete_Post_Name;
0087 
0088 typedef enum {
0089   RtemsBarrierReqDelete_Post_Flush_Yes,
0090   RtemsBarrierReqDelete_Post_Flush_No,
0091   RtemsBarrierReqDelete_Post_Flush_NA
0092 } RtemsBarrierReqDelete_Post_Flush;
0093 
0094 typedef struct {
0095   uint8_t Skip : 1;
0096   uint8_t Pre_Id_NA : 1;
0097   uint8_t Post_Status : 2;
0098   uint8_t Post_Name : 2;
0099   uint8_t Post_Flush : 2;
0100 } RtemsBarrierReqDelete_Entry;
0101 
0102 /**
0103  * @brief Test context for spec:/rtems/barrier/req/delete test case.
0104  */
0105 typedef struct {
0106   rtems_id worker_id;
0107 
0108   rtems_id barrier_id;
0109 
0110   uint32_t wait_done;
0111 
0112   uint32_t wait_expected;
0113 
0114   rtems_id id;
0115 
0116   rtems_status_code status;
0117 
0118   struct {
0119     /**
0120      * @brief This member defines the pre-condition states for the next action.
0121      */
0122     size_t pcs[ 1 ];
0123 
0124     /**
0125      * @brief If this member is true, then the test action loop is executed.
0126      */
0127     bool in_action_loop;
0128 
0129     /**
0130      * @brief This member contains the next transition map index.
0131      */
0132     size_t index;
0133 
0134     /**
0135      * @brief This member contains the current transition map entry.
0136      */
0137     RtemsBarrierReqDelete_Entry entry;
0138 
0139     /**
0140      * @brief If this member is true, then the current transition variant
0141      *   should be skipped.
0142      */
0143     bool skip;
0144   } Map;
0145 } RtemsBarrierReqDelete_Context;
0146 
0147 static RtemsBarrierReqDelete_Context
0148   RtemsBarrierReqDelete_Instance;
0149 
0150 static const char * const RtemsBarrierReqDelete_PreDesc_Id[] = {
0151   "NoObj",
0152   "Barrier",
0153   "NA"
0154 };
0155 
0156 static const char * const * const RtemsBarrierReqDelete_PreDesc[] = {
0157   RtemsBarrierReqDelete_PreDesc_Id,
0158   NULL
0159 };
0160 
0161 #define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
0162 
0163 typedef RtemsBarrierReqDelete_Context Context;
0164 
0165 static void Worker( rtems_task_argument arg )
0166 {
0167   Context *ctx;
0168 
0169   ctx = (Context *) arg;
0170 
0171   while ( true ) {
0172     rtems_status_code   sc;
0173     rtems_task_priority prio;
0174 
0175     T_eq_u32( ctx->barrier_id, 0 );
0176 
0177     sc = rtems_barrier_create(
0178       NAME,
0179       RTEMS_DEFAULT_ATTRIBUTES,
0180       0,
0181       &ctx->barrier_id
0182     );
0183     T_rsc_success( sc );
0184 
0185     sc = rtems_barrier_wait(
0186       ctx->barrier_id,
0187       RTEMS_NO_TIMEOUT
0188     );
0189     T_rsc( sc, RTEMS_OBJECT_WAS_DELETED );
0190 
0191     ++ctx->wait_done;
0192 
0193     prio = SetSelfPriority( PRIO_LOW );
0194     T_eq_u32( prio, PRIO_HIGH );
0195   }
0196 }
0197 
0198 static void RtemsBarrierReqDelete_Pre_Id_Prepare(
0199   RtemsBarrierReqDelete_Context *ctx,
0200   RtemsBarrierReqDelete_Pre_Id   state
0201 )
0202 {
0203   switch ( state ) {
0204     case RtemsBarrierReqDelete_Pre_Id_NoObj: {
0205       /*
0206        * While the ``id`` parameter is not associated with a barrier.
0207        */
0208       ctx->id = 0;
0209       break;
0210     }
0211 
0212     case RtemsBarrierReqDelete_Pre_Id_Barrier: {
0213       /*
0214        * While the ``id`` parameter is associated with a barrier.
0215        */
0216       ctx->id = ctx->barrier_id;
0217       break;
0218     }
0219 
0220     case RtemsBarrierReqDelete_Pre_Id_NA:
0221       break;
0222   }
0223 }
0224 
0225 static void RtemsBarrierReqDelete_Post_Status_Check(
0226   RtemsBarrierReqDelete_Context    *ctx,
0227   RtemsBarrierReqDelete_Post_Status state
0228 )
0229 {
0230   switch ( state ) {
0231     case RtemsBarrierReqDelete_Post_Status_Ok: {
0232       /*
0233        * The return status of rtems_barrier_delete() shall be RTEMS_SUCCESSFUL.
0234        */
0235       ctx->barrier_id = 0;
0236       T_rsc_success( ctx->status );
0237       break;
0238     }
0239 
0240     case RtemsBarrierReqDelete_Post_Status_InvId: {
0241       /*
0242        * The return status of rtems_barrier_delete() shall be RTEMS_INVALID_ID.
0243        */
0244       T_rsc( ctx->status, RTEMS_INVALID_ID );
0245       break;
0246     }
0247 
0248     case RtemsBarrierReqDelete_Post_Status_NA:
0249       break;
0250   }
0251 }
0252 
0253 static void RtemsBarrierReqDelete_Post_Name_Check(
0254   RtemsBarrierReqDelete_Context  *ctx,
0255   RtemsBarrierReqDelete_Post_Name state
0256 )
0257 {
0258   rtems_status_code sc;
0259   rtems_id          id;
0260 
0261   switch ( state ) {
0262     case RtemsBarrierReqDelete_Post_Name_Valid: {
0263       /*
0264        * The unique object name shall identify a barrier.
0265        */
0266       id = 0;
0267       sc = rtems_barrier_ident( NAME, &id );
0268       T_rsc_success( sc );
0269       T_eq_u32( id, ctx->barrier_id );
0270       break;
0271     }
0272 
0273     case RtemsBarrierReqDelete_Post_Name_Invalid: {
0274       /*
0275        * The unique object name shall not identify a barrier.
0276        */
0277       sc = rtems_barrier_ident( NAME, &id );
0278       T_rsc( sc, RTEMS_INVALID_NAME );
0279       break;
0280     }
0281 
0282     case RtemsBarrierReqDelete_Post_Name_NA:
0283       break;
0284   }
0285 }
0286 
0287 static void RtemsBarrierReqDelete_Post_Flush_Check(
0288   RtemsBarrierReqDelete_Context   *ctx,
0289   RtemsBarrierReqDelete_Post_Flush state
0290 )
0291 {
0292   switch ( state ) {
0293     case RtemsBarrierReqDelete_Post_Flush_Yes: {
0294       /*
0295        * Tasks waiting at the barrier shall be unblocked.
0296        */
0297       ++ctx->wait_expected;
0298       T_eq_u32( ctx->wait_done, ctx->wait_expected );
0299       break;
0300     }
0301 
0302     case RtemsBarrierReqDelete_Post_Flush_No: {
0303       /*
0304        * Tasks waiting at the barrier shall remain blocked.
0305        */
0306       T_eq_u32( ctx->wait_done, ctx->wait_expected );
0307       break;
0308     }
0309 
0310     case RtemsBarrierReqDelete_Post_Flush_NA:
0311       break;
0312   }
0313 }
0314 
0315 static void RtemsBarrierReqDelete_Setup( RtemsBarrierReqDelete_Context *ctx )
0316 {
0317   memset( ctx, 0, sizeof( *ctx ) );
0318   SetSelfPriority( PRIO_NORMAL );
0319   ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
0320   StartTask( ctx->worker_id, Worker, ctx );
0321 }
0322 
0323 static void RtemsBarrierReqDelete_Setup_Wrap( void *arg )
0324 {
0325   RtemsBarrierReqDelete_Context *ctx;
0326 
0327   ctx = arg;
0328   ctx->Map.in_action_loop = false;
0329   RtemsBarrierReqDelete_Setup( ctx );
0330 }
0331 
0332 static void RtemsBarrierReqDelete_Teardown(
0333   RtemsBarrierReqDelete_Context *ctx
0334 )
0335 {
0336   DeleteTask( ctx->worker_id );
0337   RestoreRunnerPriority();
0338 }
0339 
0340 static void RtemsBarrierReqDelete_Teardown_Wrap( void *arg )
0341 {
0342   RtemsBarrierReqDelete_Context *ctx;
0343 
0344   ctx = arg;
0345   ctx->Map.in_action_loop = false;
0346   RtemsBarrierReqDelete_Teardown( ctx );
0347 }
0348 
0349 static void RtemsBarrierReqDelete_Prepare( RtemsBarrierReqDelete_Context *ctx )
0350 {
0351   rtems_task_priority prio;
0352 
0353   prio = SetPriority( ctx->worker_id, PRIO_HIGH );
0354   T_true( prio == PRIO_LOW || prio == PRIO_HIGH );
0355 }
0356 
0357 static void RtemsBarrierReqDelete_Action( RtemsBarrierReqDelete_Context *ctx )
0358 {
0359   ctx->status = rtems_barrier_delete( ctx->id );
0360 }
0361 
0362 static void RtemsBarrierReqDelete_Cleanup( RtemsBarrierReqDelete_Context *ctx )
0363 {
0364   if ( ctx->barrier_id != 0 ) {
0365     rtems_status_code sc;
0366 
0367     sc = rtems_barrier_delete( ctx->barrier_id );
0368     T_rsc_success( sc );
0369 
0370     ++ctx->wait_expected;
0371     T_eq_u32( ctx->wait_done, ctx->wait_expected );
0372 
0373     ctx->barrier_id = 0;
0374   }
0375 }
0376 
0377 static const RtemsBarrierReqDelete_Entry
0378 RtemsBarrierReqDelete_Entries[] = {
0379   { 0, 0, RtemsBarrierReqDelete_Post_Status_InvId,
0380     RtemsBarrierReqDelete_Post_Name_Valid, RtemsBarrierReqDelete_Post_Flush_No },
0381   { 0, 0, RtemsBarrierReqDelete_Post_Status_Ok,
0382     RtemsBarrierReqDelete_Post_Name_Invalid,
0383     RtemsBarrierReqDelete_Post_Flush_Yes }
0384 };
0385 
0386 static const uint8_t
0387 RtemsBarrierReqDelete_Map[] = {
0388   0, 1
0389 };
0390 
0391 static size_t RtemsBarrierReqDelete_Scope( void *arg, char *buf, size_t n )
0392 {
0393   RtemsBarrierReqDelete_Context *ctx;
0394 
0395   ctx = arg;
0396 
0397   if ( ctx->Map.in_action_loop ) {
0398     return T_get_scope( RtemsBarrierReqDelete_PreDesc, buf, n, ctx->Map.pcs );
0399   }
0400 
0401   return 0;
0402 }
0403 
0404 static T_fixture RtemsBarrierReqDelete_Fixture = {
0405   .setup = RtemsBarrierReqDelete_Setup_Wrap,
0406   .stop = NULL,
0407   .teardown = RtemsBarrierReqDelete_Teardown_Wrap,
0408   .scope = RtemsBarrierReqDelete_Scope,
0409   .initial_context = &RtemsBarrierReqDelete_Instance
0410 };
0411 
0412 static inline RtemsBarrierReqDelete_Entry RtemsBarrierReqDelete_PopEntry(
0413   RtemsBarrierReqDelete_Context *ctx
0414 )
0415 {
0416   size_t index;
0417 
0418   index = ctx->Map.index;
0419   ctx->Map.index = index + 1;
0420   return RtemsBarrierReqDelete_Entries[
0421     RtemsBarrierReqDelete_Map[ index ]
0422   ];
0423 }
0424 
0425 static void RtemsBarrierReqDelete_TestVariant(
0426   RtemsBarrierReqDelete_Context *ctx
0427 )
0428 {
0429   RtemsBarrierReqDelete_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0430   RtemsBarrierReqDelete_Action( ctx );
0431   RtemsBarrierReqDelete_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
0432   RtemsBarrierReqDelete_Post_Name_Check( ctx, ctx->Map.entry.Post_Name );
0433   RtemsBarrierReqDelete_Post_Flush_Check( ctx, ctx->Map.entry.Post_Flush );
0434 }
0435 
0436 /**
0437  * @fn void T_case_body_RtemsBarrierReqDelete( void )
0438  */
0439 T_TEST_CASE_FIXTURE( RtemsBarrierReqDelete, &RtemsBarrierReqDelete_Fixture )
0440 {
0441   RtemsBarrierReqDelete_Context *ctx;
0442 
0443   ctx = T_fixture_context();
0444   ctx->Map.in_action_loop = true;
0445   ctx->Map.index = 0;
0446 
0447   for (
0448     ctx->Map.pcs[ 0 ] = RtemsBarrierReqDelete_Pre_Id_NoObj;
0449     ctx->Map.pcs[ 0 ] < RtemsBarrierReqDelete_Pre_Id_NA;
0450     ++ctx->Map.pcs[ 0 ]
0451   ) {
0452     ctx->Map.entry = RtemsBarrierReqDelete_PopEntry( ctx );
0453     RtemsBarrierReqDelete_Prepare( ctx );
0454     RtemsBarrierReqDelete_TestVariant( ctx );
0455     RtemsBarrierReqDelete_Cleanup( ctx );
0456   }
0457 }
0458 
0459 /** @} */