source: rtems/cpukit/libmisc/testsupport/test.h @ f1531574

Last change on this file since f1531574 was f1531574, checked in by Sebastian Huber <sebastian.huber@…>, on Jun 21, 2016 at 12:22:35 PM

Rename rtems_test_print() into rtems_test_printf()

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/*
2 * Copyright (c) 2014 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 * @brief Test support functions.
31 *
32 * @{
33 */
34
35/**
36 * @brief Each test must define a test name string.
37 */
38extern const char rtems_test_name[];
39
40/**
41 * @brief Each test must define a printer.
42 */
43extern rtems_printer rtems_test_printer;
44
45/**
46 * @brief Fatal extension for tests.
47 */
48void rtems_test_fatal_extension(
49  rtems_fatal_source source,
50  bool is_internal,
51  rtems_fatal_code code
52);
53
54/**
55 * @brief Initial extension for tests.
56 */
57#define RTEMS_TEST_INITIAL_EXTENSION \
58  { NULL, NULL, NULL, NULL, NULL, NULL, NULL, rtems_test_fatal_extension }
59
60/**
61 * @brief Begin of test message format string.
62 */
63#define TEST_BEGIN_STRING "\n\n*** BEGIN OF TEST %s ***\n", rtems_test_name
64
65/**
66 * @brief End of test message format string.
67 */
68#define TEST_END_STRING "*** END OF TEST %s ***\n", rtems_test_name
69
70/**
71 * @brief Prints a begin of test message using printf().
72 *
73 * @returns As specified by printf().
74 */
75int rtems_test_begin(void);
76
77/**
78 * @brief Prints an end of test message using printf().
79 *
80 * @returns As specified by printf().
81 */
82int rtems_test_end(void);
83
84/**
85 * @brief Prints via the RTEMS printer.
86 *
87 * @returns As specified by printf().
88 */
89int rtems_test_printf(const char* format, ...) RTEMS_PRINTFLIKE(1, 2);
90
91/**
92 * @brief Internal context for parallel job execution.
93 */
94typedef struct {
95  Atomic_Ulong stop;
96  SMP_barrier_Control barrier;
97  size_t worker_count;
98  rtems_id worker_ids[32];
99  rtems_id stop_worker_timer_id;
100} rtems_test_parallel_context;
101
102/**
103 * @brief Worker task setup handler.
104 *
105 * Called during rtems_test_parallel() to optionally setup a worker task before
106 * it is started.
107 *
108 * @param[in] ctx The parallel context.
109 * @param[in] worker_index The worker index.
110 * @param[in] worker_id The worker task identifier.
111 */
112typedef void (*rtems_test_parallel_worker_setup)(
113  rtems_test_parallel_context *ctx,
114  size_t worker_index,
115  rtems_id worker_id
116);
117
118/**
119 * @brief Basic parallel job description.
120 */
121typedef struct {
122  /**
123   * @brief Job initialization handler.
124   *
125   * This handler executes only in the context of the master worker before the
126   * job body handler.
127   *
128   * @param[in] ctx The parallel context.
129   * @param[in] arg The user specified argument.
130   * @param[in] active_workers Count of active workers.  Depends on the cascade
131   *   option.
132   *
133   * @return The desired job body execution time in clock ticks.  See
134   *   rtems_test_parallel_stop_job().
135   */
136  rtems_interval (*init)(
137    rtems_test_parallel_context *ctx,
138    void *arg,
139    size_t active_workers
140  );
141
142  /**
143   * @brief Job body handler.
144   *
145   * @param[in] ctx The parallel context.
146   * @param[in] arg The user specified argument.
147   * @param[in] active_workers Count of active workers.  Depends on the cascade
148   *   option.
149   * @param[in] worker_index The worker index.  It ranges from 0 to the
150   *   processor count minus one.
151   */
152  void (*body)(
153    rtems_test_parallel_context *ctx,
154    void *arg,
155    size_t active_workers,
156    size_t worker_index
157  );
158
159  /**
160   * @brief Job finalization handler.
161   *
162   * This handler executes only in the context of the master worker after 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  void (*fini)(
171    rtems_test_parallel_context *ctx,
172    void *arg,
173    size_t active_workers
174  );
175
176  /**
177   * @brief Job specific argument.
178   */
179  void *arg;
180
181  /**
182   * @brief Job cascading flag.
183   *
184   * This flag indicates whether the job should be executed in a cascaded
185   * manner (the job is executed on one processor first, two processors
186   * afterwards and incremented step by step until all processors are used).
187   */
188  bool cascade;
189} rtems_test_parallel_job;
190
191/**
192 * @brief Indicates if a job body should stop its work loop.
193 *
194 * @param[in] ctx The parallel context.
195 *
196 * @retval true The job body should stop its work loop and return to the caller.
197 * @retval false Otherwise.
198 */
199static inline bool rtems_test_parallel_stop_job(
200  const rtems_test_parallel_context *ctx
201)
202{
203  return _Atomic_Load_ulong(&ctx->stop, ATOMIC_ORDER_RELAXED) != 0;
204}
205
206/**
207 * @brief Indicates if a worker is the master worker.
208 *
209 * The master worker is the thread that called rtems_test_parallel().
210 *
211 * @param[in] worker_index The worker index.
212 *
213 * @retval true This is the master worker.
214 * @retval false Otherwise.
215 */
216static inline bool rtems_test_parallel_is_master_worker(size_t worker_index)
217{
218  return worker_index == 0;
219}
220
221/**
222 * @brief Returns the task identifier for a worker.
223 *
224 * @param[in] ctx The parallel context.
225 * @param[in] worker_index The worker index.
226 *
227 * @return The task identifier of the worker.
228 */
229static inline rtems_id rtems_test_parallel_get_task_id(
230  const rtems_test_parallel_context *ctx,
231  size_t worker_index
232)
233{
234  return ctx->worker_ids[worker_index];
235}
236
237/**
238 * @brief Runs a bunch of jobs in parallel on all processors of the system.
239 *
240 * The worker tasks inherit the priority of the executing task.
241 *
242 * There are SMP barriers before and after the job body.
243 *
244 * @param[in] ctx The parallel context.
245 * @param[in] worker_setup Optional handler to setup a worker task before it is
246 *   started.
247 * @param[in] jobs The table of jobs.
248 * @param[in] job_count The count of jobs in the job table.
249 */
250void rtems_test_parallel(
251  rtems_test_parallel_context *ctx,
252  rtems_test_parallel_worker_setup worker_setup,
253  const rtems_test_parallel_job *jobs,
254  size_t job_count
255);
256
257/** @} */
258
259#ifdef __cplusplus
260}
261#endif /* __cplusplus */
262
263#endif /* _RTEMS_TEST_H */
Note: See TracBrowser for help on using the repository browser.