source: rtems/testsuites/validation/tc-event-performance.c @ 74a6b33f

Last change on this file since 74a6b33f was 74a6b33f, checked in by Sebastian Huber <sebastian.huber@…>, on 03/17/23 at 14:52:33

validation: Replace enum Event with defines

There is a Doxygen limitation that all compound names (enum, struct,
class, union, group) within a project must be unique.

Update #3716.

  • Property mode set to 100644
File size: 13.2 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RtemsEventValPerf
7 */
8
9/*
10 * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 *    notice, this list of conditions and the following disclaimer in the
19 *    documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/*
35 * This file is part of the RTEMS quality process and was automatically
36 * generated.  If you find something that needs to be fixed or
37 * worded better please post a report or patch to an RTEMS mailing list
38 * or raise a bug report:
39 *
40 * https://www.rtems.org/bugs.html
41 *
42 * For information on updating and regenerating please refer to the How-To
43 * section in the Software Requirements Engineering chapter of the
44 * RTEMS Software Engineering manual.  The manual is provided as a part of
45 * a release.  For development sources please refer to the online
46 * documentation at:
47 *
48 * https://docs.rtems.org
49 */
50
51#ifdef HAVE_CONFIG_H
52#include "config.h"
53#endif
54
55#include <rtems.h>
56
57#include "tx-support.h"
58
59#include <rtems/test.h>
60
61/**
62 * @defgroup RtemsEventValPerf spec:/rtems/event/val/perf
63 *
64 * @ingroup TestsuitesPerformanceNoClock0
65 *
66 * @brief This test case provides a context to run @ref RTEMSAPIClassicEvent
67 *   performance tests.
68 *
69 * @{
70 */
71
72/**
73 * @brief Test context for spec:/rtems/event/val/perf test case.
74 */
75typedef struct {
76  /**
77   * @brief This member provides a worker identifier.
78   */
79  rtems_id worker_id;
80
81  /**
82   * @brief This member provides a status code.
83   */
84  rtems_status_code status;
85
86  /**
87   * @brief This member references the measure runtime context.
88   */
89  T_measure_runtime_context *context;
90
91  /**
92   * @brief This member provides the measure runtime request.
93   */
94  T_measure_runtime_request request;
95
96  /**
97   * @brief This member provides an optional measurement begin time point.
98   */
99  T_ticks begin;
100
101  /**
102   * @brief This member provides an optional measurement end time point.
103   */
104  T_ticks end;
105} RtemsEventValPerf_Context;
106
107static RtemsEventValPerf_Context
108  RtemsEventValPerf_Instance;
109
110#define EVENT_END RTEMS_EVENT_0
111
112#define EVENT_OTHER RTEMS_EVENT_1
113
114typedef RtemsEventValPerf_Context Context;
115
116static void Send( const Context *ctx, rtems_event_set events )
117{
118  SendEvents( ctx->worker_id, events );
119}
120
121static void Satisfy( void *arg )
122{
123  Context *ctx;
124
125  ctx = arg;
126  ctx->begin = T_tick();
127  ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
128}
129
130static void Worker( rtems_task_argument arg )
131{
132  Context *ctx;
133
134  ctx = (Context *) arg;
135
136  while ( true ) {
137    rtems_event_set   events;
138    rtems_status_code sc;
139    T_ticks           ticks;
140
141    sc = rtems_event_receive(
142      EVENT_END | EVENT_OTHER,
143      RTEMS_EVENT_ALL | RTEMS_WAIT,
144      RTEMS_NO_TIMEOUT,
145      &events
146    );
147    ticks = T_tick();
148    T_quiet_rsc_success( sc );
149
150    if ( ( events & EVENT_END ) != 0 ) {
151      ctx->end = ticks;
152    }
153  }
154}
155
156static void RtemsEventValPerf_Setup_Context( RtemsEventValPerf_Context *ctx )
157{
158  T_measure_runtime_config config;
159
160  memset( &config, 0, sizeof( config ) );
161  config.sample_count = 100;
162  ctx->request.arg = ctx;
163  ctx->request.flags = T_MEASURE_RUNTIME_REPORT_SAMPLES;
164  ctx->context = T_measure_runtime_create( &config );
165  T_assert_not_null( ctx->context );
166}
167
168/**
169 * @brief Create a mutex and a worker task.
170 */
171static void RtemsEventValPerf_Setup( RtemsEventValPerf_Context *ctx )
172{
173  SetSelfPriority( PRIO_NORMAL );
174  ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
175  StartTask( ctx->worker_id, Worker, ctx );
176}
177
178static void RtemsEventValPerf_Setup_Wrap( void *arg )
179{
180  RtemsEventValPerf_Context *ctx;
181
182  ctx = arg;
183  RtemsEventValPerf_Setup_Context( ctx );
184  RtemsEventValPerf_Setup( ctx );
185}
186
187/**
188 * @brief Delete the worker task and the mutex.
189 */
190static void RtemsEventValPerf_Teardown( RtemsEventValPerf_Context *ctx )
191{
192  DeleteTask( ctx->worker_id );
193  RestoreRunnerPriority();
194}
195
196static void RtemsEventValPerf_Teardown_Wrap( void *arg )
197{
198  RtemsEventValPerf_Context *ctx;
199
200  ctx = arg;
201  RtemsEventValPerf_Teardown( ctx );
202}
203
204static T_fixture RtemsEventValPerf_Fixture = {
205  .setup = RtemsEventValPerf_Setup_Wrap,
206  .stop = NULL,
207  .teardown = RtemsEventValPerf_Teardown_Wrap,
208  .scope = NULL,
209  .initial_context = &RtemsEventValPerf_Instance
210};
211
212/**
213 * @brief Send two events from with interrupt context.  Satisfy the event
214 *   condition.
215 */
216static void RtemsEventReqPerfIsrPreempt_Body( RtemsEventValPerf_Context *ctx )
217{
218  CallWithinISR( Satisfy, ctx );
219}
220
221static void RtemsEventReqPerfIsrPreempt_Body_Wrap( void *arg )
222{
223  RtemsEventValPerf_Context *ctx;
224
225  ctx = arg;
226  RtemsEventReqPerfIsrPreempt_Body( ctx );
227}
228
229/**
230 * @brief Set the measured runtime.  Discard samples interrupted by a clock
231 *   tick.
232 */
233static bool RtemsEventReqPerfIsrPreempt_Teardown(
234  RtemsEventValPerf_Context *ctx,
235  T_ticks                   *delta,
236  uint32_t                   tic,
237  uint32_t                   toc,
238  unsigned int               retry
239)
240{
241  T_quiet_rsc_success( ctx->status );
242
243  *delta = ctx->end - ctx->begin;
244
245  return tic == toc;
246}
247
248static bool RtemsEventReqPerfIsrPreempt_Teardown_Wrap(
249  void        *arg,
250  T_ticks     *delta,
251  uint32_t     tic,
252  uint32_t     toc,
253  unsigned int retry
254)
255{
256  RtemsEventValPerf_Context *ctx;
257
258  ctx = arg;
259  return RtemsEventReqPerfIsrPreempt_Teardown( ctx, delta, tic, toc, retry );
260}
261
262/**
263 * @brief Lower the worker priority.
264 */
265static void RtemsEventReqPerfOther_Setup( RtemsEventValPerf_Context *ctx )
266{
267  SetPriority( ctx->worker_id, PRIO_LOW );
268}
269
270static void RtemsEventReqPerfOther_Setup_Wrap( void *arg )
271{
272  RtemsEventValPerf_Context *ctx;
273
274  ctx = arg;
275  RtemsEventReqPerfOther_Setup( ctx );
276}
277
278/**
279 * @brief Send two events.  Satisfy the event condition.
280 */
281static void RtemsEventReqPerfOther_Body( RtemsEventValPerf_Context *ctx )
282{
283  ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
284}
285
286static void RtemsEventReqPerfOther_Body_Wrap( void *arg )
287{
288  RtemsEventValPerf_Context *ctx;
289
290  ctx = arg;
291  RtemsEventReqPerfOther_Body( ctx );
292}
293
294/**
295 * @brief Restore the worker priority.  Discard samples interrupted by a clock
296 *   tick.
297 */
298static bool RtemsEventReqPerfOther_Teardown(
299  RtemsEventValPerf_Context *ctx,
300  T_ticks                   *delta,
301  uint32_t                   tic,
302  uint32_t                   toc,
303  unsigned int               retry
304)
305{
306  T_quiet_rsc_success( ctx->status );
307
308  SetPriority( ctx->worker_id, PRIO_HIGH );
309
310  return tic == toc;
311}
312
313static bool RtemsEventReqPerfOther_Teardown_Wrap(
314  void        *arg,
315  T_ticks     *delta,
316  uint32_t     tic,
317  uint32_t     toc,
318  unsigned int retry
319)
320{
321  RtemsEventValPerf_Context *ctx;
322
323  ctx = arg;
324  return RtemsEventReqPerfOther_Teardown( ctx, delta, tic, toc, retry );
325}
326
327#if defined(RTEMS_SMP)
328/**
329 * @brief Move worker to scheduler B.
330 */
331static void RtemsEventReqPerfOtherCpu_Prepare( RtemsEventValPerf_Context *ctx )
332{
333  SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
334}
335
336/**
337 * @brief Send two events.  Satisfy the event condition.
338 */
339static void RtemsEventReqPerfOtherCpu_Body( RtemsEventValPerf_Context *ctx )
340{
341  ctx->begin = T_tick();
342  ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
343}
344
345static void RtemsEventReqPerfOtherCpu_Body_Wrap( void *arg )
346{
347  RtemsEventValPerf_Context *ctx;
348
349  ctx = arg;
350  RtemsEventReqPerfOtherCpu_Body( ctx );
351}
352
353/**
354 * @brief Make sure the worker waits for the next event.  Set the measured
355 *   runtime. Discard samples interrupted by a clock tick.
356 */
357static bool RtemsEventReqPerfOtherCpu_Teardown(
358  RtemsEventValPerf_Context *ctx,
359  T_ticks                   *delta,
360  uint32_t                   tic,
361  uint32_t                   toc,
362  unsigned int               retry
363)
364{
365  T_quiet_rsc_success( ctx->status );
366
367  WaitForNextTask( 1, ctx->worker_id );
368  *delta = ctx->end - ctx->begin;
369
370  return tic == toc;
371}
372
373static bool RtemsEventReqPerfOtherCpu_Teardown_Wrap(
374  void        *arg,
375  T_ticks     *delta,
376  uint32_t     tic,
377  uint32_t     toc,
378  unsigned int retry
379)
380{
381  RtemsEventValPerf_Context *ctx;
382
383  ctx = arg;
384  return RtemsEventReqPerfOtherCpu_Teardown( ctx, delta, tic, toc, retry );
385}
386
387/**
388 * @brief Move worker to scheduler A.
389 */
390static void RtemsEventReqPerfOtherCpu_Cleanup( RtemsEventValPerf_Context *ctx )
391{
392  SetScheduler( ctx->worker_id, SCHEDULER_A_ID, PRIO_HIGH );
393}
394#endif
395
396/**
397 * @brief Send an event.  Do not satisfy the event condition.
398 */
399static void RtemsEventReqPerfOtherNotSatisfied_Body(
400  RtemsEventValPerf_Context *ctx
401)
402{
403  ctx->status = rtems_event_send( ctx->worker_id, EVENT_OTHER );
404}
405
406static void RtemsEventReqPerfOtherNotSatisfied_Body_Wrap( void *arg )
407{
408  RtemsEventValPerf_Context *ctx;
409
410  ctx = arg;
411  RtemsEventReqPerfOtherNotSatisfied_Body( ctx );
412}
413
414/**
415 * @brief Let the worker wait for the next set of events.  Discard samples
416 *   interrupted by a clock tick.
417 */
418static bool RtemsEventReqPerfOtherNotSatisfied_Teardown(
419  RtemsEventValPerf_Context *ctx,
420  T_ticks                   *delta,
421  uint32_t                   tic,
422  uint32_t                   toc,
423  unsigned int               retry
424)
425{
426  T_quiet_rsc_success( ctx->status );
427
428  Send( ctx, EVENT_END );
429
430  return tic == toc;
431}
432
433static bool RtemsEventReqPerfOtherNotSatisfied_Teardown_Wrap(
434  void        *arg,
435  T_ticks     *delta,
436  uint32_t     tic,
437  uint32_t     toc,
438  unsigned int retry
439)
440{
441  RtemsEventValPerf_Context *ctx;
442
443  ctx = arg;
444  return RtemsEventReqPerfOtherNotSatisfied_Teardown(
445    ctx,
446    delta,
447    tic,
448    toc,
449    retry
450  );
451}
452
453/**
454 * @brief Send two events.  Satisfy the event condition.
455 */
456static void RtemsEventReqPerfOtherPreempt_Body(
457  RtemsEventValPerf_Context *ctx
458)
459{
460  ctx->begin = T_tick();
461  ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
462}
463
464static void RtemsEventReqPerfOtherPreempt_Body_Wrap( void *arg )
465{
466  RtemsEventValPerf_Context *ctx;
467
468  ctx = arg;
469  RtemsEventReqPerfOtherPreempt_Body( ctx );
470}
471
472/**
473 * @brief Set the measured runtime.  Discard samples interrupted by a clock
474 *   tick.
475 */
476static bool RtemsEventReqPerfOtherPreempt_Teardown(
477  RtemsEventValPerf_Context *ctx,
478  T_ticks                   *delta,
479  uint32_t                   tic,
480  uint32_t                   toc,
481  unsigned int               retry
482)
483{
484  T_quiet_rsc_success( ctx->status );
485
486  *delta = ctx->end - ctx->begin;
487
488  return tic == toc;
489}
490
491static bool RtemsEventReqPerfOtherPreempt_Teardown_Wrap(
492  void        *arg,
493  T_ticks     *delta,
494  uint32_t     tic,
495  uint32_t     toc,
496  unsigned int retry
497)
498{
499  RtemsEventValPerf_Context *ctx;
500
501  ctx = arg;
502  return RtemsEventReqPerfOtherPreempt_Teardown( ctx, delta, tic, toc, retry );
503}
504
505/**
506 * @fn void T_case_body_RtemsEventValPerf( void )
507 */
508T_TEST_CASE_FIXTURE( RtemsEventValPerf, &RtemsEventValPerf_Fixture )
509{
510  RtemsEventValPerf_Context *ctx;
511
512  ctx = T_fixture_context();
513
514  ctx->request.name = "RtemsEventReqPerfIsrPreempt";
515  ctx->request.setup = NULL;
516  ctx->request.body = RtemsEventReqPerfIsrPreempt_Body_Wrap;
517  ctx->request.teardown = RtemsEventReqPerfIsrPreempt_Teardown_Wrap;
518  T_measure_runtime( ctx->context, &ctx->request );
519
520  ctx->request.name = "RtemsEventReqPerfOther";
521  ctx->request.setup = RtemsEventReqPerfOther_Setup_Wrap;
522  ctx->request.body = RtemsEventReqPerfOther_Body_Wrap;
523  ctx->request.teardown = RtemsEventReqPerfOther_Teardown_Wrap;
524  T_measure_runtime( ctx->context, &ctx->request );
525
526  #if defined(RTEMS_SMP)
527  RtemsEventReqPerfOtherCpu_Prepare( ctx );
528  ctx->request.name = "RtemsEventReqPerfOtherCpu";
529  ctx->request.setup = NULL;
530  ctx->request.body = RtemsEventReqPerfOtherCpu_Body_Wrap;
531  ctx->request.teardown = RtemsEventReqPerfOtherCpu_Teardown_Wrap;
532  T_measure_runtime( ctx->context, &ctx->request );
533  RtemsEventReqPerfOtherCpu_Cleanup( ctx );
534  #endif
535
536  ctx->request.name = "RtemsEventReqPerfOtherNotSatisfied";
537  ctx->request.setup = NULL;
538  ctx->request.body = RtemsEventReqPerfOtherNotSatisfied_Body_Wrap;
539  ctx->request.teardown = RtemsEventReqPerfOtherNotSatisfied_Teardown_Wrap;
540  T_measure_runtime( ctx->context, &ctx->request );
541
542  ctx->request.name = "RtemsEventReqPerfOtherPreempt";
543  ctx->request.setup = NULL;
544  ctx->request.body = RtemsEventReqPerfOtherPreempt_Body_Wrap;
545  ctx->request.teardown = RtemsEventReqPerfOtherPreempt_Teardown_Wrap;
546  T_measure_runtime( ctx->context, &ctx->request );
547}
548
549/** @} */
Note: See TracBrowser for help on using the repository browser.