Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RtemsTaskReqGetAffinity
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 RtemsTaskReqGetAffinity spec:/rtems/task/req/get-affinity
0063  *
0064  * @ingroup TestsuitesValidationNoClock0
0065  *
0066  * @{
0067  */
0068 
0069 typedef enum {
0070   RtemsTaskReqGetAffinity_Pre_Id_Invalid,
0071   RtemsTaskReqGetAffinity_Pre_Id_Task,
0072   RtemsTaskReqGetAffinity_Pre_Id_NA
0073 } RtemsTaskReqGetAffinity_Pre_Id;
0074 
0075 typedef enum {
0076   RtemsTaskReqGetAffinity_Pre_CPUSetSize_Valid,
0077   RtemsTaskReqGetAffinity_Pre_CPUSetSize_TooSmall,
0078   RtemsTaskReqGetAffinity_Pre_CPUSetSize_Askew,
0079   RtemsTaskReqGetAffinity_Pre_CPUSetSize_NA
0080 } RtemsTaskReqGetAffinity_Pre_CPUSetSize;
0081 
0082 typedef enum {
0083   RtemsTaskReqGetAffinity_Pre_CPUSet_Valid,
0084   RtemsTaskReqGetAffinity_Pre_CPUSet_Null,
0085   RtemsTaskReqGetAffinity_Pre_CPUSet_NA
0086 } RtemsTaskReqGetAffinity_Pre_CPUSet;
0087 
0088 typedef enum {
0089   RtemsTaskReqGetAffinity_Post_Status_Ok,
0090   RtemsTaskReqGetAffinity_Post_Status_InvAddr,
0091   RtemsTaskReqGetAffinity_Post_Status_InvId,
0092   RtemsTaskReqGetAffinity_Post_Status_InvSize,
0093   RtemsTaskReqGetAffinity_Post_Status_NA
0094 } RtemsTaskReqGetAffinity_Post_Status;
0095 
0096 typedef enum {
0097   RtemsTaskReqGetAffinity_Post_CPUSetObj_Set,
0098   RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop,
0099   RtemsTaskReqGetAffinity_Post_CPUSetObj_NA
0100 } RtemsTaskReqGetAffinity_Post_CPUSetObj;
0101 
0102 typedef struct {
0103   uint16_t Skip : 1;
0104   uint16_t Pre_Id_NA : 1;
0105   uint16_t Pre_CPUSetSize_NA : 1;
0106   uint16_t Pre_CPUSet_NA : 1;
0107   uint16_t Post_Status : 3;
0108   uint16_t Post_CPUSetObj : 2;
0109 } RtemsTaskReqGetAffinity_Entry;
0110 
0111 /**
0112  * @brief Test context for spec:/rtems/task/req/get-affinity test case.
0113  */
0114 typedef struct {
0115   /**
0116    * @brief This member provides the object referenced by the ``cpuset``
0117    *   parameter.
0118    */
0119   cpu_set_t cpuset_obj;
0120 
0121   /**
0122    * @brief This member contains the return value of the
0123    *   rtems_task_get_affinity() call.
0124    */
0125   rtems_status_code status;
0126 
0127   /**
0128    * @brief This member specifies if the ``id`` parameter value.
0129    */
0130   rtems_id id;
0131 
0132   /**
0133    * @brief This member specifies if the ``cpusetsize`` parameter value.
0134    */
0135   size_t cpusetsize;
0136 
0137   /**
0138    * @brief This member specifies if the ``cpuset`` parameter value.
0139    */
0140   cpu_set_t *cpuset;
0141 
0142   struct {
0143     /**
0144      * @brief This member defines the pre-condition states for the next action.
0145      */
0146     size_t pcs[ 3 ];
0147 
0148     /**
0149      * @brief If this member is true, then the test action loop is executed.
0150      */
0151     bool in_action_loop;
0152 
0153     /**
0154      * @brief This member contains the next transition map index.
0155      */
0156     size_t index;
0157 
0158     /**
0159      * @brief This member contains the current transition map entry.
0160      */
0161     RtemsTaskReqGetAffinity_Entry entry;
0162 
0163     /**
0164      * @brief If this member is true, then the current transition variant
0165      *   should be skipped.
0166      */
0167     bool skip;
0168   } Map;
0169 } RtemsTaskReqGetAffinity_Context;
0170 
0171 static RtemsTaskReqGetAffinity_Context
0172   RtemsTaskReqGetAffinity_Instance;
0173 
0174 static const char * const RtemsTaskReqGetAffinity_PreDesc_Id[] = {
0175   "Invalid",
0176   "Task",
0177   "NA"
0178 };
0179 
0180 static const char * const RtemsTaskReqGetAffinity_PreDesc_CPUSetSize[] = {
0181   "Valid",
0182   "TooSmall",
0183   "Askew",
0184   "NA"
0185 };
0186 
0187 static const char * const RtemsTaskReqGetAffinity_PreDesc_CPUSet[] = {
0188   "Valid",
0189   "Null",
0190   "NA"
0191 };
0192 
0193 static const char * const * const RtemsTaskReqGetAffinity_PreDesc[] = {
0194   RtemsTaskReqGetAffinity_PreDesc_Id,
0195   RtemsTaskReqGetAffinity_PreDesc_CPUSetSize,
0196   RtemsTaskReqGetAffinity_PreDesc_CPUSet,
0197   NULL
0198 };
0199 
0200 static void RtemsTaskReqGetAffinity_Pre_Id_Prepare(
0201   RtemsTaskReqGetAffinity_Context *ctx,
0202   RtemsTaskReqGetAffinity_Pre_Id   state
0203 )
0204 {
0205   switch ( state ) {
0206     case RtemsTaskReqGetAffinity_Pre_Id_Invalid: {
0207       /*
0208        * While the ``id`` parameter is not associated with a task.
0209        */
0210       ctx->id = INVALID_ID;
0211       break;
0212     }
0213 
0214     case RtemsTaskReqGetAffinity_Pre_Id_Task: {
0215       /*
0216        * While the ``id`` parameter is associated with a task.
0217        */
0218       ctx->id = RTEMS_SELF;
0219       break;
0220     }
0221 
0222     case RtemsTaskReqGetAffinity_Pre_Id_NA:
0223       break;
0224   }
0225 }
0226 
0227 static void RtemsTaskReqGetAffinity_Pre_CPUSetSize_Prepare(
0228   RtemsTaskReqGetAffinity_Context       *ctx,
0229   RtemsTaskReqGetAffinity_Pre_CPUSetSize state
0230 )
0231 {
0232   switch ( state ) {
0233     case RtemsTaskReqGetAffinity_Pre_CPUSetSize_Valid: {
0234       /*
0235        * While the ``cpusetsize`` parameter is an integral multiple of the size
0236        * of long, while the ``cpusetsize`` parameter specifies a processor set
0237        * which is large enough to contain the processor affinity set of the
0238        * task.
0239        */
0240       ctx->cpusetsize = sizeof( ctx->cpuset_obj );
0241       break;
0242     }
0243 
0244     case RtemsTaskReqGetAffinity_Pre_CPUSetSize_TooSmall: {
0245       /*
0246        * While the ``cpusetsize`` parameter is an integral multiple of the size
0247        * of long, while the ``cpusetsize`` parameter specifies a processor set
0248        * which is not large enough to contain the processor affinity set of the
0249        * task.
0250        */
0251       ctx->cpusetsize = 0;
0252       break;
0253     }
0254 
0255     case RtemsTaskReqGetAffinity_Pre_CPUSetSize_Askew: {
0256       /*
0257        * While the ``cpusetsize`` parameter is not an integral multiple of the
0258        * size of long.
0259        */
0260       ctx->cpusetsize = SIZE_MAX;
0261       break;
0262     }
0263 
0264     case RtemsTaskReqGetAffinity_Pre_CPUSetSize_NA:
0265       break;
0266   }
0267 }
0268 
0269 static void RtemsTaskReqGetAffinity_Pre_CPUSet_Prepare(
0270   RtemsTaskReqGetAffinity_Context   *ctx,
0271   RtemsTaskReqGetAffinity_Pre_CPUSet state
0272 )
0273 {
0274   switch ( state ) {
0275     case RtemsTaskReqGetAffinity_Pre_CPUSet_Valid: {
0276       /*
0277        * While the ``cpuset`` parameter references an object of type cpu_set_t.
0278        */
0279       ctx->cpuset = &ctx->cpuset_obj;
0280       break;
0281     }
0282 
0283     case RtemsTaskReqGetAffinity_Pre_CPUSet_Null: {
0284       /*
0285        * While the ``cpuset`` parameter is equal to NULL.
0286        */
0287       ctx->cpuset = NULL;
0288       break;
0289     }
0290 
0291     case RtemsTaskReqGetAffinity_Pre_CPUSet_NA:
0292       break;
0293   }
0294 }
0295 
0296 static void RtemsTaskReqGetAffinity_Post_Status_Check(
0297   RtemsTaskReqGetAffinity_Context    *ctx,
0298   RtemsTaskReqGetAffinity_Post_Status state
0299 )
0300 {
0301   switch ( state ) {
0302     case RtemsTaskReqGetAffinity_Post_Status_Ok: {
0303       /*
0304        * The return status of rtems_task_get_affinity() shall be
0305        * RTEMS_SUCCESSFUL.
0306        */
0307       T_rsc_success( ctx->status );
0308       break;
0309     }
0310 
0311     case RtemsTaskReqGetAffinity_Post_Status_InvAddr: {
0312       /*
0313        * The return status of rtems_task_get_affinity() shall be
0314        * RTEMS_INVALID_ADDRESS.
0315        */
0316       T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
0317       break;
0318     }
0319 
0320     case RtemsTaskReqGetAffinity_Post_Status_InvId: {
0321       /*
0322        * The return status of rtems_task_get_affinity() shall be
0323        * RTEMS_INVALID_ID.
0324        */
0325       T_rsc( ctx->status, RTEMS_INVALID_ID );
0326       break;
0327     }
0328 
0329     case RtemsTaskReqGetAffinity_Post_Status_InvSize: {
0330       /*
0331        * The return status of rtems_task_get_affinity() shall be
0332        * RTEMS_INVALID_SIZE.
0333        */
0334       T_rsc( ctx->status, RTEMS_INVALID_SIZE );
0335       break;
0336     }
0337 
0338     case RtemsTaskReqGetAffinity_Post_Status_NA:
0339       break;
0340   }
0341 }
0342 
0343 static void RtemsTaskReqGetAffinity_Post_CPUSetObj_Check(
0344   RtemsTaskReqGetAffinity_Context       *ctx,
0345   RtemsTaskReqGetAffinity_Post_CPUSetObj state
0346 )
0347 {
0348   cpu_set_t set;
0349   uint32_t  cpu_index;
0350   uint32_t  cpu_max;
0351 
0352   switch ( state ) {
0353     case RtemsTaskReqGetAffinity_Post_CPUSetObj_Set: {
0354       /*
0355        * The value of the object referenced by the ``cpuset`` parameter shall
0356        * be set to the processor affinity set of the task specified by the
0357        * ``id`` parameter at some point during the call after the return of the
0358        * rtems_task_get_affinity() call.
0359        */
0360       CPU_ZERO( &set );
0361 
0362       cpu_max = rtems_scheduler_get_processor_maximum();
0363 
0364       /* We need the online processors */
0365       if ( cpu_max > 4 ) {
0366         cpu_max = 4;
0367       }
0368 
0369       for ( cpu_index = 0; cpu_index < cpu_max; ++cpu_index ) {
0370         CPU_SET( (int) cpu_index, &set );
0371       }
0372 
0373       T_eq_int( CPU_CMP( &ctx->cpuset_obj, &set ), 0 );
0374       break;
0375     }
0376 
0377     case RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop: {
0378       /*
0379        * Objects referenced by the ``cpuset`` parameter in past calls to
0380        * rtems_task_get_affinity() shall not be accessed by the
0381        * rtems_task_get_affinity() call.
0382        */
0383       CPU_ZERO( &set );
0384       T_eq_int( CPU_CMP( &ctx->cpuset_obj, &set ), 0 );
0385       break;
0386     }
0387 
0388     case RtemsTaskReqGetAffinity_Post_CPUSetObj_NA:
0389       break;
0390   }
0391 }
0392 
0393 static void RtemsTaskReqGetAffinity_Prepare(
0394   RtemsTaskReqGetAffinity_Context *ctx
0395 )
0396 {
0397   CPU_ZERO( &ctx->cpuset_obj );
0398 }
0399 
0400 static void RtemsTaskReqGetAffinity_Action(
0401   RtemsTaskReqGetAffinity_Context *ctx
0402 )
0403 {
0404   ctx->status = rtems_task_get_affinity(
0405     ctx->id,
0406     ctx->cpusetsize,
0407     ctx->cpuset
0408   );
0409 }
0410 
0411 static const RtemsTaskReqGetAffinity_Entry
0412 RtemsTaskReqGetAffinity_Entries[] = {
0413   { 0, 0, 0, 0, RtemsTaskReqGetAffinity_Post_Status_InvAddr,
0414     RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop },
0415   { 0, 0, 0, 0, RtemsTaskReqGetAffinity_Post_Status_InvId,
0416     RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop },
0417   { 0, 0, 0, 0, RtemsTaskReqGetAffinity_Post_Status_InvSize,
0418     RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop },
0419   { 0, 0, 0, 0, RtemsTaskReqGetAffinity_Post_Status_Ok,
0420     RtemsTaskReqGetAffinity_Post_CPUSetObj_Set }
0421 };
0422 
0423 static const uint8_t
0424 RtemsTaskReqGetAffinity_Map[] = {
0425   1, 0, 1, 0, 1, 0, 3, 0, 2, 0, 2, 0
0426 };
0427 
0428 static size_t RtemsTaskReqGetAffinity_Scope( void *arg, char *buf, size_t n )
0429 {
0430   RtemsTaskReqGetAffinity_Context *ctx;
0431 
0432   ctx = arg;
0433 
0434   if ( ctx->Map.in_action_loop ) {
0435     return T_get_scope(
0436       RtemsTaskReqGetAffinity_PreDesc,
0437       buf,
0438       n,
0439       ctx->Map.pcs
0440     );
0441   }
0442 
0443   return 0;
0444 }
0445 
0446 static T_fixture RtemsTaskReqGetAffinity_Fixture = {
0447   .setup = NULL,
0448   .stop = NULL,
0449   .teardown = NULL,
0450   .scope = RtemsTaskReqGetAffinity_Scope,
0451   .initial_context = &RtemsTaskReqGetAffinity_Instance
0452 };
0453 
0454 static inline RtemsTaskReqGetAffinity_Entry RtemsTaskReqGetAffinity_PopEntry(
0455   RtemsTaskReqGetAffinity_Context *ctx
0456 )
0457 {
0458   size_t index;
0459 
0460   index = ctx->Map.index;
0461   ctx->Map.index = index + 1;
0462   return RtemsTaskReqGetAffinity_Entries[
0463     RtemsTaskReqGetAffinity_Map[ index ]
0464   ];
0465 }
0466 
0467 static void RtemsTaskReqGetAffinity_TestVariant(
0468   RtemsTaskReqGetAffinity_Context *ctx
0469 )
0470 {
0471   RtemsTaskReqGetAffinity_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0472   RtemsTaskReqGetAffinity_Pre_CPUSetSize_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0473   RtemsTaskReqGetAffinity_Pre_CPUSet_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0474   RtemsTaskReqGetAffinity_Action( ctx );
0475   RtemsTaskReqGetAffinity_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
0476   RtemsTaskReqGetAffinity_Post_CPUSetObj_Check(
0477     ctx,
0478     ctx->Map.entry.Post_CPUSetObj
0479   );
0480 }
0481 
0482 /**
0483  * @fn void T_case_body_RtemsTaskReqGetAffinity( void )
0484  */
0485 T_TEST_CASE_FIXTURE(
0486   RtemsTaskReqGetAffinity,
0487   &RtemsTaskReqGetAffinity_Fixture
0488 )
0489 {
0490   RtemsTaskReqGetAffinity_Context *ctx;
0491 
0492   ctx = T_fixture_context();
0493   ctx->Map.in_action_loop = true;
0494   ctx->Map.index = 0;
0495 
0496   for (
0497     ctx->Map.pcs[ 0 ] = RtemsTaskReqGetAffinity_Pre_Id_Invalid;
0498     ctx->Map.pcs[ 0 ] < RtemsTaskReqGetAffinity_Pre_Id_NA;
0499     ++ctx->Map.pcs[ 0 ]
0500   ) {
0501     for (
0502       ctx->Map.pcs[ 1 ] = RtemsTaskReqGetAffinity_Pre_CPUSetSize_Valid;
0503       ctx->Map.pcs[ 1 ] < RtemsTaskReqGetAffinity_Pre_CPUSetSize_NA;
0504       ++ctx->Map.pcs[ 1 ]
0505     ) {
0506       for (
0507         ctx->Map.pcs[ 2 ] = RtemsTaskReqGetAffinity_Pre_CPUSet_Valid;
0508         ctx->Map.pcs[ 2 ] < RtemsTaskReqGetAffinity_Pre_CPUSet_NA;
0509         ++ctx->Map.pcs[ 2 ]
0510       ) {
0511         ctx->Map.entry = RtemsTaskReqGetAffinity_PopEntry( ctx );
0512         RtemsTaskReqGetAffinity_Prepare( ctx );
0513         RtemsTaskReqGetAffinity_TestVariant( ctx );
0514       }
0515     }
0516   }
0517 }
0518 
0519 /** @} */