source: rtems/cpukit/include/rtems/test-info.h @ 10ef708

Last change on this file since 10ef708 was 4f87edb, checked in by Sebastian Huber <sebastian.huber@…>, on 06/28/22 at 05:45:02

gcov: Add functions to dump the gcov information

Update #4670.

  • Property mode set to 100644
File size: 9.3 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/*
4 * Copyright (c) 2014, 2018 embedded brains GmbH.  All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef _RTEMS_TEST_H
29#define _RTEMS_TEST_H
30
31#include <rtems.h>
32#include <rtems/printer.h>
33#include <rtems/score/atomic.h>
34#include <rtems/score/smpbarrier.h>
35
36#ifdef __cplusplus
37extern "C" {
38#endif /* __cplusplus */
39
40/**
41 * @defgroup RTEMSTest Test Support
42 *
43 * @ingroup RTEMSAPI
44 *
45 * @brief Test support functions.
46 *
47 * @{
48 */
49
50/**
51 * @brief Each test must define a test name string.
52 */
53extern const char rtems_test_name[];
54
55/**
56 * @brief Each test must define a printer.
57 */
58extern rtems_printer rtems_test_printer;
59
60/**
61 * @brief Fatal extension for tests.
62 */
63void rtems_test_fatal_extension(
64  rtems_fatal_source source,
65  bool always_set_to_false,
66  rtems_fatal_code code
67);
68
69/**
70 * @brief Initial extension for tests.
71 */
72#define RTEMS_TEST_INITIAL_EXTENSION \
73  { NULL, NULL, NULL, NULL, NULL, NULL, NULL, rtems_test_fatal_extension }
74
75/**
76 * @brief Test states.
77 */
78typedef enum
79{
80  RTEMS_TEST_STATE_PASS,
81  RTEMS_TEST_STATE_FAIL,
82  RTEMS_TEST_STATE_USER_INPUT,
83  RTEMS_TEST_STATE_INDETERMINATE,
84  RTEMS_TEST_STATE_BENCHMARK
85} RTEMS_TEST_STATE;
86
87#if (TEST_STATE_EXPECTED_FAIL && TEST_STATE_USER_INPUT) || \
88    (TEST_STATE_EXPECTED_FAIL && TEST_STATE_INDETERMINATE) || \
89    (TEST_STATE_EXPECTED_FAIL && TEST_STATE_BENCHMARK) || \
90    (TEST_STATE_USER_INPUT    && TEST_STATE_INDETERMINATE) || \
91    (TEST_STATE_USER_INPUT    && TEST_STATE_BENCHMARK) || \
92    (TEST_STATE_INDETERMINATE && TEST_STATE_BENCHMARK)
93  #error Test states must be unique
94#endif
95
96#if TEST_STATE_EXPECTED_FAIL
97  #define TEST_STATE RTEMS_TEST_STATE_FAIL
98#elif TEST_STATE_USER_INPUT
99  #define TEST_STATE RTEMS_TEST_STATE_USER_INPUT
100#elif TEST_STATE_INDETERMINATE
101  #define TEST_STATE RTEMS_TEST_STATE_INDETERMINATE
102#elif TEST_STATE_BENCHMARK
103  #define TEST_STATE RTEMS_TEST_STATE_BENCHMARK
104#else
105  #define TEST_STATE RTEMS_TEST_STATE_PASS
106#endif
107
108/**
109 * @brief Prints a begin of test message using printf().
110 *
111 * @returns As specified by printf().
112 */
113int rtems_test_begin(const char* name, const RTEMS_TEST_STATE state);
114
115/**
116 * @brief Prints an end of test message using printf().
117 *
118 * @returns As specified by printf().
119 */
120int rtems_test_end(const char* name);
121
122/**
123 * @brief Exit the test without calling exit() since it closes stdin, etc and
124 * pulls in stdio code
125 */
126RTEMS_NO_RETURN void rtems_test_exit(int status);
127
128/**
129 * @brief Prints via the RTEMS printer.
130 *
131 * @returns As specified by printf().
132 */
133int rtems_test_printf(const char* format, ...) RTEMS_PRINTFLIKE(1, 2);
134
135#define RTEMS_TEST_PARALLEL_PROCESSOR_MAX 32
136
137typedef struct rtems_test_parallel_job rtems_test_parallel_job;
138
139/**
140 * @brief Internal context for parallel job execution.
141 */
142typedef struct {
143  Atomic_Ulong stop;
144  SMP_barrier_Control barrier;
145  size_t worker_count;
146  rtems_id worker_ids[RTEMS_TEST_PARALLEL_PROCESSOR_MAX];
147  rtems_id stop_worker_timer_id;
148  const struct rtems_test_parallel_job *jobs;
149  size_t job_count;
150} rtems_test_parallel_context;
151
152/**
153 * @brief Worker task setup handler.
154 *
155 * Called during rtems_test_parallel() to optionally setup a worker task before
156 * it is started.
157 *
158 * @param[in] ctx The parallel context.
159 * @param[in] worker_index The worker index.
160 * @param[in] worker_id The worker task identifier.
161 */
162typedef void (*rtems_test_parallel_worker_setup)(
163  rtems_test_parallel_context *ctx,
164  size_t worker_index,
165  rtems_id worker_id
166);
167
168/**
169 * @brief Basic parallel job description.
170 */
171struct rtems_test_parallel_job {
172  /**
173   * @brief Job initialization handler.
174   *
175   * This handler executes only in the context of the master worker before the
176   * job body handler.
177   *
178   * @param[in] ctx The parallel context.
179   * @param[in] arg The user specified argument.
180   * @param[in] active_workers Count of active workers.  Depends on the cascade
181   *   option.
182   *
183   * @return The desired job body execution time in clock ticks.  See
184   *   rtems_test_parallel_stop_job().
185   */
186  rtems_interval (*init)(
187    rtems_test_parallel_context *ctx,
188    void *arg,
189    size_t active_workers
190  );
191
192  /**
193   * @brief Job body handler.
194   *
195   * @param[in] ctx The parallel context.
196   * @param[in] arg The user specified argument.
197   * @param[in] active_workers Count of active workers.  Depends on the cascade
198   *   option.
199   * @param[in] worker_index The worker index.  It ranges from 0 to the
200   *   processor count minus one.
201   */
202  void (*body)(
203    rtems_test_parallel_context *ctx,
204    void *arg,
205    size_t active_workers,
206    size_t worker_index
207  );
208
209  /**
210   * @brief Job finalization handler.
211   *
212   * This handler executes only in the context of the master worker after the
213   * job body handler.
214   *
215   * @param[in] ctx The parallel context.
216   * @param[in] arg The user specified argument.
217   * @param[in] active_workers Count of active workers.  Depends on the cascade
218   *   option.
219   */
220  void (*fini)(
221    rtems_test_parallel_context *ctx,
222    void *arg,
223    size_t active_workers
224  );
225
226  /**
227   * @brief Job specific argument.
228   */
229  void *arg;
230
231  /**
232   * @brief Job cascading flag.
233   *
234   * This flag indicates whether the job should be executed in a cascaded
235   * manner (the job is executed on one processor first, two processors
236   * afterwards and incremented step by step until all processors are used).
237   */
238  bool cascade;
239};
240
241/**
242 * @brief Indicates if a job body should stop its work loop.
243 *
244 * @param[in] ctx The parallel context.
245 *
246 * @retval true The job body should stop its work loop and return to the caller.
247 * @retval false Otherwise.
248 */
249static inline bool rtems_test_parallel_stop_job(
250  const rtems_test_parallel_context *ctx
251)
252{
253  return _Atomic_Load_ulong(&ctx->stop, ATOMIC_ORDER_RELAXED) != 0;
254}
255
256/**
257 * @brief Indicates if a worker is the master worker.
258 *
259 * The master worker is the thread that called rtems_test_parallel().
260 *
261 * @param[in] worker_index The worker index.
262 *
263 * @retval true This is the master worker.
264 * @retval false Otherwise.
265 */
266static inline bool rtems_test_parallel_is_master_worker(size_t worker_index)
267{
268  return worker_index == 0;
269}
270
271/**
272 * @brief Returns the task identifier for a worker.
273 *
274 * @param[in] ctx The parallel context.
275 * @param[in] worker_index The worker index.
276 *
277 * @return The task identifier of the worker.
278 */
279static inline rtems_id rtems_test_parallel_get_task_id(
280  const rtems_test_parallel_context *ctx,
281  size_t worker_index
282)
283{
284  return ctx->worker_ids[worker_index];
285}
286
287/**
288 * @brief Runs a bunch of jobs in parallel on all processors of the system.
289 *
290 * The worker tasks inherit the priority of the executing task.
291 *
292 * There are SMP barriers before and after the job body.
293 *
294 * @param[in] ctx The parallel context.
295 * @param[in] worker_setup Optional handler to setup a worker task before it is
296 *   started.
297 * @param[in] jobs The table of jobs.
298 * @param[in] job_count The count of jobs in the job table.
299 */
300void rtems_test_parallel(
301  rtems_test_parallel_context *ctx,
302  rtems_test_parallel_worker_setup worker_setup,
303  const rtems_test_parallel_job *jobs,
304  size_t job_count
305);
306
307/**
308 * @brief Performs a busy loop for the specified seconds and nanoseconds based
309 * on the CPU usage of the executing thread.
310 *
311 * This function continuously reads the CPU usage of the executing thread.
312 * This operation may lead to a scheduler instance lock contention in SMP
313 * configurations.
314 *
315 * @param[in] seconds The busy seconds.
316 * @param[in] nanoseconds The busy nanoseconds.
317 */
318void rtems_test_busy_cpu_usage(time_t seconds, long nanoseconds);
319
320/**
321 * @brief Runs the test cases of the RTEMS Test Framework using a default
322 *   configuration in the context of a task.
323 *
324 * The application must provide rtems_test_name.
325 *
326 * @param arg is the task argument.
327 * @param state is the test state.
328 */
329RTEMS_NO_RETURN void rtems_test_run(
330  rtems_task_argument    arg,
331  const RTEMS_TEST_STATE state
332);
333
334/**
335 * @brief Dumps the gcov information as a base64 encoded gcfn and gcda data
336 *   stream using rtems_put_char().
337 */
338void rtems_test_gcov_dump_info( void );
339
340/** @} */
341
342#ifdef __cplusplus
343}
344#endif /* __cplusplus */
345
346#endif /* _RTEMS_TEST_H */
Note: See TracBrowser for help on using the repository browser.