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 RtemsBarrierReqRelease
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 RtemsBarrierReqRelease spec:/rtems/barrier/req/release
0064  *
0065  * @ingroup TestsuitesValidationNoClock0
0066  *
0067  * @{
0068  */
0069 
0070 typedef enum {
0071   RtemsBarrierReqRelease_Pre_Id_NoObj,
0072   RtemsBarrierReqRelease_Pre_Id_Manual,
0073   RtemsBarrierReqRelease_Pre_Id_Auto,
0074   RtemsBarrierReqRelease_Pre_Id_NA
0075 } RtemsBarrierReqRelease_Pre_Id;
0076 
0077 typedef enum {
0078   RtemsBarrierReqRelease_Pre_Released_Valid,
0079   RtemsBarrierReqRelease_Pre_Released_Null,
0080   RtemsBarrierReqRelease_Pre_Released_NA
0081 } RtemsBarrierReqRelease_Pre_Released;
0082 
0083 typedef enum {
0084   RtemsBarrierReqRelease_Pre_Waiting_Zero,
0085   RtemsBarrierReqRelease_Pre_Waiting_Positive,
0086   RtemsBarrierReqRelease_Pre_Waiting_NA
0087 } RtemsBarrierReqRelease_Pre_Waiting;
0088 
0089 typedef enum {
0090   RtemsBarrierReqRelease_Post_Status_Ok,
0091   RtemsBarrierReqRelease_Post_Status_InvId,
0092   RtemsBarrierReqRelease_Post_Status_InvAddr,
0093   RtemsBarrierReqRelease_Post_Status_NA
0094 } RtemsBarrierReqRelease_Post_Status;
0095 
0096 typedef enum {
0097   RtemsBarrierReqRelease_Post_ReleasedVar_Set,
0098   RtemsBarrierReqRelease_Post_ReleasedVar_Nop,
0099   RtemsBarrierReqRelease_Post_ReleasedVar_NA
0100 } RtemsBarrierReqRelease_Post_ReleasedVar;
0101 
0102 typedef struct {
0103   uint8_t Skip : 1;
0104   uint8_t Pre_Id_NA : 1;
0105   uint8_t Pre_Released_NA : 1;
0106   uint8_t Pre_Waiting_NA : 1;
0107   uint8_t Post_Status : 2;
0108   uint8_t Post_ReleasedVar : 2;
0109 } RtemsBarrierReqRelease_Entry;
0110 
0111 /**
0112  * @brief Test context for spec:/rtems/barrier/req/release test case.
0113  */
0114 typedef struct {
0115   rtems_id worker_id;
0116 
0117   rtems_id manual_release_id;
0118 
0119   rtems_id auto_release_id;
0120 
0121   uint32_t waiting_tasks;
0122 
0123   uint32_t released_value;
0124 
0125   rtems_id id;
0126 
0127   uint32_t *released;
0128 
0129   rtems_status_code status;
0130 
0131   struct {
0132     /**
0133      * @brief This member defines the pre-condition indices for the next
0134      *   action.
0135      */
0136     size_t pci[ 3 ];
0137 
0138     /**
0139      * @brief This member defines the pre-condition states for the next action.
0140      */
0141     size_t pcs[ 3 ];
0142 
0143     /**
0144      * @brief If this member is true, then the test action loop is executed.
0145      */
0146     bool in_action_loop;
0147 
0148     /**
0149      * @brief This member contains the next transition map index.
0150      */
0151     size_t index;
0152 
0153     /**
0154      * @brief This member contains the current transition map entry.
0155      */
0156     RtemsBarrierReqRelease_Entry entry;
0157 
0158     /**
0159      * @brief If this member is true, then the current transition variant
0160      *   should be skipped.
0161      */
0162     bool skip;
0163   } Map;
0164 } RtemsBarrierReqRelease_Context;
0165 
0166 static RtemsBarrierReqRelease_Context
0167   RtemsBarrierReqRelease_Instance;
0168 
0169 static const char * const RtemsBarrierReqRelease_PreDesc_Id[] = {
0170   "NoObj",
0171   "Manual",
0172   "Auto",
0173   "NA"
0174 };
0175 
0176 static const char * const RtemsBarrierReqRelease_PreDesc_Released[] = {
0177   "Valid",
0178   "Null",
0179   "NA"
0180 };
0181 
0182 static const char * const RtemsBarrierReqRelease_PreDesc_Waiting[] = {
0183   "Zero",
0184   "Positive",
0185   "NA"
0186 };
0187 
0188 static const char * const * const RtemsBarrierReqRelease_PreDesc[] = {
0189   RtemsBarrierReqRelease_PreDesc_Id,
0190   RtemsBarrierReqRelease_PreDesc_Released,
0191   RtemsBarrierReqRelease_PreDesc_Waiting,
0192   NULL
0193 };
0194 
0195 #define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
0196 
0197 #define EVENT_WAIT RTEMS_EVENT_0
0198 
0199 #define RELEASED_INVALID_VALUE 0xffffffff
0200 
0201 typedef RtemsBarrierReqRelease_Context Context;
0202 
0203 static void Worker( rtems_task_argument arg )
0204 {
0205   Context *ctx;
0206 
0207   ctx = (Context *) arg;
0208 
0209   while ( true ) {
0210     rtems_event_set events;
0211 
0212     events = ReceiveAnyEvents();
0213 
0214     if ( ( events & EVENT_WAIT ) != 0 ) {
0215       rtems_status_code sc;
0216 
0217       sc = rtems_barrier_wait( ctx->id, RTEMS_NO_TIMEOUT );
0218       T_rsc_success( sc );
0219     }
0220   }
0221 }
0222 
0223 static void RtemsBarrierReqRelease_Pre_Id_Prepare(
0224   RtemsBarrierReqRelease_Context *ctx,
0225   RtemsBarrierReqRelease_Pre_Id   state
0226 )
0227 {
0228   switch ( state ) {
0229     case RtemsBarrierReqRelease_Pre_Id_NoObj: {
0230       /*
0231        * While the ``id`` parameter is not associated with a barrier.
0232        */
0233       ctx->id = 0xffffffff;
0234       break;
0235     }
0236 
0237     case RtemsBarrierReqRelease_Pre_Id_Manual: {
0238       /*
0239        * While the ``id`` parameter is associated with a manual release
0240        * barrier.
0241        */
0242       ctx->id = ctx->manual_release_id;
0243       break;
0244     }
0245 
0246     case RtemsBarrierReqRelease_Pre_Id_Auto: {
0247       /*
0248        * While the ``id`` parameter is associated with an automatic release
0249        * barrier.
0250        */
0251       ctx->id = ctx->auto_release_id;
0252       break;
0253     }
0254 
0255     case RtemsBarrierReqRelease_Pre_Id_NA:
0256       break;
0257   }
0258 }
0259 
0260 static void RtemsBarrierReqRelease_Pre_Released_Prepare(
0261   RtemsBarrierReqRelease_Context     *ctx,
0262   RtemsBarrierReqRelease_Pre_Released state
0263 )
0264 {
0265   ctx->released_value = RELEASED_INVALID_VALUE;
0266 
0267   switch ( state ) {
0268     case RtemsBarrierReqRelease_Pre_Released_Valid: {
0269       /*
0270        * While the ``released`` parameter references an object of type
0271        * uint32_t.
0272        */
0273       ctx->released = &ctx->released_value;
0274       break;
0275     }
0276 
0277     case RtemsBarrierReqRelease_Pre_Released_Null: {
0278       /*
0279        * While the ``released`` parameter is NULL.
0280        */
0281       ctx->released = NULL;
0282       break;
0283     }
0284 
0285     case RtemsBarrierReqRelease_Pre_Released_NA:
0286       break;
0287   }
0288 }
0289 
0290 static void RtemsBarrierReqRelease_Pre_Waiting_Prepare(
0291   RtemsBarrierReqRelease_Context    *ctx,
0292   RtemsBarrierReqRelease_Pre_Waiting state
0293 )
0294 {
0295   switch ( state ) {
0296     case RtemsBarrierReqRelease_Pre_Waiting_Zero: {
0297       /*
0298        * While the number of tasks waiting at the barrier is zero.
0299        */
0300       ctx->waiting_tasks = 0;
0301       break;
0302     }
0303 
0304     case RtemsBarrierReqRelease_Pre_Waiting_Positive: {
0305       /*
0306        * While the number of tasks waiting at the barrier is positive.
0307        */
0308       ctx->waiting_tasks = 1;
0309       SendEvents( ctx->worker_id, EVENT_WAIT );
0310       break;
0311     }
0312 
0313     case RtemsBarrierReqRelease_Pre_Waiting_NA:
0314       break;
0315   }
0316 }
0317 
0318 static void RtemsBarrierReqRelease_Post_Status_Check(
0319   RtemsBarrierReqRelease_Context    *ctx,
0320   RtemsBarrierReqRelease_Post_Status state
0321 )
0322 {
0323   switch ( state ) {
0324     case RtemsBarrierReqRelease_Post_Status_Ok: {
0325       /*
0326        * The return status of rtems_barrier_release() shall be
0327        * RTEMS_SUCCESSFUL.
0328        */
0329       T_rsc_success( ctx->status );
0330       break;
0331     }
0332 
0333     case RtemsBarrierReqRelease_Post_Status_InvId: {
0334       /*
0335        * The return status of rtems_barrier_release() shall be
0336        * RTEMS_INVALID_ID.
0337        */
0338       T_rsc( ctx->status, RTEMS_INVALID_ID );
0339       break;
0340     }
0341 
0342     case RtemsBarrierReqRelease_Post_Status_InvAddr: {
0343       /*
0344        * The return status of rtems_barrier_release() shall be
0345        * RTEMS_INVALID_ADDRESS.
0346        */
0347       T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
0348       break;
0349     }
0350 
0351     case RtemsBarrierReqRelease_Post_Status_NA:
0352       break;
0353   }
0354 }
0355 
0356 static void RtemsBarrierReqRelease_Post_ReleasedVar_Check(
0357   RtemsBarrierReqRelease_Context         *ctx,
0358   RtemsBarrierReqRelease_Post_ReleasedVar state
0359 )
0360 {
0361   switch ( state ) {
0362     case RtemsBarrierReqRelease_Post_ReleasedVar_Set: {
0363       /*
0364        * The value of the object referenced by the ``released`` parameter shall
0365        * be set to the number of released tasks after the return of the
0366        * rtems_barrier_release() call.
0367        */
0368       T_eq_u32( ctx->released_value, ctx->waiting_tasks );
0369       break;
0370     }
0371 
0372     case RtemsBarrierReqRelease_Post_ReleasedVar_Nop: {
0373       /*
0374        * Objects referenced by the ``released`` parameter in past calls to
0375        * rtems_barrier_release() shall not be accessed by the
0376        * rtems_barrier_release() call.
0377        */
0378       T_eq_u32( ctx->released_value, RELEASED_INVALID_VALUE );
0379       break;
0380     }
0381 
0382     case RtemsBarrierReqRelease_Post_ReleasedVar_NA:
0383       break;
0384   }
0385 }
0386 
0387 static void RtemsBarrierReqRelease_Setup( RtemsBarrierReqRelease_Context *ctx )
0388 {
0389   rtems_status_code sc;
0390 
0391   memset( ctx, 0, sizeof( *ctx ) );
0392   SetSelfPriority( PRIO_NORMAL );
0393   ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
0394   StartTask( ctx->worker_id, Worker, ctx );
0395 
0396   sc = rtems_barrier_create(
0397     NAME,
0398     RTEMS_BARRIER_MANUAL_RELEASE,
0399     0,
0400     &ctx->manual_release_id
0401   );
0402   T_assert_rsc_success( sc );
0403 
0404   sc = rtems_barrier_create(
0405     NAME,
0406     RTEMS_BARRIER_AUTOMATIC_RELEASE,
0407     2,
0408     &ctx->auto_release_id
0409   );
0410   T_assert_rsc_success( sc );
0411 }
0412 
0413 static void RtemsBarrierReqRelease_Setup_Wrap( void *arg )
0414 {
0415   RtemsBarrierReqRelease_Context *ctx;
0416 
0417   ctx = arg;
0418   ctx->Map.in_action_loop = false;
0419   RtemsBarrierReqRelease_Setup( ctx );
0420 }
0421 
0422 static void RtemsBarrierReqRelease_Teardown(
0423   RtemsBarrierReqRelease_Context *ctx
0424 )
0425 {
0426   rtems_status_code sc;
0427 
0428   DeleteTask( ctx->worker_id );
0429 
0430   if ( ctx->manual_release_id != 0 ) {
0431     sc = rtems_barrier_delete( ctx->manual_release_id );
0432     T_rsc_success( sc );
0433   }
0434 
0435   if ( ctx->auto_release_id != 0 ) {
0436     sc = rtems_barrier_delete( ctx->auto_release_id );
0437     T_rsc_success( sc );
0438   }
0439 
0440   RestoreRunnerPriority();
0441 }
0442 
0443 static void RtemsBarrierReqRelease_Teardown_Wrap( void *arg )
0444 {
0445   RtemsBarrierReqRelease_Context *ctx;
0446 
0447   ctx = arg;
0448   ctx->Map.in_action_loop = false;
0449   RtemsBarrierReqRelease_Teardown( ctx );
0450 }
0451 
0452 static void RtemsBarrierReqRelease_Action(
0453   RtemsBarrierReqRelease_Context *ctx
0454 )
0455 {
0456   ctx->status = rtems_barrier_release( ctx->id, ctx->released );
0457 }
0458 
0459 static const RtemsBarrierReqRelease_Entry
0460 RtemsBarrierReqRelease_Entries[] = {
0461   { 0, 0, 0, 1, RtemsBarrierReqRelease_Post_Status_InvAddr,
0462     RtemsBarrierReqRelease_Post_ReleasedVar_Nop },
0463   { 0, 0, 0, 0, RtemsBarrierReqRelease_Post_Status_Ok,
0464     RtemsBarrierReqRelease_Post_ReleasedVar_Set },
0465   { 0, 0, 0, 1, RtemsBarrierReqRelease_Post_Status_InvId,
0466     RtemsBarrierReqRelease_Post_ReleasedVar_Nop }
0467 };
0468 
0469 static const uint8_t
0470 RtemsBarrierReqRelease_Map[] = {
0471   2, 2, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0
0472 };
0473 
0474 static size_t RtemsBarrierReqRelease_Scope( void *arg, char *buf, size_t n )
0475 {
0476   RtemsBarrierReqRelease_Context *ctx;
0477 
0478   ctx = arg;
0479 
0480   if ( ctx->Map.in_action_loop ) {
0481     return T_get_scope( RtemsBarrierReqRelease_PreDesc, buf, n, ctx->Map.pcs );
0482   }
0483 
0484   return 0;
0485 }
0486 
0487 static T_fixture RtemsBarrierReqRelease_Fixture = {
0488   .setup = RtemsBarrierReqRelease_Setup_Wrap,
0489   .stop = NULL,
0490   .teardown = RtemsBarrierReqRelease_Teardown_Wrap,
0491   .scope = RtemsBarrierReqRelease_Scope,
0492   .initial_context = &RtemsBarrierReqRelease_Instance
0493 };
0494 
0495 static inline RtemsBarrierReqRelease_Entry RtemsBarrierReqRelease_PopEntry(
0496   RtemsBarrierReqRelease_Context *ctx
0497 )
0498 {
0499   size_t index;
0500 
0501   index = ctx->Map.index;
0502   ctx->Map.index = index + 1;
0503   return RtemsBarrierReqRelease_Entries[
0504     RtemsBarrierReqRelease_Map[ index ]
0505   ];
0506 }
0507 
0508 static void RtemsBarrierReqRelease_SetPreConditionStates(
0509   RtemsBarrierReqRelease_Context *ctx
0510 )
0511 {
0512   ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
0513   ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
0514 
0515   if ( ctx->Map.entry.Pre_Waiting_NA ) {
0516     ctx->Map.pcs[ 2 ] = RtemsBarrierReqRelease_Pre_Waiting_NA;
0517   } else {
0518     ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
0519   }
0520 }
0521 
0522 static void RtemsBarrierReqRelease_TestVariant(
0523   RtemsBarrierReqRelease_Context *ctx
0524 )
0525 {
0526   RtemsBarrierReqRelease_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0527   RtemsBarrierReqRelease_Pre_Released_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0528   RtemsBarrierReqRelease_Pre_Waiting_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0529   RtemsBarrierReqRelease_Action( ctx );
0530   RtemsBarrierReqRelease_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
0531   RtemsBarrierReqRelease_Post_ReleasedVar_Check(
0532     ctx,
0533     ctx->Map.entry.Post_ReleasedVar
0534   );
0535 }
0536 
0537 /**
0538  * @fn void T_case_body_RtemsBarrierReqRelease( void )
0539  */
0540 T_TEST_CASE_FIXTURE( RtemsBarrierReqRelease, &RtemsBarrierReqRelease_Fixture )
0541 {
0542   RtemsBarrierReqRelease_Context *ctx;
0543 
0544   ctx = T_fixture_context();
0545   ctx->Map.in_action_loop = true;
0546   ctx->Map.index = 0;
0547 
0548   for (
0549     ctx->Map.pci[ 0 ] = RtemsBarrierReqRelease_Pre_Id_NoObj;
0550     ctx->Map.pci[ 0 ] < RtemsBarrierReqRelease_Pre_Id_NA;
0551     ++ctx->Map.pci[ 0 ]
0552   ) {
0553     for (
0554       ctx->Map.pci[ 1 ] = RtemsBarrierReqRelease_Pre_Released_Valid;
0555       ctx->Map.pci[ 1 ] < RtemsBarrierReqRelease_Pre_Released_NA;
0556       ++ctx->Map.pci[ 1 ]
0557     ) {
0558       for (
0559         ctx->Map.pci[ 2 ] = RtemsBarrierReqRelease_Pre_Waiting_Zero;
0560         ctx->Map.pci[ 2 ] < RtemsBarrierReqRelease_Pre_Waiting_NA;
0561         ++ctx->Map.pci[ 2 ]
0562       ) {
0563         ctx->Map.entry = RtemsBarrierReqRelease_PopEntry( ctx );
0564         RtemsBarrierReqRelease_SetPreConditionStates( ctx );
0565         RtemsBarrierReqRelease_TestVariant( ctx );
0566       }
0567     }
0568   }
0569 }
0570 
0571 /** @} */