source: rtems/testsuites/validation/tc-event-performance.c @ 9bfe5f5

Last change on this file since 9bfe5f5 was 9bfe5f5, checked in by Sebastian Huber <sebastian.huber@…>, on 02/14/23 at 14:59:22

validation: Derive names from item UIDs

Use the item UID converted to CamelCase for Doxygen group names and
testsuite names.

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
110typedef RtemsEventValPerf_Context Context;
111
112typedef enum {
113  EVENT_END = RTEMS_EVENT_0,
114  EVENT_OTHER = RTEMS_EVENT_1
115} Event;
116
117static void Send( const Context *ctx, rtems_event_set events )
118{
119  SendEvents( ctx->worker_id, events );
120}
121
122static void Satisfy( void *arg )
123{
124  Context *ctx;
125
126  ctx = arg;
127  ctx->begin = T_tick();
128  ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
129}
130
131static void Worker( rtems_task_argument arg )
132{
133  Context *ctx;
134
135  ctx = (Context *) arg;
136
137  while ( true ) {
138    rtems_event_set   events;
139    rtems_status_code sc;
140    T_ticks           ticks;
141
142    sc = rtems_event_receive(
143      EVENT_END | EVENT_OTHER,
144      RTEMS_EVENT_ALL | RTEMS_WAIT,
145      RTEMS_NO_TIMEOUT,
146      &events
147    );
148    ticks = T_tick();
149    T_quiet_rsc_success( sc );
150
151    if ( ( events & EVENT_END ) != 0 ) {
152      ctx->end = ticks;
153    }
154  }
155}
156
157static void RtemsEventValPerf_Setup_Context( RtemsEventValPerf_Context *ctx )
158{
159  T_measure_runtime_config config;
160
161  memset( &config, 0, sizeof( config ) );
162  config.sample_count = 100;
163  ctx->request.arg = ctx;
164  ctx->request.flags = T_MEASURE_RUNTIME_REPORT_SAMPLES;
165  ctx->context = T_measure_runtime_create( &config );
166  T_assert_not_null( ctx->context );
167}
168
169/**
170 * @brief Create a mutex and a worker task.
171 */
172static void RtemsEventValPerf_Setup( RtemsEventValPerf_Context *ctx )
173{
174  SetSelfPriority( PRIO_NORMAL );
175  ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
176  StartTask( ctx->worker_id, Worker, ctx );
177}
178
179static void RtemsEventValPerf_Setup_Wrap( void *arg )
180{
181  RtemsEventValPerf_Context *ctx;
182
183  ctx = arg;
184  RtemsEventValPerf_Setup_Context( ctx );
185  RtemsEventValPerf_Setup( ctx );
186}
187
188/**
189 * @brief Delete the worker task and the mutex.
190 */
191static void RtemsEventValPerf_Teardown( RtemsEventValPerf_Context *ctx )
192{
193  DeleteTask( ctx->worker_id );
194  RestoreRunnerPriority();
195}
196
197static void RtemsEventValPerf_Teardown_Wrap( void *arg )
198{
199  RtemsEventValPerf_Context *ctx;
200
201  ctx = arg;
202  RtemsEventValPerf_Teardown( ctx );
203}
204
205static T_fixture RtemsEventValPerf_Fixture = {
206  .setup = RtemsEventValPerf_Setup_Wrap,
207  .stop = NULL,
208  .teardown = RtemsEventValPerf_Teardown_Wrap,
209  .scope = NULL,
210  .initial_context = &RtemsEventValPerf_Instance
211};
212
213/**
214 * @brief Send two events from with interrupt context.  Satisfy the event
215 *   condition.
216 */
217static void RtemsEventReqPerfIsrPreempt_Body( RtemsEventValPerf_Context *ctx )
218{
219  CallWithinISR( Satisfy, ctx );
220}
221
222static void RtemsEventReqPerfIsrPreempt_Body_Wrap( void *arg )
223{
224  RtemsEventValPerf_Context *ctx;
225
226  ctx = arg;
227  RtemsEventReqPerfIsrPreempt_Body( ctx );
228}
229
230/**
231 * @brief Set the measured runtime.  Discard samples interrupted by a clock
232 *   tick.
233 */
234static bool RtemsEventReqPerfIsrPreempt_Teardown(
235  RtemsEventValPerf_Context *ctx,
236  T_ticks                   *delta,
237  uint32_t                   tic,
238  uint32_t                   toc,
239  unsigned int               retry
240)
241{
242  T_quiet_rsc_success( ctx->status );
243
244  *delta = ctx->end - ctx->begin;
245
246  return tic == toc;
247}
248
249static bool RtemsEventReqPerfIsrPreempt_Teardown_Wrap(
250  void        *arg,
251  T_ticks     *delta,
252  uint32_t     tic,
253  uint32_t     toc,
254  unsigned int retry
255)
256{
257  RtemsEventValPerf_Context *ctx;
258
259  ctx = arg;
260  return RtemsEventReqPerfIsrPreempt_Teardown( ctx, delta, tic, toc, retry );
261}
262
263/**
264 * @brief Lower the worker priority.
265 */
266static void RtemsEventReqPerfOther_Setup( RtemsEventValPerf_Context *ctx )
267{
268  SetPriority( ctx->worker_id, PRIO_LOW );
269}
270
271static void RtemsEventReqPerfOther_Setup_Wrap( void *arg )
272{
273  RtemsEventValPerf_Context *ctx;
274
275  ctx = arg;
276  RtemsEventReqPerfOther_Setup( ctx );
277}
278
279/**
280 * @brief Send two events.  Satisfy the event condition.
281 */
282static void RtemsEventReqPerfOther_Body( RtemsEventValPerf_Context *ctx )
283{
284  ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
285}
286
287static void RtemsEventReqPerfOther_Body_Wrap( void *arg )
288{
289  RtemsEventValPerf_Context *ctx;
290
291  ctx = arg;
292  RtemsEventReqPerfOther_Body( ctx );
293}
294
295/**
296 * @brief Restore the worker priority.  Discard samples interrupted by a clock
297 *   tick.
298 */
299static bool RtemsEventReqPerfOther_Teardown(
300  RtemsEventValPerf_Context *ctx,
301  T_ticks                   *delta,
302  uint32_t                   tic,
303  uint32_t                   toc,
304  unsigned int               retry
305)
306{
307  T_quiet_rsc_success( ctx->status );
308
309  SetPriority( ctx->worker_id, PRIO_HIGH );
310
311  return tic == toc;
312}
313
314static bool RtemsEventReqPerfOther_Teardown_Wrap(
315  void        *arg,
316  T_ticks     *delta,
317  uint32_t     tic,
318  uint32_t     toc,
319  unsigned int retry
320)
321{
322  RtemsEventValPerf_Context *ctx;
323
324  ctx = arg;
325  return RtemsEventReqPerfOther_Teardown( ctx, delta, tic, toc, retry );
326}
327
328#if defined(RTEMS_SMP)
329/**
330 * @brief Move worker to scheduler B.
331 */
332static void RtemsEventReqPerfOtherCpu_Prepare( RtemsEventValPerf_Context *ctx )
333{
334  SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
335}
336
337/**
338 * @brief Send two events.  Satisfy the event condition.
339 */
340static void RtemsEventReqPerfOtherCpu_Body( RtemsEventValPerf_Context *ctx )
341{
342  ctx->begin = T_tick();
343  ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
344}
345
346static void RtemsEventReqPerfOtherCpu_Body_Wrap( void *arg )
347{
348  RtemsEventValPerf_Context *ctx;
349
350  ctx = arg;
351  RtemsEventReqPerfOtherCpu_Body( ctx );
352}
353
354/**
355 * @brief Make sure the worker waits for the next event.  Set the measured
356 *   runtime. Discard samples interrupted by a clock tick.
357 */
358static bool RtemsEventReqPerfOtherCpu_Teardown(
359  RtemsEventValPerf_Context *ctx,
360  T_ticks                   *delta,
361  uint32_t                   tic,
362  uint32_t                   toc,
363  unsigned int               retry
364)
365{
366  T_quiet_rsc_success( ctx->status );
367
368  WaitForNextTask( 1, ctx->worker_id );
369  *delta = ctx->end - ctx->begin;
370
371  return tic == toc;
372}
373
374static bool RtemsEventReqPerfOtherCpu_Teardown_Wrap(
375  void        *arg,
376  T_ticks     *delta,
377  uint32_t     tic,
378  uint32_t     toc,
379  unsigned int retry
380)
381{
382  RtemsEventValPerf_Context *ctx;
383
384  ctx = arg;
385  return RtemsEventReqPerfOtherCpu_Teardown( ctx, delta, tic, toc, retry );
386}
387
388/**
389 * @brief Move worker to scheduler A.
390 */
391static void RtemsEventReqPerfOtherCpu_Cleanup( RtemsEventValPerf_Context *ctx )
392{
393  SetScheduler( ctx->worker_id, SCHEDULER_A_ID, PRIO_HIGH );
394}
395#endif
396
397/**
398 * @brief Send an event.  Do not satisfy the event condition.
399 */
400static void RtemsEventReqPerfOtherNotSatisfied_Body(
401  RtemsEventValPerf_Context *ctx
402)
403{
404  ctx->status = rtems_event_send( ctx->worker_id, EVENT_OTHER );
405}
406
407static void RtemsEventReqPerfOtherNotSatisfied_Body_Wrap( void *arg )
408{
409  RtemsEventValPerf_Context *ctx;
410
411  ctx = arg;
412  RtemsEventReqPerfOtherNotSatisfied_Body( ctx );
413}
414
415/**
416 * @brief Let the worker wait for the next set of events.  Discard samples
417 *   interrupted by a clock tick.
418 */
419static bool RtemsEventReqPerfOtherNotSatisfied_Teardown(
420  RtemsEventValPerf_Context *ctx,
421  T_ticks                   *delta,
422  uint32_t                   tic,
423  uint32_t                   toc,
424  unsigned int               retry
425)
426{
427  T_quiet_rsc_success( ctx->status );
428
429  Send( ctx, EVENT_END );
430
431  return tic == toc;
432}
433
434static bool RtemsEventReqPerfOtherNotSatisfied_Teardown_Wrap(
435  void        *arg,
436  T_ticks     *delta,
437  uint32_t     tic,
438  uint32_t     toc,
439  unsigned int retry
440)
441{
442  RtemsEventValPerf_Context *ctx;
443
444  ctx = arg;
445  return RtemsEventReqPerfOtherNotSatisfied_Teardown(
446    ctx,
447    delta,
448    tic,
449    toc,
450    retry
451  );
452}
453
454/**
455 * @brief Send two events.  Satisfy the event condition.
456 */
457static void RtemsEventReqPerfOtherPreempt_Body(
458  RtemsEventValPerf_Context *ctx
459)
460{
461  ctx->begin = T_tick();
462  ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
463}
464
465static void RtemsEventReqPerfOtherPreempt_Body_Wrap( void *arg )
466{
467  RtemsEventValPerf_Context *ctx;
468
469  ctx = arg;
470  RtemsEventReqPerfOtherPreempt_Body( ctx );
471}
472
473/**
474 * @brief Set the measured runtime.  Discard samples interrupted by a clock
475 *   tick.
476 */
477static bool RtemsEventReqPerfOtherPreempt_Teardown(
478  RtemsEventValPerf_Context *ctx,
479  T_ticks                   *delta,
480  uint32_t                   tic,
481  uint32_t                   toc,
482  unsigned int               retry
483)
484{
485  T_quiet_rsc_success( ctx->status );
486
487  *delta = ctx->end - ctx->begin;
488
489  return tic == toc;
490}
491
492static bool RtemsEventReqPerfOtherPreempt_Teardown_Wrap(
493  void        *arg,
494  T_ticks     *delta,
495  uint32_t     tic,
496  uint32_t     toc,
497  unsigned int retry
498)
499{
500  RtemsEventValPerf_Context *ctx;
501
502  ctx = arg;
503  return RtemsEventReqPerfOtherPreempt_Teardown( ctx, delta, tic, toc, retry );
504}
505
506/**
507 * @fn void T_case_body_RtemsEventValPerf( void )
508 */
509T_TEST_CASE_FIXTURE( RtemsEventValPerf, &RtemsEventValPerf_Fixture )
510{
511  RtemsEventValPerf_Context *ctx;
512
513  ctx = T_fixture_context();
514
515  ctx->request.name = "RtemsEventReqPerfIsrPreempt";
516  ctx->request.setup = NULL;
517  ctx->request.body = RtemsEventReqPerfIsrPreempt_Body_Wrap;
518  ctx->request.teardown = RtemsEventReqPerfIsrPreempt_Teardown_Wrap;
519  T_measure_runtime( ctx->context, &ctx->request );
520
521  ctx->request.name = "RtemsEventReqPerfOther";
522  ctx->request.setup = RtemsEventReqPerfOther_Setup_Wrap;
523  ctx->request.body = RtemsEventReqPerfOther_Body_Wrap;
524  ctx->request.teardown = RtemsEventReqPerfOther_Teardown_Wrap;
525  T_measure_runtime( ctx->context, &ctx->request );
526
527  #if defined(RTEMS_SMP)
528  RtemsEventReqPerfOtherCpu_Prepare( ctx );
529  ctx->request.name = "RtemsEventReqPerfOtherCpu";
530  ctx->request.setup = NULL;
531  ctx->request.body = RtemsEventReqPerfOtherCpu_Body_Wrap;
532  ctx->request.teardown = RtemsEventReqPerfOtherCpu_Teardown_Wrap;
533  T_measure_runtime( ctx->context, &ctx->request );
534  RtemsEventReqPerfOtherCpu_Cleanup( ctx );
535  #endif
536
537  ctx->request.name = "RtemsEventReqPerfOtherNotSatisfied";
538  ctx->request.setup = NULL;
539  ctx->request.body = RtemsEventReqPerfOtherNotSatisfied_Body_Wrap;
540  ctx->request.teardown = RtemsEventReqPerfOtherNotSatisfied_Teardown_Wrap;
541  T_measure_runtime( ctx->context, &ctx->request );
542
543  ctx->request.name = "RtemsEventReqPerfOtherPreempt";
544  ctx->request.setup = NULL;
545  ctx->request.body = RtemsEventReqPerfOtherPreempt_Body_Wrap;
546  ctx->request.teardown = RtemsEventReqPerfOtherPreempt_Teardown_Wrap;
547  T_measure_runtime( ctx->context, &ctx->request );
548}
549
550/** @} */
Note: See TracBrowser for help on using the repository browser.