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 RtemsSemValPerf
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 RtemsSemValPerf spec:/rtems/sem/val/perf
0063  *
0064  * @ingroup TestsuitesPerformanceNoClock0
0065  *
0066  * @brief This test case provides a context to run @ref RTEMSAPIClassicSem
0067  *   performance tests.
0068  *
0069  * @{
0070  */
0071 
0072 /**
0073  * @brief Test context for spec:/rtems/sem/val/perf test case.
0074  */
0075 typedef struct {
0076   /**
0077    * @brief This member provides a mutex identifier.
0078    */
0079   rtems_id mutex_id;
0080 
0081   /**
0082    * @brief This member provides a worker identifier.
0083    */
0084   rtems_id worker_id;
0085 
0086   /**
0087    * @brief This member provides a status code.
0088    */
0089   rtems_status_code status;
0090 
0091   /**
0092    * @brief This member references the measure runtime context.
0093    */
0094   T_measure_runtime_context *context;
0095 
0096   /**
0097    * @brief This member provides the measure runtime request.
0098    */
0099   T_measure_runtime_request request;
0100 
0101   /**
0102    * @brief This member provides an optional measurement begin time point.
0103    */
0104   T_ticks begin;
0105 
0106   /**
0107    * @brief This member provides an optional measurement end time point.
0108    */
0109   T_ticks end;
0110 } RtemsSemValPerf_Context;
0111 
0112 static RtemsSemValPerf_Context
0113   RtemsSemValPerf_Instance;
0114 
0115 #define EVENT_END RTEMS_EVENT_0
0116 
0117 #define EVENT_OBTAIN RTEMS_EVENT_1
0118 
0119 #define EVENT_OBTAIN_END RTEMS_EVENT_2
0120 
0121 #define EVENT_RELEASE RTEMS_EVENT_3
0122 
0123 #define EVENT_RELEASE_END RTEMS_EVENT_4
0124 
0125 typedef RtemsSemValPerf_Context Context;
0126 
0127 static void Send( const Context *ctx, rtems_event_set events )
0128 {
0129   SendEvents( ctx->worker_id, events );
0130 }
0131 
0132 static void Worker( rtems_task_argument arg )
0133 {
0134   Context *ctx;
0135 
0136   ctx = (Context *) arg;
0137 
0138   while ( true ) {
0139     rtems_event_set   events;
0140     rtems_status_code sc;
0141     T_ticks           ticks;
0142 
0143     sc = rtems_event_receive(
0144       RTEMS_ALL_EVENTS,
0145       RTEMS_EVENT_ANY | RTEMS_WAIT,
0146       RTEMS_NO_TIMEOUT,
0147       &events
0148     );
0149     ticks = T_tick();
0150     T_quiet_rsc_success( sc );
0151 
0152     if ( ( events & EVENT_END ) != 0 ) {
0153       ctx->end = ticks;
0154     }
0155 
0156     if ( ( events & EVENT_OBTAIN ) != 0 ) {
0157       sc = rtems_semaphore_obtain(
0158         ctx->mutex_id,
0159         RTEMS_WAIT,
0160         RTEMS_NO_TIMEOUT
0161       );
0162       ticks = T_tick();
0163       T_quiet_rsc_success( sc );
0164 
0165       if ( ( events & EVENT_OBTAIN_END ) != 0 ) {
0166         ctx->end = ticks;
0167       }
0168     }
0169 
0170     if ( ( events & EVENT_RELEASE ) != 0 ) {
0171       sc = rtems_semaphore_release( ctx->mutex_id );
0172       ticks = T_tick();
0173       T_quiet_rsc_success( sc );
0174 
0175       if ( ( events & EVENT_RELEASE_END ) != 0 ) {
0176         ctx->end = ticks;
0177       }
0178     }
0179   }
0180 }
0181 
0182 static void RtemsSemValPerf_Setup_Context( RtemsSemValPerf_Context *ctx )
0183 {
0184   T_measure_runtime_config config;
0185 
0186   memset( &config, 0, sizeof( config ) );
0187   config.sample_count = 100;
0188   ctx->request.arg = ctx;
0189   ctx->request.flags = T_MEASURE_RUNTIME_REPORT_SAMPLES;
0190   ctx->context = T_measure_runtime_create( &config );
0191   T_assert_not_null( ctx->context );
0192 }
0193 
0194 /**
0195  * @brief Create a mutex and a worker task.
0196  */
0197 static void RtemsSemValPerf_Setup( RtemsSemValPerf_Context *ctx )
0198 {
0199   SetSelfPriority( PRIO_NORMAL );
0200   ctx->mutex_id = CreateMutex();
0201   ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
0202   StartTask( ctx->worker_id, Worker, ctx );
0203 }
0204 
0205 static void RtemsSemValPerf_Setup_Wrap( void *arg )
0206 {
0207   RtemsSemValPerf_Context *ctx;
0208 
0209   ctx = arg;
0210   RtemsSemValPerf_Setup_Context( ctx );
0211   RtemsSemValPerf_Setup( ctx );
0212 }
0213 
0214 /**
0215  * @brief Delete the worker task and the mutex.
0216  */
0217 static void RtemsSemValPerf_Teardown( RtemsSemValPerf_Context *ctx )
0218 {
0219   DeleteTask( ctx->worker_id );
0220   DeleteMutex( ctx->mutex_id );
0221   RestoreRunnerPriority();
0222 }
0223 
0224 static void RtemsSemValPerf_Teardown_Wrap( void *arg )
0225 {
0226   RtemsSemValPerf_Context *ctx;
0227 
0228   ctx = arg;
0229   RtemsSemValPerf_Teardown( ctx );
0230 }
0231 
0232 static T_fixture RtemsSemValPerf_Fixture = {
0233   .setup = RtemsSemValPerf_Setup_Wrap,
0234   .stop = NULL,
0235   .teardown = RtemsSemValPerf_Teardown_Wrap,
0236   .scope = NULL,
0237   .initial_context = &RtemsSemValPerf_Instance
0238 };
0239 
0240 /**
0241  * @defgroup RtemsSemReqPerfMtxPiObtain spec:/rtems/sem/req/perf-mtx-pi-obtain
0242  *
0243  * @{
0244  */
0245 
0246 /**
0247  * @brief Obtain the available mutex.
0248  */
0249 static void RtemsSemReqPerfMtxPiObtain_Body( RtemsSemValPerf_Context *ctx )
0250 {
0251   ctx->status = rtems_semaphore_obtain(
0252     ctx->mutex_id,
0253     RTEMS_WAIT,
0254     RTEMS_NO_TIMEOUT
0255   );
0256 }
0257 
0258 static void RtemsSemReqPerfMtxPiObtain_Body_Wrap( void *arg )
0259 {
0260   RtemsSemValPerf_Context *ctx;
0261 
0262   ctx = arg;
0263   RtemsSemReqPerfMtxPiObtain_Body( ctx );
0264 }
0265 
0266 /**
0267  * @brief Release the mutex.  Discard samples interrupted by a clock tick.
0268  */
0269 static bool RtemsSemReqPerfMtxPiObtain_Teardown(
0270   RtemsSemValPerf_Context *ctx,
0271   T_ticks                 *delta,
0272   uint32_t                 tic,
0273   uint32_t                 toc,
0274   unsigned int             retry
0275 )
0276 {
0277   T_quiet_rsc_success( ctx->status );
0278 
0279   ReleaseMutex( ctx->mutex_id );
0280 
0281   return tic == toc;
0282 }
0283 
0284 static bool RtemsSemReqPerfMtxPiObtain_Teardown_Wrap(
0285   void        *arg,
0286   T_ticks     *delta,
0287   uint32_t     tic,
0288   uint32_t     toc,
0289   unsigned int retry
0290 )
0291 {
0292   RtemsSemValPerf_Context *ctx;
0293 
0294   ctx = arg;
0295   return RtemsSemReqPerfMtxPiObtain_Teardown( ctx, delta, tic, toc, retry );
0296 }
0297 
0298 /** @} */
0299 
0300 /**
0301  * @defgroup RtemsSemReqPerfMtxPiRelease \
0302  *   spec:/rtems/sem/req/perf-mtx-pi-release
0303  *
0304  * @{
0305  */
0306 
0307 /**
0308  * @brief Obtain the mutex.
0309  */
0310 static void RtemsSemReqPerfMtxPiRelease_Setup( RtemsSemValPerf_Context *ctx )
0311 {
0312   ObtainMutex( ctx->mutex_id );
0313 }
0314 
0315 static void RtemsSemReqPerfMtxPiRelease_Setup_Wrap( void *arg )
0316 {
0317   RtemsSemValPerf_Context *ctx;
0318 
0319   ctx = arg;
0320   RtemsSemReqPerfMtxPiRelease_Setup( ctx );
0321 }
0322 
0323 /**
0324  * @brief Release the mutex.
0325  */
0326 static void RtemsSemReqPerfMtxPiRelease_Body( RtemsSemValPerf_Context *ctx )
0327 {
0328   ctx->status = rtems_semaphore_release( ctx->mutex_id );
0329 }
0330 
0331 static void RtemsSemReqPerfMtxPiRelease_Body_Wrap( void *arg )
0332 {
0333   RtemsSemValPerf_Context *ctx;
0334 
0335   ctx = arg;
0336   RtemsSemReqPerfMtxPiRelease_Body( ctx );
0337 }
0338 
0339 /**
0340  * @brief Discard samples interrupted by a clock tick.
0341  */
0342 static bool RtemsSemReqPerfMtxPiRelease_Teardown(
0343   RtemsSemValPerf_Context *ctx,
0344   T_ticks                 *delta,
0345   uint32_t                 tic,
0346   uint32_t                 toc,
0347   unsigned int             retry
0348 )
0349 {
0350   T_quiet_rsc_success( ctx->status );
0351 
0352   return tic == toc;
0353 }
0354 
0355 static bool RtemsSemReqPerfMtxPiRelease_Teardown_Wrap(
0356   void        *arg,
0357   T_ticks     *delta,
0358   uint32_t     tic,
0359   uint32_t     toc,
0360   unsigned int retry
0361 )
0362 {
0363   RtemsSemValPerf_Context *ctx;
0364 
0365   ctx = arg;
0366   return RtemsSemReqPerfMtxPiRelease_Teardown( ctx, delta, tic, toc, retry );
0367 }
0368 
0369 /** @} */
0370 
0371 /**
0372  * @defgroup RtemsSemReqPerfMtxPiReleaseOne \
0373  *   spec:/rtems/sem/req/perf-mtx-pi-release-one
0374  *
0375  * @{
0376  */
0377 
0378 /**
0379  * @brief Let one task wait on the mutex.
0380  */
0381 static void RtemsSemReqPerfMtxPiReleaseOne_Setup(
0382   RtemsSemValPerf_Context *ctx
0383 )
0384 {
0385   SetSelfPriority( PRIO_HIGH );
0386   ObtainMutex( ctx->mutex_id );
0387   Send( ctx, EVENT_OBTAIN );
0388   Yield();
0389   Send( ctx, EVENT_RELEASE );
0390 }
0391 
0392 static void RtemsSemReqPerfMtxPiReleaseOne_Setup_Wrap( void *arg )
0393 {
0394   RtemsSemValPerf_Context *ctx;
0395 
0396   ctx = arg;
0397   RtemsSemReqPerfMtxPiReleaseOne_Setup( ctx );
0398 }
0399 
0400 /**
0401  * @brief Release the mutex.
0402  */
0403 static void RtemsSemReqPerfMtxPiReleaseOne_Body( RtemsSemValPerf_Context *ctx )
0404 {
0405   /*
0406    * The release will unblock the worker task which has our priority.  The
0407    * scheduler ensures FIFO ordering for ready threads of the same priority, so
0408    * the release will not preempt us.
0409    */
0410   ctx->status = rtems_semaphore_release( ctx->mutex_id );
0411 }
0412 
0413 static void RtemsSemReqPerfMtxPiReleaseOne_Body_Wrap( void *arg )
0414 {
0415   RtemsSemValPerf_Context *ctx;
0416 
0417   ctx = arg;
0418   RtemsSemReqPerfMtxPiReleaseOne_Body( ctx );
0419 }
0420 
0421 /**
0422  * @brief Restore the worker priority.  Discard samples interrupted by a clock
0423  *   tick.
0424  */
0425 static bool RtemsSemReqPerfMtxPiReleaseOne_Teardown(
0426   RtemsSemValPerf_Context *ctx,
0427   T_ticks                 *delta,
0428   uint32_t                 tic,
0429   uint32_t                 toc,
0430   unsigned int             retry
0431 )
0432 {
0433   T_quiet_rsc( ctx->status, RTEMS_SUCCESSFUL );
0434 
0435   SetSelfPriority( PRIO_NORMAL );
0436 
0437   return tic == toc;
0438 }
0439 
0440 static bool RtemsSemReqPerfMtxPiReleaseOne_Teardown_Wrap(
0441   void        *arg,
0442   T_ticks     *delta,
0443   uint32_t     tic,
0444   uint32_t     toc,
0445   unsigned int retry
0446 )
0447 {
0448   RtemsSemValPerf_Context *ctx;
0449 
0450   ctx = arg;
0451   return RtemsSemReqPerfMtxPiReleaseOne_Teardown(
0452     ctx,
0453     delta,
0454     tic,
0455     toc,
0456     retry
0457   );
0458 }
0459 
0460 /** @} */
0461 
0462 #if defined(RTEMS_SMP)
0463 /**
0464  * @defgroup RtemsSemReqPerfMtxPiReleaseOtherCpu \
0465  *   spec:/rtems/sem/req/perf-mtx-pi-release-other-cpu
0466  *
0467  * @{
0468  */
0469 
0470 /**
0471  * @brief Move worker to scheduler B.
0472  */
0473 static void RtemsSemReqPerfMtxPiReleaseOtherCpu_Prepare(
0474   RtemsSemValPerf_Context *ctx
0475 )
0476 {
0477   SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
0478 }
0479 
0480 /**
0481  * @brief Let one task wait on the mutex.
0482  */
0483 static void RtemsSemReqPerfMtxPiReleaseOtherCpu_Setup(
0484   RtemsSemValPerf_Context *ctx
0485 )
0486 {
0487   ObtainMutex( ctx->mutex_id );
0488   Send( ctx, EVENT_OBTAIN | EVENT_OBTAIN_END | EVENT_RELEASE );
0489   WaitForNextTask( 1, ctx->worker_id );
0490 }
0491 
0492 static void RtemsSemReqPerfMtxPiReleaseOtherCpu_Setup_Wrap( void *arg )
0493 {
0494   RtemsSemValPerf_Context *ctx;
0495 
0496   ctx = arg;
0497   RtemsSemReqPerfMtxPiReleaseOtherCpu_Setup( ctx );
0498 }
0499 
0500 /**
0501  * @brief Release the mutex.
0502  */
0503 static void RtemsSemReqPerfMtxPiReleaseOtherCpu_Body(
0504   RtemsSemValPerf_Context *ctx
0505 )
0506 {
0507   ctx->begin = T_tick();
0508   ctx->status = rtems_semaphore_release( ctx->mutex_id );
0509 }
0510 
0511 static void RtemsSemReqPerfMtxPiReleaseOtherCpu_Body_Wrap( void *arg )
0512 {
0513   RtemsSemValPerf_Context *ctx;
0514 
0515   ctx = arg;
0516   RtemsSemReqPerfMtxPiReleaseOtherCpu_Body( ctx );
0517 }
0518 
0519 /**
0520  * @brief Make sure the worker waits for the next event.  Set the measured
0521  *   runtime. Discard samples interrupted by a clock tick.
0522  */
0523 static bool RtemsSemReqPerfMtxPiReleaseOtherCpu_Teardown(
0524   RtemsSemValPerf_Context *ctx,
0525   T_ticks                 *delta,
0526   uint32_t                 tic,
0527   uint32_t                 toc,
0528   unsigned int             retry
0529 )
0530 {
0531   T_quiet_rsc( ctx->status, RTEMS_SUCCESSFUL );
0532 
0533   WaitForNextTask( 1, ctx->worker_id );
0534   *delta = ctx->end - ctx->begin;
0535 
0536   return tic == toc;
0537 }
0538 
0539 static bool RtemsSemReqPerfMtxPiReleaseOtherCpu_Teardown_Wrap(
0540   void        *arg,
0541   T_ticks     *delta,
0542   uint32_t     tic,
0543   uint32_t     toc,
0544   unsigned int retry
0545 )
0546 {
0547   RtemsSemValPerf_Context *ctx;
0548 
0549   ctx = arg;
0550   return RtemsSemReqPerfMtxPiReleaseOtherCpu_Teardown(
0551     ctx,
0552     delta,
0553     tic,
0554     toc,
0555     retry
0556   );
0557 }
0558 
0559 /**
0560  * @brief Move worker to scheduler A.
0561  */
0562 static void RtemsSemReqPerfMtxPiReleaseOtherCpu_Cleanup(
0563   RtemsSemValPerf_Context *ctx
0564 )
0565 {
0566   SetScheduler( ctx->worker_id, SCHEDULER_A_ID, PRIO_HIGH );
0567 }
0568 
0569 /** @} */
0570 #endif
0571 
0572 /**
0573  * @defgroup RtemsSemReqPerfMtxPiReleasePreempt \
0574  *   spec:/rtems/sem/req/perf-mtx-pi-release-preempt
0575  *
0576  * @{
0577  */
0578 
0579 /**
0580  * @brief Let one task wait on the mutex.
0581  */
0582 static void RtemsSemReqPerfMtxPiReleasePreempt_Setup(
0583   RtemsSemValPerf_Context *ctx
0584 )
0585 {
0586   ObtainMutex( ctx->mutex_id );
0587   Send( ctx, EVENT_OBTAIN | EVENT_OBTAIN_END | EVENT_RELEASE );
0588 }
0589 
0590 static void RtemsSemReqPerfMtxPiReleasePreempt_Setup_Wrap( void *arg )
0591 {
0592   RtemsSemValPerf_Context *ctx;
0593 
0594   ctx = arg;
0595   RtemsSemReqPerfMtxPiReleasePreempt_Setup( ctx );
0596 }
0597 
0598 /**
0599  * @brief Release the mutex.
0600  */
0601 static void RtemsSemReqPerfMtxPiReleasePreempt_Body(
0602   RtemsSemValPerf_Context *ctx
0603 )
0604 {
0605   ctx->begin = T_tick();
0606   ctx->status = rtems_semaphore_release( ctx->mutex_id );
0607 }
0608 
0609 static void RtemsSemReqPerfMtxPiReleasePreempt_Body_Wrap( void *arg )
0610 {
0611   RtemsSemValPerf_Context *ctx;
0612 
0613   ctx = arg;
0614   RtemsSemReqPerfMtxPiReleasePreempt_Body( ctx );
0615 }
0616 
0617 /**
0618  * @brief Set the measured runtime.  Discard samples interrupted by a clock
0619  *   tick.
0620  */
0621 static bool RtemsSemReqPerfMtxPiReleasePreempt_Teardown(
0622   RtemsSemValPerf_Context *ctx,
0623   T_ticks                 *delta,
0624   uint32_t                 tic,
0625   uint32_t                 toc,
0626   unsigned int             retry
0627 )
0628 {
0629   T_quiet_rsc( ctx->status, RTEMS_SUCCESSFUL );
0630 
0631   *delta = ctx->end - ctx->begin;
0632 
0633   return tic == toc;
0634 }
0635 
0636 static bool RtemsSemReqPerfMtxPiReleasePreempt_Teardown_Wrap(
0637   void        *arg,
0638   T_ticks     *delta,
0639   uint32_t     tic,
0640   uint32_t     toc,
0641   unsigned int retry
0642 )
0643 {
0644   RtemsSemValPerf_Context *ctx;
0645 
0646   ctx = arg;
0647   return RtemsSemReqPerfMtxPiReleasePreempt_Teardown(
0648     ctx,
0649     delta,
0650     tic,
0651     toc,
0652     retry
0653   );
0654 }
0655 
0656 /** @} */
0657 
0658 /**
0659  * @defgroup RtemsSemReqPerfMtxPiTry spec:/rtems/sem/req/perf-mtx-pi-try
0660  *
0661  * @{
0662  */
0663 
0664 /**
0665  * @brief Make the mutex unavailable.
0666  */
0667 static void RtemsSemReqPerfMtxPiTry_Prepare( RtemsSemValPerf_Context *ctx )
0668 {
0669   Send( ctx, EVENT_OBTAIN );
0670 }
0671 
0672 /**
0673  * @brief Try to obtain the unavailable mutex.
0674  */
0675 static void RtemsSemReqPerfMtxPiTry_Body( RtemsSemValPerf_Context *ctx )
0676 {
0677   ctx->status = rtems_semaphore_obtain( ctx->mutex_id, RTEMS_NO_WAIT, 0 );
0678 }
0679 
0680 static void RtemsSemReqPerfMtxPiTry_Body_Wrap( void *arg )
0681 {
0682   RtemsSemValPerf_Context *ctx;
0683 
0684   ctx = arg;
0685   RtemsSemReqPerfMtxPiTry_Body( ctx );
0686 }
0687 
0688 /**
0689  * @brief Discard samples interrupted by a clock tick.
0690  */
0691 static bool RtemsSemReqPerfMtxPiTry_Teardown(
0692   RtemsSemValPerf_Context *ctx,
0693   T_ticks                 *delta,
0694   uint32_t                 tic,
0695   uint32_t                 toc,
0696   unsigned int             retry
0697 )
0698 {
0699   T_quiet_rsc( ctx->status, RTEMS_UNSATISFIED );
0700 
0701   return tic == toc;
0702 }
0703 
0704 static bool RtemsSemReqPerfMtxPiTry_Teardown_Wrap(
0705   void        *arg,
0706   T_ticks     *delta,
0707   uint32_t     tic,
0708   uint32_t     toc,
0709   unsigned int retry
0710 )
0711 {
0712   RtemsSemValPerf_Context *ctx;
0713 
0714   ctx = arg;
0715   return RtemsSemReqPerfMtxPiTry_Teardown( ctx, delta, tic, toc, retry );
0716 }
0717 
0718 /**
0719  * @brief Make the mutex available.
0720  */
0721 static void RtemsSemReqPerfMtxPiTry_Cleanup( RtemsSemValPerf_Context *ctx )
0722 {
0723   Send( ctx, EVENT_RELEASE );
0724 }
0725 
0726 /** @} */
0727 
0728 /**
0729  * @defgroup RtemsSemReqPerfMtxPiWaitForever \
0730  *   spec:/rtems/sem/req/perf-mtx-pi-wait-forever
0731  *
0732  * @{
0733  */
0734 
0735 /**
0736  * @brief Make the mutex unavailable.
0737  */
0738 static void RtemsSemReqPerfMtxPiWaitForever_Setup(
0739   RtemsSemValPerf_Context *ctx
0740 )
0741 {
0742   Send( ctx, EVENT_OBTAIN );
0743   SetSelfPriority( PRIO_VERY_HIGH );
0744   Send( ctx, EVENT_END | EVENT_RELEASE );
0745 }
0746 
0747 static void RtemsSemReqPerfMtxPiWaitForever_Setup_Wrap( void *arg )
0748 {
0749   RtemsSemValPerf_Context *ctx;
0750 
0751   ctx = arg;
0752   RtemsSemReqPerfMtxPiWaitForever_Setup( ctx );
0753 }
0754 
0755 /**
0756  * @brief Obtain the unavailable mutex and wait forever.
0757  */
0758 static void RtemsSemReqPerfMtxPiWaitForever_Body(
0759   RtemsSemValPerf_Context *ctx
0760 )
0761 {
0762   ctx->begin = T_tick();
0763   ctx->status = rtems_semaphore_obtain(
0764     ctx->mutex_id,
0765     RTEMS_WAIT,
0766     RTEMS_NO_TIMEOUT
0767   );
0768 }
0769 
0770 static void RtemsSemReqPerfMtxPiWaitForever_Body_Wrap( void *arg )
0771 {
0772   RtemsSemValPerf_Context *ctx;
0773 
0774   ctx = arg;
0775   RtemsSemReqPerfMtxPiWaitForever_Body( ctx );
0776 }
0777 
0778 /**
0779  * @brief Set the measured runtime.  Restore the worker priority.  Release the
0780  *   mutex. Discard samples interrupted by a clock tick.
0781  */
0782 static bool RtemsSemReqPerfMtxPiWaitForever_Teardown(
0783   RtemsSemValPerf_Context *ctx,
0784   T_ticks                 *delta,
0785   uint32_t                 tic,
0786   uint32_t                 toc,
0787   unsigned int             retry
0788 )
0789 {
0790   T_quiet_rsc( ctx->status, RTEMS_SUCCESSFUL );
0791 
0792   *delta = ctx->end - ctx->begin;
0793   ReleaseMutex( ctx->mutex_id );
0794   SetSelfPriority( PRIO_NORMAL );
0795 
0796   return tic == toc;
0797 }
0798 
0799 static bool RtemsSemReqPerfMtxPiWaitForever_Teardown_Wrap(
0800   void        *arg,
0801   T_ticks     *delta,
0802   uint32_t     tic,
0803   uint32_t     toc,
0804   unsigned int retry
0805 )
0806 {
0807   RtemsSemValPerf_Context *ctx;
0808 
0809   ctx = arg;
0810   return RtemsSemReqPerfMtxPiWaitForever_Teardown(
0811     ctx,
0812     delta,
0813     tic,
0814     toc,
0815     retry
0816   );
0817 }
0818 
0819 /** @} */
0820 
0821 /**
0822  * @defgroup RtemsSemReqPerfMtxPiWaitTimed \
0823  *   spec:/rtems/sem/req/perf-mtx-pi-wait-timed
0824  *
0825  * @{
0826  */
0827 
0828 /**
0829  * @brief Make the mutex unavailable.
0830  */
0831 static void RtemsSemReqPerfMtxPiWaitTimed_Setup( RtemsSemValPerf_Context *ctx )
0832 {
0833   Send( ctx, EVENT_OBTAIN );
0834   SetSelfPriority( PRIO_VERY_HIGH );
0835   Send( ctx, EVENT_END | EVENT_RELEASE );
0836 }
0837 
0838 static void RtemsSemReqPerfMtxPiWaitTimed_Setup_Wrap( void *arg )
0839 {
0840   RtemsSemValPerf_Context *ctx;
0841 
0842   ctx = arg;
0843   RtemsSemReqPerfMtxPiWaitTimed_Setup( ctx );
0844 }
0845 
0846 /**
0847  * @brief Obtain the unavailable mutex and wait forever.
0848  */
0849 static void RtemsSemReqPerfMtxPiWaitTimed_Body( RtemsSemValPerf_Context *ctx )
0850 {
0851   ctx->begin = T_tick();
0852   ctx->status = rtems_semaphore_obtain(
0853     ctx->mutex_id,
0854     RTEMS_WAIT,
0855     UINT32_MAX
0856   );
0857 }
0858 
0859 static void RtemsSemReqPerfMtxPiWaitTimed_Body_Wrap( void *arg )
0860 {
0861   RtemsSemValPerf_Context *ctx;
0862 
0863   ctx = arg;
0864   RtemsSemReqPerfMtxPiWaitTimed_Body( ctx );
0865 }
0866 
0867 /**
0868  * @brief Set the measured runtime.  Restore the worker priority.  Release the
0869  *   mutex. Discard samples interrupted by a clock tick.
0870  */
0871 static bool RtemsSemReqPerfMtxPiWaitTimed_Teardown(
0872   RtemsSemValPerf_Context *ctx,
0873   T_ticks                 *delta,
0874   uint32_t                 tic,
0875   uint32_t                 toc,
0876   unsigned int             retry
0877 )
0878 {
0879   T_quiet_rsc( ctx->status, RTEMS_SUCCESSFUL );
0880 
0881   *delta = ctx->end - ctx->begin;
0882   ReleaseMutex( ctx->mutex_id );
0883   SetSelfPriority( PRIO_NORMAL );
0884 
0885   return tic == toc;
0886 }
0887 
0888 static bool RtemsSemReqPerfMtxPiWaitTimed_Teardown_Wrap(
0889   void        *arg,
0890   T_ticks     *delta,
0891   uint32_t     tic,
0892   uint32_t     toc,
0893   unsigned int retry
0894 )
0895 {
0896   RtemsSemValPerf_Context *ctx;
0897 
0898   ctx = arg;
0899   return RtemsSemReqPerfMtxPiWaitTimed_Teardown( ctx, delta, tic, toc, retry );
0900 }
0901 
0902 /** @} */
0903 
0904 /**
0905  * @fn void T_case_body_RtemsSemValPerf( void )
0906  */
0907 T_TEST_CASE_FIXTURE( RtemsSemValPerf, &RtemsSemValPerf_Fixture )
0908 {
0909   RtemsSemValPerf_Context *ctx;
0910 
0911   ctx = T_fixture_context();
0912 
0913   ctx->request.name = "RtemsSemReqPerfMtxPiObtain";
0914   ctx->request.setup = NULL;
0915   ctx->request.body = RtemsSemReqPerfMtxPiObtain_Body_Wrap;
0916   ctx->request.teardown = RtemsSemReqPerfMtxPiObtain_Teardown_Wrap;
0917   T_measure_runtime( ctx->context, &ctx->request );
0918 
0919   ctx->request.name = "RtemsSemReqPerfMtxPiRelease";
0920   ctx->request.setup = RtemsSemReqPerfMtxPiRelease_Setup_Wrap;
0921   ctx->request.body = RtemsSemReqPerfMtxPiRelease_Body_Wrap;
0922   ctx->request.teardown = RtemsSemReqPerfMtxPiRelease_Teardown_Wrap;
0923   T_measure_runtime( ctx->context, &ctx->request );
0924 
0925   ctx->request.name = "RtemsSemReqPerfMtxPiReleaseOne";
0926   ctx->request.setup = RtemsSemReqPerfMtxPiReleaseOne_Setup_Wrap;
0927   ctx->request.body = RtemsSemReqPerfMtxPiReleaseOne_Body_Wrap;
0928   ctx->request.teardown = RtemsSemReqPerfMtxPiReleaseOne_Teardown_Wrap;
0929   T_measure_runtime( ctx->context, &ctx->request );
0930 
0931   #if defined(RTEMS_SMP)
0932   RtemsSemReqPerfMtxPiReleaseOtherCpu_Prepare( ctx );
0933   ctx->request.name = "RtemsSemReqPerfMtxPiReleaseOtherCpu";
0934   ctx->request.setup = RtemsSemReqPerfMtxPiReleaseOtherCpu_Setup_Wrap;
0935   ctx->request.body = RtemsSemReqPerfMtxPiReleaseOtherCpu_Body_Wrap;
0936   ctx->request.teardown = RtemsSemReqPerfMtxPiReleaseOtherCpu_Teardown_Wrap;
0937   T_measure_runtime( ctx->context, &ctx->request );
0938   RtemsSemReqPerfMtxPiReleaseOtherCpu_Cleanup( ctx );
0939   #endif
0940 
0941   ctx->request.name = "RtemsSemReqPerfMtxPiReleasePreempt";
0942   ctx->request.setup = RtemsSemReqPerfMtxPiReleasePreempt_Setup_Wrap;
0943   ctx->request.body = RtemsSemReqPerfMtxPiReleasePreempt_Body_Wrap;
0944   ctx->request.teardown = RtemsSemReqPerfMtxPiReleasePreempt_Teardown_Wrap;
0945   T_measure_runtime( ctx->context, &ctx->request );
0946 
0947   RtemsSemReqPerfMtxPiTry_Prepare( ctx );
0948   ctx->request.name = "RtemsSemReqPerfMtxPiTry";
0949   ctx->request.setup = NULL;
0950   ctx->request.body = RtemsSemReqPerfMtxPiTry_Body_Wrap;
0951   ctx->request.teardown = RtemsSemReqPerfMtxPiTry_Teardown_Wrap;
0952   T_measure_runtime( ctx->context, &ctx->request );
0953   RtemsSemReqPerfMtxPiTry_Cleanup( ctx );
0954 
0955   ctx->request.name = "RtemsSemReqPerfMtxPiWaitForever";
0956   ctx->request.setup = RtemsSemReqPerfMtxPiWaitForever_Setup_Wrap;
0957   ctx->request.body = RtemsSemReqPerfMtxPiWaitForever_Body_Wrap;
0958   ctx->request.teardown = RtemsSemReqPerfMtxPiWaitForever_Teardown_Wrap;
0959   T_measure_runtime( ctx->context, &ctx->request );
0960 
0961   ctx->request.name = "RtemsSemReqPerfMtxPiWaitTimed";
0962   ctx->request.setup = RtemsSemReqPerfMtxPiWaitTimed_Setup_Wrap;
0963   ctx->request.body = RtemsSemReqPerfMtxPiWaitTimed_Body_Wrap;
0964   ctx->request.teardown = RtemsSemReqPerfMtxPiWaitTimed_Teardown_Wrap;
0965   T_measure_runtime( ctx->context, &ctx->request );
0966 }
0967 
0968 /** @} */