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