source: rtems/cpukit/include/rtems/test-info.h @ 9de8d61

Last change on this file since 9de8d61 was 9de8d61, checked in by Sebastian Huber <sebastian.huber@…>, on 07/17/20 at 11:36:49

libtest: <rtems/test.h> to <rtems/test-info.h>

Rename this header file to later move <t.h> to <rtems/test.h>. The main
feature provided by <rtems/test-info.h> is the output of standard test
information which is consumed by the RTEMS Tester.

Update #3199.

  • Property mode set to 100644
File size: 8.1 KB
Line 
1/*
2 * Copyright (c) 2014, 2018 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#ifndef _RTEMS_TEST_H
16#define _RTEMS_TEST_H
17
18#include <rtems.h>
19#include <rtems/printer.h>
20#include <rtems/score/atomic.h>
21#include <rtems/score/smpbarrier.h>
22
23#ifdef __cplusplus
24extern "C" {
25#endif /* __cplusplus */
26
27/**
28 * @defgroup RTEMSTest Test Support
29 *
30 * @ingroup RTEMSAPI
31 *
32 * @brief Test support functions.
33 *
34 * @{
35 */
36
37/**
38 * @brief Each test must define a test name string.
39 */
40extern const char rtems_test_name[];
41
42/**
43 * @brief Each test must define a printer.
44 */
45extern rtems_printer rtems_test_printer;
46
47/**
48 * @brief Fatal extension for tests.
49 */
50void rtems_test_fatal_extension(
51  rtems_fatal_source source,
52  bool always_set_to_false,
53  rtems_fatal_code code
54);
55
56/**
57 * @brief Initial extension for tests.
58 */
59#define RTEMS_TEST_INITIAL_EXTENSION \
60  { NULL, NULL, NULL, NULL, NULL, NULL, NULL, rtems_test_fatal_extension }
61
62/**
63 * @brief Test states.
64 */
65typedef enum
66{
67  RTEMS_TEST_STATE_PASS,
68  RTEMS_TEST_STATE_FAIL,
69  RTEMS_TEST_STATE_USER_INPUT,
70  RTEMS_TEST_STATE_INDETERMINATE,
71  RTEMS_TEST_STATE_BENCHMARK
72} RTEMS_TEST_STATE;
73
74#if (TEST_STATE_EXPECTED_FAIL && TEST_STATE_USER_INPUT) || \
75    (TEST_STATE_EXPECTED_FAIL && TEST_STATE_INDETERMINATE) || \
76    (TEST_STATE_EXPECTED_FAIL && TEST_STATE_BENCHMARK) || \
77    (TEST_STATE_USER_INPUT    && TEST_STATE_INDETERMINATE) || \
78    (TEST_STATE_USER_INPUT    && TEST_STATE_BENCHMARK) || \
79    (TEST_STATE_INDETERMINATE && TEST_STATE_BENCHMARK)
80  #error Test states must be unique
81#endif
82
83#if TEST_STATE_EXPECTED_FAIL
84  #define TEST_STATE RTEMS_TEST_STATE_FAIL
85#elif TEST_STATE_USER_INPUT
86  #define TEST_STATE RTEMS_TEST_STATE_USER_INPUT
87#elif TEST_STATE_INDETERMINATE
88  #define TEST_STATE RTEMS_TEST_STATE_INDETERMINATE
89#elif TEST_STATE_BENCHMARK
90  #define TEST_STATE RTEMS_TEST_STATE_BENCHMARK
91#else
92  #define TEST_STATE RTEMS_TEST_STATE_PASS
93#endif
94
95/**
96 * @brief Prints a begin of test message using printf().
97 *
98 * @returns As specified by printf().
99 */
100int rtems_test_begin(const char* name, const RTEMS_TEST_STATE state);
101
102/**
103 * @brief Prints an end of test message using printf().
104 *
105 * @returns As specified by printf().
106 */
107int rtems_test_end(const char* name);
108
109/**
110 * @brief Exit the test without calling exit() since it closes stdin, etc and
111 * pulls in stdio code
112 */
113void rtems_test_exit(int status) RTEMS_NO_RETURN;
114
115/**
116 * @brief Prints via the RTEMS printer.
117 *
118 * @returns As specified by printf().
119 */
120int rtems_test_printf(const char* format, ...) RTEMS_PRINTFLIKE(1, 2);
121
122#define RTEMS_TEST_PARALLEL_PROCESSOR_MAX 32
123
124typedef struct rtems_test_parallel_job rtems_test_parallel_job;
125
126/**
127 * @brief Internal context for parallel job execution.
128 */
129typedef struct {
130  Atomic_Ulong stop;
131  SMP_barrier_Control barrier;
132  size_t worker_count;
133  rtems_id worker_ids[RTEMS_TEST_PARALLEL_PROCESSOR_MAX];
134  rtems_id stop_worker_timer_id;
135  const struct rtems_test_parallel_job *jobs;
136  size_t job_count;
137} rtems_test_parallel_context;
138
139/**
140 * @brief Worker task setup handler.
141 *
142 * Called during rtems_test_parallel() to optionally setup a worker task before
143 * it is started.
144 *
145 * @param[in] ctx The parallel context.
146 * @param[in] worker_index The worker index.
147 * @param[in] worker_id The worker task identifier.
148 */
149typedef void (*rtems_test_parallel_worker_setup)(
150  rtems_test_parallel_context *ctx,
151  size_t worker_index,
152  rtems_id worker_id
153);
154
155/**
156 * @brief Basic parallel job description.
157 */
158struct rtems_test_parallel_job {
159  /**
160   * @brief Job initialization handler.
161   *
162   * This handler executes only in the context of the master worker before the
163   * job body handler.
164   *
165   * @param[in] ctx The parallel context.
166   * @param[in] arg The user specified argument.
167   * @param[in] active_workers Count of active workers.  Depends on the cascade
168   *   option.
169   *
170   * @return The desired job body execution time in clock ticks.  See
171   *   rtems_test_parallel_stop_job().
172   */
173  rtems_interval (*init)(
174    rtems_test_parallel_context *ctx,
175    void *arg,
176    size_t active_workers
177  );
178
179  /**
180   * @brief Job body handler.
181   *
182   * @param[in] ctx The parallel context.
183   * @param[in] arg The user specified argument.
184   * @param[in] active_workers Count of active workers.  Depends on the cascade
185   *   option.
186   * @param[in] worker_index The worker index.  It ranges from 0 to the
187   *   processor count minus one.
188   */
189  void (*body)(
190    rtems_test_parallel_context *ctx,
191    void *arg,
192    size_t active_workers,
193    size_t worker_index
194  );
195
196  /**
197   * @brief Job finalization handler.
198   *
199   * This handler executes only in the context of the master worker after the
200   * job body handler.
201   *
202   * @param[in] ctx The parallel context.
203   * @param[in] arg The user specified argument.
204   * @param[in] active_workers Count of active workers.  Depends on the cascade
205   *   option.
206   */
207  void (*fini)(
208    rtems_test_parallel_context *ctx,
209    void *arg,
210    size_t active_workers
211  );
212
213  /**
214   * @brief Job specific argument.
215   */
216  void *arg;
217
218  /**
219   * @brief Job cascading flag.
220   *
221   * This flag indicates whether the job should be executed in a cascaded
222   * manner (the job is executed on one processor first, two processors
223   * afterwards and incremented step by step until all processors are used).
224   */
225  bool cascade;
226};
227
228/**
229 * @brief Indicates if a job body should stop its work loop.
230 *
231 * @param[in] ctx The parallel context.
232 *
233 * @retval true The job body should stop its work loop and return to the caller.
234 * @retval false Otherwise.
235 */
236static inline bool rtems_test_parallel_stop_job(
237  const rtems_test_parallel_context *ctx
238)
239{
240  return _Atomic_Load_ulong(&ctx->stop, ATOMIC_ORDER_RELAXED) != 0;
241}
242
243/**
244 * @brief Indicates if a worker is the master worker.
245 *
246 * The master worker is the thread that called rtems_test_parallel().
247 *
248 * @param[in] worker_index The worker index.
249 *
250 * @retval true This is the master worker.
251 * @retval false Otherwise.
252 */
253static inline bool rtems_test_parallel_is_master_worker(size_t worker_index)
254{
255  return worker_index == 0;
256}
257
258/**
259 * @brief Returns the task identifier for a worker.
260 *
261 * @param[in] ctx The parallel context.
262 * @param[in] worker_index The worker index.
263 *
264 * @return The task identifier of the worker.
265 */
266static inline rtems_id rtems_test_parallel_get_task_id(
267  const rtems_test_parallel_context *ctx,
268  size_t worker_index
269)
270{
271  return ctx->worker_ids[worker_index];
272}
273
274/**
275 * @brief Runs a bunch of jobs in parallel on all processors of the system.
276 *
277 * The worker tasks inherit the priority of the executing task.
278 *
279 * There are SMP barriers before and after the job body.
280 *
281 * @param[in] ctx The parallel context.
282 * @param[in] worker_setup Optional handler to setup a worker task before it is
283 *   started.
284 * @param[in] jobs The table of jobs.
285 * @param[in] job_count The count of jobs in the job table.
286 */
287void rtems_test_parallel(
288  rtems_test_parallel_context *ctx,
289  rtems_test_parallel_worker_setup worker_setup,
290  const rtems_test_parallel_job *jobs,
291  size_t job_count
292);
293
294/**
295 * @brief Performs a busy loop for the specified seconds and nanoseconds based
296 * on the CPU usage of the executing thread.
297 *
298 * This function continuously reads the CPU usage of the executing thread.
299 * This operation may lead to a scheduler instance lock contention in SMP
300 * configurations.
301 *
302 * @param[in] seconds The busy seconds.
303 * @param[in] nanoseconds The busy nanoseconds.
304 */
305void rtems_test_busy_cpu_usage(time_t seconds, long nanoseconds);
306
307/**
308 * @brief Performs a busy loop with the specified iteration count.
309 *
310 * This function is optimized to not perform memory accesses and should have a
311 * small jitter.
312 *
313 * @param[in] count The iteration count.
314 */
315void rtems_test_busy(uint_fast32_t count);
316
317/**
318 * @brief Returns a count value for rtems_test_busy() which yields roughly a
319 * duration of one clock tick.
320 */
321uint_fast32_t rtems_test_get_one_tick_busy_count(void);
322
323/** @} */
324
325#ifdef __cplusplus
326}
327#endif /* __cplusplus */
328
329#endif /* _RTEMS_TEST_H */
Note: See TracBrowser for help on using the repository browser.