xref: /aosp_15_r20/trusty/kernel/include/shared/lk/trusty_benchmark.h (revision 344aa361028b423587d4ef3fa52a23d194628137)
1*344aa361SAndroid Build Coastguard Worker /*
2*344aa361SAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
3*344aa361SAndroid Build Coastguard Worker  *
4*344aa361SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining
5*344aa361SAndroid Build Coastguard Worker  * a copy of this software and associated documentation files
6*344aa361SAndroid Build Coastguard Worker  * (the "Software"), to deal in the Software without restriction,
7*344aa361SAndroid Build Coastguard Worker  * including without limitation the rights to use, copy, modify, merge,
8*344aa361SAndroid Build Coastguard Worker  * publish, distribute, sublicense, and/or sell copies of the Software,
9*344aa361SAndroid Build Coastguard Worker  * and to permit persons to whom the Software is furnished to do so,
10*344aa361SAndroid Build Coastguard Worker  * subject to the following conditions:
11*344aa361SAndroid Build Coastguard Worker  *
12*344aa361SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be
13*344aa361SAndroid Build Coastguard Worker  * included in all copies or substantial portions of the Software.
14*344aa361SAndroid Build Coastguard Worker  *
15*344aa361SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*344aa361SAndroid Build Coastguard Worker  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*344aa361SAndroid Build Coastguard Worker  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18*344aa361SAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19*344aa361SAndroid Build Coastguard Worker  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20*344aa361SAndroid Build Coastguard Worker  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21*344aa361SAndroid Build Coastguard Worker  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22*344aa361SAndroid Build Coastguard Worker  */
23*344aa361SAndroid Build Coastguard Worker 
24*344aa361SAndroid Build Coastguard Worker /*
25*344aa361SAndroid Build Coastguard Worker  * bench functions can be defined with the macro
26*344aa361SAndroid Build Coastguard Worker  * BENCH(suite_name,bench_name,n [, params])
27*344aa361SAndroid Build Coastguard Worker  * {
28*344aa361SAndroid Build Coastguard Worker  *     ... bench function body ...
29*344aa361SAndroid Build Coastguard Worker  * }
30*344aa361SAndroid Build Coastguard Worker  *
31*344aa361SAndroid Build Coastguard Worker  *  - This body will be executed n times for each params, if 4 arguments are
32*344aa361SAndroid Build Coastguard Worker  *    given.
33*344aa361SAndroid Build Coastguard Worker  *  - This body will be executed n times, if 3 arguments are given.
34*344aa361SAndroid Build Coastguard Worker  *
35*344aa361SAndroid Build Coastguard Worker  * For a suite, one is expected to also define BENCH_SETUP, BENCH_TEARDOWN.
36*344aa361SAndroid Build Coastguard Worker  * For a 2-tuple (suite_name, bench_name) one is expected to also define at
37*344aa361SAndroid Build Coastguard Worker  * least one BENCH_RESULT.
38*344aa361SAndroid Build Coastguard Worker  *
39*344aa361SAndroid Build Coastguard Worker  * BENCH_SETUP(suite_name)
40*344aa361SAndroid Build Coastguard Worker  * {
41*344aa361SAndroid Build Coastguard Worker  *     ... bench setup body ...
42*344aa361SAndroid Build Coastguard Worker  *     return int_error_code;
43*344aa361SAndroid Build Coastguard Worker  * }
44*344aa361SAndroid Build Coastguard Worker  *
45*344aa361SAndroid Build Coastguard Worker  * BENCH_SETUP(suite_name):
46*344aa361SAndroid Build Coastguard Worker  *  - Will return 0 or NO_ERROR when it succeed.
47*344aa361SAndroid Build Coastguard Worker  *  - Will be run before every execution of the BENCH body
48*344aa361SAndroid Build Coastguard Worker  *  - Will cancel execution of the next BENCH body if returns non-zero.
49*344aa361SAndroid Build Coastguard Worker  *    Test will be considered failed.
50*344aa361SAndroid Build Coastguard Worker  *  - Will cancel execution of the next BENCH body if any ASSERT_<op> fails.
51*344aa361SAndroid Build Coastguard Worker  *    Test will be considered failed.
52*344aa361SAndroid Build Coastguard Worker  *  - All ASSERT_<op> macros from trusty_unittest can be used
53*344aa361SAndroid Build Coastguard Worker  *  - GTEST_SKIP() maybe be called to skip the benchmark run.
54*344aa361SAndroid Build Coastguard Worker  *
55*344aa361SAndroid Build Coastguard Worker  * BENCH_TEARDOWN(suite_name)
56*344aa361SAndroid Build Coastguard Worker  * {
57*344aa361SAndroid Build Coastguard Worker  *     ... bench teardown body ...
58*344aa361SAndroid Build Coastguard Worker  * }
59*344aa361SAndroid Build Coastguard Worker  *
60*344aa361SAndroid Build Coastguard Worker  * BENCH_TEARDOWN(suite_name):
61*344aa361SAndroid Build Coastguard Worker  *  - Is executed even if BENCH_SETUP failed
62*344aa361SAndroid Build Coastguard Worker  *  - Does not return any value
63*344aa361SAndroid Build Coastguard Worker  *  - All ASSERT_<op> macros from trusty_unittest can be used
64*344aa361SAndroid Build Coastguard Worker  *
65*344aa361SAndroid Build Coastguard Worker  * BENCH_RESULT(suite_name,bench_name,res_name)
66*344aa361SAndroid Build Coastguard Worker  * {
67*344aa361SAndroid Build Coastguard Worker  *     ... bench result body ...
68*344aa361SAndroid Build Coastguard Worker  *     return int64_t_value_of_res_name_for_last_bench_body_run;
69*344aa361SAndroid Build Coastguard Worker  * }
70*344aa361SAndroid Build Coastguard Worker  *
71*344aa361SAndroid Build Coastguard Worker  *
72*344aa361SAndroid Build Coastguard Worker  * BENCH_RESULT(suite_name,bench_name,res_name):
73*344aa361SAndroid Build Coastguard Worker  *  - At least one must be defined. Can define multiple times.
74*344aa361SAndroid Build Coastguard Worker  *  - Must return an int64_t
75*344aa361SAndroid Build Coastguard Worker  *  - Results will be aggregated for n runs of the BENCH( ) body.
76*344aa361SAndroid Build Coastguard Worker  *    Aggregation is grouped by params to min/max/avg of the n runs
77*344aa361SAndroid Build Coastguard Worker  *  - res_name will be used as column title for the metric summary
78*344aa361SAndroid Build Coastguard Worker  *
79*344aa361SAndroid Build Coastguard Worker  * Example:
80*344aa361SAndroid Build Coastguard Worker  *      BENCH_RESULT(hwcrypto, hwrng, time_ns) {
81*344aa361SAndroid Build Coastguard Worker  *          return bench_get_duration_ns();
82*344aa361SAndroid Build Coastguard Worker  *      }
83*344aa361SAndroid Build Coastguard Worker  *
84*344aa361SAndroid Build Coastguard Worker  * - The execution sequence is roughly:
85*344aa361SAndroid Build Coastguard Worker  *
86*344aa361SAndroid Build Coastguard Worker  *       for each param if any:
87*344aa361SAndroid Build Coastguard Worker  *          BENCH_SETUP(suite_name,bench_name)
88*344aa361SAndroid Build Coastguard Worker  *           repeat n times:
89*344aa361SAndroid Build Coastguard Worker  *               BENCH_CONTENT
90*344aa361SAndroid Build Coastguard Worker  *               for each BENCH_RESULT(suite_name,bench_name,res_name)
91*344aa361SAndroid Build Coastguard Worker  *                   update the accumulators for res_name [min,max,avg]
92*344aa361SAndroid Build Coastguard Worker  *           BENCH_TEARDOWN(suite_name,bench_name)
93*344aa361SAndroid Build Coastguard Worker  *       Print Result Table
94*344aa361SAndroid Build Coastguard Worker  *
95*344aa361SAndroid Build Coastguard Worker  * NOTE:
96*344aa361SAndroid Build Coastguard Worker  * When using a parameter array:
97*344aa361SAndroid Build Coastguard Worker  *  - params must be an array of any type T any_name_is_fine[NB_PARAMS] = {...};
98*344aa361SAndroid Build Coastguard Worker  *    The number of params is deduced from the sizeof(params)/sizeof(params[0]).
99*344aa361SAndroid Build Coastguard Worker  *    So please do not dynamically allocate T* params.
100*344aa361SAndroid Build Coastguard Worker  *  - params array name is up to the test writer
101*344aa361SAndroid Build Coastguard Worker  *
102*344aa361SAndroid Build Coastguard Worker  * The default column name for a parameter in the summary table is its index in
103*344aa361SAndroid Build Coastguard Worker  * the param array. To customize it, one can define a function with the
104*344aa361SAndroid Build Coastguard Worker  * following signature:
105*344aa361SAndroid Build Coastguard Worker  * static void trusty_bench_get_param_name_cb(char* buf, size_t buf_size,
106*344aa361SAndroid Build Coastguard Worker  * size_t param_idx);
107*344aa361SAndroid Build Coastguard Worker  *
108*344aa361SAndroid Build Coastguard Worker  * then assign it during BENCH_SETUP to the trusty_bench_get_param_name_cb
109*344aa361SAndroid Build Coastguard Worker  * global:
110*344aa361SAndroid Build Coastguard Worker  *
111*344aa361SAndroid Build Coastguard Worker  * BENCH_SETUP(suite_name) {
112*344aa361SAndroid Build Coastguard Worker  *   trusty_bench_get_param_name_cb = &get_param_name_cb;
113*344aa361SAndroid Build Coastguard Worker  *   …
114*344aa361SAndroid Build Coastguard Worker  * }
115*344aa361SAndroid Build Coastguard Worker  *
116*344aa361SAndroid Build Coastguard Worker  * trusty_bench_get_param_name_cb will be reset to NULL after teardown.
117*344aa361SAndroid Build Coastguard Worker  *
118*344aa361SAndroid Build Coastguard Worker  * See "trusty/user/app/sample/hwrng-bench/main.c" for a working and thoroughly
119*344aa361SAndroid Build Coastguard Worker  * commented example
120*344aa361SAndroid Build Coastguard Worker  */
121*344aa361SAndroid Build Coastguard Worker 
122*344aa361SAndroid Build Coastguard Worker #pragma once
123*344aa361SAndroid Build Coastguard Worker #include <errno.h>
124*344aa361SAndroid Build Coastguard Worker #include <inttypes.h>
125*344aa361SAndroid Build Coastguard Worker #include <stdarg.h>
126*344aa361SAndroid Build Coastguard Worker #include <stdlib.h>
127*344aa361SAndroid Build Coastguard Worker 
128*344aa361SAndroid Build Coastguard Worker #include <lib/pmu/pmu_arch.h>
129*344aa361SAndroid Build Coastguard Worker #include <lib/unittest/unittest.h>
130*344aa361SAndroid Build Coastguard Worker #include <trusty_log.h>
131*344aa361SAndroid Build Coastguard Worker #include "trusty_bench_common.h"
132*344aa361SAndroid Build Coastguard Worker #include "trusty_bench_json_print.h"
133*344aa361SAndroid Build Coastguard Worker #include "trusty_bench_option_cb.h"
134*344aa361SAndroid Build Coastguard Worker #include "trusty_bench_print_tables.h"
135*344aa361SAndroid Build Coastguard Worker #include "trusty_unittest.h"
136*344aa361SAndroid Build Coastguard Worker #ifdef TRUSTY_USERSPACE
137*344aa361SAndroid Build Coastguard Worker #ifdef WITH_PTHREAD
138*344aa361SAndroid Build Coastguard Worker #include <lib/thread/pthread.h>
139*344aa361SAndroid Build Coastguard Worker #endif
140*344aa361SAndroid Build Coastguard Worker #elif WITH_SMP
141*344aa361SAndroid Build Coastguard Worker #include <kernel/mp.h>
142*344aa361SAndroid Build Coastguard Worker #endif
143*344aa361SAndroid Build Coastguard Worker #include <uapi/err.h>
144*344aa361SAndroid Build Coastguard Worker 
145*344aa361SAndroid Build Coastguard Worker #ifdef WITH_TEST_PMU
146*344aa361SAndroid Build Coastguard Worker #include <lib/pmu/pmu.h>
147*344aa361SAndroid Build Coastguard Worker #endif
148*344aa361SAndroid Build Coastguard Worker 
149*344aa361SAndroid Build Coastguard Worker /*
150*344aa361SAndroid Build Coastguard Worker  * A few helper macros for static dispatch
151*344aa361SAndroid Build Coastguard Worker  */
152*344aa361SAndroid Build Coastguard Worker #define NB_ARGS_HELPER(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
153*344aa361SAndroid Build Coastguard Worker #define NB_ARGS(...) NB_ARGS_HELPER(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0)
154*344aa361SAndroid Build Coastguard Worker 
155*344aa361SAndroid Build Coastguard Worker #define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
156*344aa361SAndroid Build Coastguard Worker #define PRIMITIVE_CAT(a, ...) a##__VA_ARGS__
157*344aa361SAndroid Build Coastguard Worker 
158*344aa361SAndroid Build Coastguard Worker #define EVAL(...) __VA_ARGS__
159*344aa361SAndroid Build Coastguard Worker 
160*344aa361SAndroid Build Coastguard Worker __BEGIN_CDECLS
161*344aa361SAndroid Build Coastguard Worker 
162*344aa361SAndroid Build Coastguard Worker /**
163*344aa361SAndroid Build Coastguard Worker  * struct benchmark_internal_state - Store internals for current bench.
164*344aa361SAndroid Build Coastguard Worker  * @last_bench_body_duration:   nanoseconds duration of the last execution of
165*344aa361SAndroid Build Coastguard Worker  *                              the bench body.
166*344aa361SAndroid Build Coastguard Worker  * @cur_param_idx:              index of current parameter in param_array.
167*344aa361SAndroid Build Coastguard Worker  * @pmu:                        state of pmu counters
168*344aa361SAndroid Build Coastguard Worker  */
169*344aa361SAndroid Build Coastguard Worker static struct benchmark_internal_state {
170*344aa361SAndroid Build Coastguard Worker     int64_t last_bench_body_duration;
171*344aa361SAndroid Build Coastguard Worker     size_t cur_param_idx;
172*344aa361SAndroid Build Coastguard Worker #ifdef WITH_TEST_PMU
173*344aa361SAndroid Build Coastguard Worker     struct trusty_pmu_state pmu;
174*344aa361SAndroid Build Coastguard Worker #endif
175*344aa361SAndroid Build Coastguard Worker } bench_state;
176*344aa361SAndroid Build Coastguard Worker 
177*344aa361SAndroid Build Coastguard Worker /**
178*344aa361SAndroid Build Coastguard Worker  * bench_get_duration_ns - convenience function to use in BENCH_RESULT to get
179*344aa361SAndroid Build Coastguard Worker  * the duration of last bench body execution.
180*344aa361SAndroid Build Coastguard Worker  *
181*344aa361SAndroid Build Coastguard Worker  * Return: The duration of the last completed BENCH body in nanoseconds.
182*344aa361SAndroid Build Coastguard Worker  */
bench_get_duration_ns(void)183*344aa361SAndroid Build Coastguard Worker static inline int64_t bench_get_duration_ns(void) {
184*344aa361SAndroid Build Coastguard Worker     return bench_state.last_bench_body_duration;
185*344aa361SAndroid Build Coastguard Worker }
186*344aa361SAndroid Build Coastguard Worker 
187*344aa361SAndroid Build Coastguard Worker /**
188*344aa361SAndroid Build Coastguard Worker  * bench_get_param_idx - convenience function to use to get the
189*344aa361SAndroid Build Coastguard Worker  * index of the current parameter BENCH_XXX is running for.
190*344aa361SAndroid Build Coastguard Worker  * Return: The index of the parameter BENCH_XXX is running for.
191*344aa361SAndroid Build Coastguard Worker  */
bench_get_param_idx(void)192*344aa361SAndroid Build Coastguard Worker static inline size_t bench_get_param_idx(void) {
193*344aa361SAndroid Build Coastguard Worker     return bench_state.cur_param_idx % trusty_cur_bench_nb_params;
194*344aa361SAndroid Build Coastguard Worker }
195*344aa361SAndroid Build Coastguard Worker 
196*344aa361SAndroid Build Coastguard Worker /**
197*344aa361SAndroid Build Coastguard Worker  * bench_get_cpu_idx - convenience function to use to get the
198*344aa361SAndroid Build Coastguard Worker  * index of the current cpu BENCH_XXX is running for.
199*344aa361SAndroid Build Coastguard Worker  * Return: The index of the cpu BENCH_XXX is running for.
200*344aa361SAndroid Build Coastguard Worker  */
bench_get_cpu_idx(void)201*344aa361SAndroid Build Coastguard Worker static inline size_t bench_get_cpu_idx(void) {
202*344aa361SAndroid Build Coastguard Worker     return bench_state.cur_param_idx / trusty_cur_bench_nb_params;
203*344aa361SAndroid Build Coastguard Worker }
204*344aa361SAndroid Build Coastguard Worker 
205*344aa361SAndroid Build Coastguard Worker /*
206*344aa361SAndroid Build Coastguard Worker  * Helper macros to run on tests on all CPUs
207*344aa361SAndroid Build Coastguard Worker  */
208*344aa361SAndroid Build Coastguard Worker #if defined(TRUSTY_USERSPACE) && defined(WITH_PTHREAD)
trusty_bench_multi_cpus_setup(void)209*344aa361SAndroid Build Coastguard Worker static int trusty_bench_multi_cpus_setup(void) {
210*344aa361SAndroid Build Coastguard Worker     if (trusty_bench_nb_cpu > 1) {
211*344aa361SAndroid Build Coastguard Worker         cpu_set_t cpu_set;
212*344aa361SAndroid Build Coastguard Worker 
213*344aa361SAndroid Build Coastguard Worker         CPU_ZERO(&cpu_set);
214*344aa361SAndroid Build Coastguard Worker         CPU_SET(bench_state.cur_param_idx / trusty_cur_bench_nb_params,
215*344aa361SAndroid Build Coastguard Worker                 &cpu_set);
216*344aa361SAndroid Build Coastguard Worker 
217*344aa361SAndroid Build Coastguard Worker         return pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t),
218*344aa361SAndroid Build Coastguard Worker                                       &cpu_set);
219*344aa361SAndroid Build Coastguard Worker     }
220*344aa361SAndroid Build Coastguard Worker     return NO_ERROR;
221*344aa361SAndroid Build Coastguard Worker }
222*344aa361SAndroid Build Coastguard Worker 
trusty_bench_multi_cpus_teardown(void)223*344aa361SAndroid Build Coastguard Worker static int trusty_bench_multi_cpus_teardown(void) {
224*344aa361SAndroid Build Coastguard Worker     if (trusty_bench_nb_cpu > 1) {
225*344aa361SAndroid Build Coastguard Worker         cpu_set_t cpu_set;
226*344aa361SAndroid Build Coastguard Worker 
227*344aa361SAndroid Build Coastguard Worker         CPU_ZERO(&cpu_set);
228*344aa361SAndroid Build Coastguard Worker         for (int i = 0; i < SMP_MAX_CPUS; i++) {
229*344aa361SAndroid Build Coastguard Worker             CPU_SET(i, &cpu_set);
230*344aa361SAndroid Build Coastguard Worker         }
231*344aa361SAndroid Build Coastguard Worker 
232*344aa361SAndroid Build Coastguard Worker         return pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t),
233*344aa361SAndroid Build Coastguard Worker                                       &cpu_set);
234*344aa361SAndroid Build Coastguard Worker     }
235*344aa361SAndroid Build Coastguard Worker     return NO_ERROR;
236*344aa361SAndroid Build Coastguard Worker }
237*344aa361SAndroid Build Coastguard Worker #elif !defined(TRUSTY_USERSPACE) && WITH_SMP
trusty_bench_multi_cpus_setup(void)238*344aa361SAndroid Build Coastguard Worker static int trusty_bench_multi_cpus_setup(void) {
239*344aa361SAndroid Build Coastguard Worker     if (trusty_bench_nb_cpu > 1) {
240*344aa361SAndroid Build Coastguard Worker         const int cpu = bench_state.cur_param_idx / trusty_cur_bench_nb_params;
241*344aa361SAndroid Build Coastguard Worker 
242*344aa361SAndroid Build Coastguard Worker         if (cpu < SMP_MAX_CPUS && mp_is_cpu_active(cpu)) {
243*344aa361SAndroid Build Coastguard Worker             thread_set_pinned_cpu(get_current_thread(), cpu);
244*344aa361SAndroid Build Coastguard Worker         } else {
245*344aa361SAndroid Build Coastguard Worker             return EINVAL;
246*344aa361SAndroid Build Coastguard Worker         }
247*344aa361SAndroid Build Coastguard Worker     }
248*344aa361SAndroid Build Coastguard Worker 
249*344aa361SAndroid Build Coastguard Worker     return NO_ERROR;
250*344aa361SAndroid Build Coastguard Worker }
251*344aa361SAndroid Build Coastguard Worker 
trusty_bench_multi_cpus_teardown(void)252*344aa361SAndroid Build Coastguard Worker static int trusty_bench_multi_cpus_teardown(void) {
253*344aa361SAndroid Build Coastguard Worker     if (trusty_bench_nb_cpu > 1) {
254*344aa361SAndroid Build Coastguard Worker         thread_set_pinned_cpu(get_current_thread(), -1);
255*344aa361SAndroid Build Coastguard Worker     }
256*344aa361SAndroid Build Coastguard Worker     return NO_ERROR;
257*344aa361SAndroid Build Coastguard Worker }
258*344aa361SAndroid Build Coastguard Worker #else
trusty_bench_multi_cpus_setup(void)259*344aa361SAndroid Build Coastguard Worker static int trusty_bench_multi_cpus_setup(void) {
260*344aa361SAndroid Build Coastguard Worker     return NO_ERROR;
261*344aa361SAndroid Build Coastguard Worker }
262*344aa361SAndroid Build Coastguard Worker 
trusty_bench_multi_cpus_teardown(void)263*344aa361SAndroid Build Coastguard Worker static int trusty_bench_multi_cpus_teardown(void) {
264*344aa361SAndroid Build Coastguard Worker     return NO_ERROR;
265*344aa361SAndroid Build Coastguard Worker }
266*344aa361SAndroid Build Coastguard Worker #endif
267*344aa361SAndroid Build Coastguard Worker 
268*344aa361SAndroid Build Coastguard Worker /**
269*344aa361SAndroid Build Coastguard Worker  * trusty_bench_update_metric -  Update the appropriate metric with the value
270*344aa361SAndroid Build Coastguard Worker  * returned by BENCH_RESULT
271*344aa361SAndroid Build Coastguard Worker  * @m:              The metric whose aggregate needs to be updated.
272*344aa361SAndroid Build Coastguard Worker  * @val:            The value returned by BENCH_RESULT.
273*344aa361SAndroid Build Coastguard Worker  */
trusty_bench_update_metric(struct bench_metric_node * m,int64_t val)274*344aa361SAndroid Build Coastguard Worker static inline void trusty_bench_update_metric(struct bench_metric_node* m,
275*344aa361SAndroid Build Coastguard Worker                                               int64_t val) {
276*344aa361SAndroid Build Coastguard Worker     m->cnt += 1;
277*344aa361SAndroid Build Coastguard Worker     m->tot += val;
278*344aa361SAndroid Build Coastguard Worker     m->aggregates[BENCH_AGGREGATE_AVG] = m->tot / m->cnt;
279*344aa361SAndroid Build Coastguard Worker     m->aggregates[BENCH_AGGREGATE_MIN] =
280*344aa361SAndroid Build Coastguard Worker             MIN(m->aggregates[BENCH_AGGREGATE_MIN], val);
281*344aa361SAndroid Build Coastguard Worker     m->aggregates[BENCH_AGGREGATE_MAX] =
282*344aa361SAndroid Build Coastguard Worker             MAX(m->aggregates[BENCH_AGGREGATE_MAX], val);
283*344aa361SAndroid Build Coastguard Worker }
284*344aa361SAndroid Build Coastguard Worker 
285*344aa361SAndroid Build Coastguard Worker /**
286*344aa361SAndroid Build Coastguard Worker  * trusty_bench_run_metrics -        Run All Metric Updaters after one iteration
287*344aa361SAndroid Build Coastguard Worker  * of bench function for all param/metric in the last BENCH.
288*344aa361SAndroid Build Coastguard Worker  * @metric_list:        List of metrics aggregated during all BENCH runs.
289*344aa361SAndroid Build Coastguard Worker  * @param_idx:          Index of the current parameter in the param_array of
290*344aa361SAndroid Build Coastguard Worker  *                      BENCH.
291*344aa361SAndroid Build Coastguard Worker  * @cold_run:           Are we updating metrics for the initial cold run?
292*344aa361SAndroid Build Coastguard Worker  */
trusty_bench_run_metrics(struct list_node * metric_list,size_t param_idx,bool cold_run)293*344aa361SAndroid Build Coastguard Worker static inline void trusty_bench_run_metrics(struct list_node* metric_list,
294*344aa361SAndroid Build Coastguard Worker                                             size_t param_idx,
295*344aa361SAndroid Build Coastguard Worker                                             bool cold_run) {
296*344aa361SAndroid Build Coastguard Worker     struct bench_metric_list_node* entry;
297*344aa361SAndroid Build Coastguard Worker 
298*344aa361SAndroid Build Coastguard Worker     list_for_every_entry(metric_list, entry, struct bench_metric_list_node,
299*344aa361SAndroid Build Coastguard Worker                          node) {
300*344aa361SAndroid Build Coastguard Worker         if (param_idx == entry->param_idx) {
301*344aa361SAndroid Build Coastguard Worker             if (cold_run) {
302*344aa361SAndroid Build Coastguard Worker                 entry->metric.cold = entry->bench_result();
303*344aa361SAndroid Build Coastguard Worker             } else {
304*344aa361SAndroid Build Coastguard Worker                 trusty_bench_update_metric(&entry->metric,
305*344aa361SAndroid Build Coastguard Worker                                            entry->bench_result());
306*344aa361SAndroid Build Coastguard Worker             }
307*344aa361SAndroid Build Coastguard Worker         }
308*344aa361SAndroid Build Coastguard Worker     }
309*344aa361SAndroid Build Coastguard Worker }
310*344aa361SAndroid Build Coastguard Worker 
311*344aa361SAndroid Build Coastguard Worker /**
312*344aa361SAndroid Build Coastguard Worker  * trusty_bench_check_metrics -        Check if All Metric are within range
313*344aa361SAndroid Build Coastguard Worker  * after one iteration of bench function for all param/metric in the last BENCH.
314*344aa361SAndroid Build Coastguard Worker  * @metric_list:        List of metrics aggregated during all BENCH runs.
315*344aa361SAndroid Build Coastguard Worker  * @param_idx:          Index of the current parameter in the param_array of
316*344aa361SAndroid Build Coastguard Worker  *                      BENCH.
317*344aa361SAndroid Build Coastguard Worker  */
trusty_bench_check_metrics(struct list_node * metric_list,size_t param_idx)318*344aa361SAndroid Build Coastguard Worker static inline bool trusty_bench_check_metrics(struct list_node* metric_list,
319*344aa361SAndroid Build Coastguard Worker                                               size_t param_idx) {
320*344aa361SAndroid Build Coastguard Worker     struct bench_metric_list_node* entry;
321*344aa361SAndroid Build Coastguard Worker 
322*344aa361SAndroid Build Coastguard Worker     list_for_every_entry(metric_list, entry, struct bench_metric_list_node,
323*344aa361SAndroid Build Coastguard Worker                          node) {
324*344aa361SAndroid Build Coastguard Worker         if (param_idx == entry->param_idx) {
325*344aa361SAndroid Build Coastguard Worker             if (entry->check_results_cb != NULL &&
326*344aa361SAndroid Build Coastguard Worker                 !entry->check_results_cb(entry)) {
327*344aa361SAndroid Build Coastguard Worker                 return false;
328*344aa361SAndroid Build Coastguard Worker             }
329*344aa361SAndroid Build Coastguard Worker         }
330*344aa361SAndroid Build Coastguard Worker     }
331*344aa361SAndroid Build Coastguard Worker     return true;
332*344aa361SAndroid Build Coastguard Worker }
333*344aa361SAndroid Build Coastguard Worker 
334*344aa361SAndroid Build Coastguard Worker /**
335*344aa361SAndroid Build Coastguard Worker  * trusty_bench_reset_metrics -        Run All Metric Updaters after one
336*344aa361SAndroid Build Coastguard Worker  * iteration of bench function for all param/metric in the last BENCH.
337*344aa361SAndroid Build Coastguard Worker  * @metric_list:        List of metrics aggregated during all BENCH runs.
338*344aa361SAndroid Build Coastguard Worker  * @param_idx:          Index of the current parameter in the param_array of
339*344aa361SAndroid Build Coastguard Worker  *                      BENCH.
340*344aa361SAndroid Build Coastguard Worker  */
trusty_bench_reset_metrics(struct list_node * metric_list,size_t param_idx)341*344aa361SAndroid Build Coastguard Worker static inline void trusty_bench_reset_metrics(struct list_node* metric_list,
342*344aa361SAndroid Build Coastguard Worker                                               size_t param_idx) {
343*344aa361SAndroid Build Coastguard Worker     struct bench_metric_list_node* entry;
344*344aa361SAndroid Build Coastguard Worker 
345*344aa361SAndroid Build Coastguard Worker     list_for_every_entry(metric_list, entry, struct bench_metric_list_node,
346*344aa361SAndroid Build Coastguard Worker                          node) {
347*344aa361SAndroid Build Coastguard Worker         if (param_idx == entry->param_idx) {
348*344aa361SAndroid Build Coastguard Worker             trusty_bench_update_metric(&entry->metric, entry->bench_result());
349*344aa361SAndroid Build Coastguard Worker         }
350*344aa361SAndroid Build Coastguard Worker     }
351*344aa361SAndroid Build Coastguard Worker }
352*344aa361SAndroid Build Coastguard Worker 
353*344aa361SAndroid Build Coastguard Worker /**
354*344aa361SAndroid Build Coastguard Worker  * BENCH_SETUP -        Runs before every execution of the body of the BENCH
355*344aa361SAndroid Build Coastguard Worker  *                      macro. Can be used to allocate memory, setup 'states',
356*344aa361SAndroid Build Coastguard Worker  *                      initialize 'sessions'...
357*344aa361SAndroid Build Coastguard Worker  * @suite_name:         Identifier of the current suite.
358*344aa361SAndroid Build Coastguard Worker  */
359*344aa361SAndroid Build Coastguard Worker #define BENCH_SETUP(suite_name)          \
360*344aa361SAndroid Build Coastguard Worker     static int suite_name##_setup(void); \
361*344aa361SAndroid Build Coastguard Worker     static int suite_name##_setup(void)
362*344aa361SAndroid Build Coastguard Worker 
363*344aa361SAndroid Build Coastguard Worker /**
364*344aa361SAndroid Build Coastguard Worker  * BENCH_TEARDOWN -     Runs after every execution of the body of the BENCH
365*344aa361SAndroid Build Coastguard Worker  *                      macro. Can be used to free memory, clear 'states',
366*344aa361SAndroid Build Coastguard Worker  *                      close 'sessions'...
367*344aa361SAndroid Build Coastguard Worker  * @suite_name:         Identifier of the current suite.
368*344aa361SAndroid Build Coastguard Worker  */
369*344aa361SAndroid Build Coastguard Worker #define BENCH_TEARDOWN(suite_name)           \
370*344aa361SAndroid Build Coastguard Worker     static void suite_name##_teardown(void); \
371*344aa361SAndroid Build Coastguard Worker     static void suite_name##_teardown(void)
372*344aa361SAndroid Build Coastguard Worker 
373*344aa361SAndroid Build Coastguard Worker /**
374*344aa361SAndroid Build Coastguard Worker  * BENCH_RESULT_INNER -       Declare a metric name for the corresponding BENCH
375*344aa361SAndroid Build Coastguard Worker  * and declare the functions to update it after every iteration
376*344aa361SAndroid Build Coastguard Worker  * @suite_name:         Identifier of the current suite.
377*344aa361SAndroid Build Coastguard Worker  * @bench_name:         Unique identifier of the Bench in the suite.
378*344aa361SAndroid Build Coastguard Worker  * @metric_name:        Name of the metric to print in the result table.
379*344aa361SAndroid Build Coastguard Worker  * @formatted_value_cb: [optional] A callback of
380*344aa361SAndroid Build Coastguard Worker  *                      trusty_bench_get_formatted_value_callback_t type
381*344aa361SAndroid Build Coastguard Worker  *                      for formatting the result
382*344aa361SAndroid Build Coastguard Worker  *                      value to a string
383*344aa361SAndroid Build Coastguard Worker  * @param_name_cb:      [optional] A callback of
384*344aa361SAndroid Build Coastguard Worker  *                      trusty_bench_get_param_name_callback_t type
385*344aa361SAndroid Build Coastguard Worker  *                      for formatting the param name
386*344aa361SAndroid Build Coastguard Worker  * @check_results_cb:   [optional] A callback of
387*344aa361SAndroid Build Coastguard Worker  *                      trusty_bench_check_results_callback_t
388*344aa361SAndroid Build Coastguard Worker  *                      type for formatting the param name
389*344aa361SAndroid Build Coastguard Worker  */
390*344aa361SAndroid Build Coastguard Worker #define BENCH_RESULT_INNER(suite_name, bench_name, metric_name,                 \
391*344aa361SAndroid Build Coastguard Worker                            formatted_value_cb_, param_name_cb_,                 \
392*344aa361SAndroid Build Coastguard Worker                            check_results_cb_)                                   \
393*344aa361SAndroid Build Coastguard Worker     static int64_t update_##suite_name##_##bench_name##_##metric_name(void);    \
394*344aa361SAndroid Build Coastguard Worker     static struct bench_metric_list_node                                        \
395*344aa361SAndroid Build Coastguard Worker             suite_name##_##bench_name##_##metric_name##_node = {                \
396*344aa361SAndroid Build Coastguard Worker                     .node = LIST_INITIAL_CLEARED_VALUE,                         \
397*344aa361SAndroid Build Coastguard Worker                     .metric = {0, 0, 0, {INT32_MAX, 0, 0}},                     \
398*344aa361SAndroid Build Coastguard Worker                     .name = STRINGIFY(metric_name),                             \
399*344aa361SAndroid Build Coastguard Worker                     .param_idx = 0,                                             \
400*344aa361SAndroid Build Coastguard Worker                     .nb_params = 0,                                             \
401*344aa361SAndroid Build Coastguard Worker                     .bench_result =                                             \
402*344aa361SAndroid Build Coastguard Worker                             update_##suite_name##_##bench_name##_##metric_name, \
403*344aa361SAndroid Build Coastguard Worker                     .formatted_value_cb = formatted_value_cb_,                  \
404*344aa361SAndroid Build Coastguard Worker                     .param_name_cb = param_name_cb_,                            \
405*344aa361SAndroid Build Coastguard Worker                     .check_results_cb = check_results_cb_};                     \
406*344aa361SAndroid Build Coastguard Worker     __attribute__((constructor)) void                                           \
407*344aa361SAndroid Build Coastguard Worker             suite_name##_##bench_name##_##metric_name##_add(void) {             \
408*344aa361SAndroid Build Coastguard Worker         list_add_tail(&suite_name##_##bench_name##_metric_list,                 \
409*344aa361SAndroid Build Coastguard Worker                       &suite_name##_##bench_name##_##metric_name##_node.node);  \
410*344aa361SAndroid Build Coastguard Worker     }                                                                           \
411*344aa361SAndroid Build Coastguard Worker                                                                                 \
412*344aa361SAndroid Build Coastguard Worker     static int64_t update_##suite_name##_##bench_name##_##metric_name(void)
413*344aa361SAndroid Build Coastguard Worker 
414*344aa361SAndroid Build Coastguard Worker /* Dispatch Mechanics for BENCH_RESULT */
415*344aa361SAndroid Build Coastguard Worker #define BENCH_RESULT_3(suite_name, bench_name, metric_name) \
416*344aa361SAndroid Build Coastguard Worker     BENCH_RESULT_INNER(suite_name, bench_name, metric_name, 0, 0, 0)
417*344aa361SAndroid Build Coastguard Worker 
418*344aa361SAndroid Build Coastguard Worker #define BENCH_RESULT_4(suite_name, bench_name, metric_name, \
419*344aa361SAndroid Build Coastguard Worker                        formatted_value_cb)                  \
420*344aa361SAndroid Build Coastguard Worker     BENCH_RESULT_INNER(suite_name, bench_name, metric_name, \
421*344aa361SAndroid Build Coastguard Worker                        formatted_value_cb, 0, 0)
422*344aa361SAndroid Build Coastguard Worker 
423*344aa361SAndroid Build Coastguard Worker #define BENCH_RESULT_5(suite_name, bench_name, metric_name, \
424*344aa361SAndroid Build Coastguard Worker                        formatted_value_cb, param_name_cb)   \
425*344aa361SAndroid Build Coastguard Worker     BENCH_RESULT_INNER(suite_name, bench_name, metric_name, \
426*344aa361SAndroid Build Coastguard Worker                        formatted_value_cb, param_name_cb, 0)
427*344aa361SAndroid Build Coastguard Worker 
428*344aa361SAndroid Build Coastguard Worker #define BENCH_RESULT_6(suite_name, bench_name, metric_name,                 \
429*344aa361SAndroid Build Coastguard Worker                        formatted_value_cb, param_name_cb, check_results_cb) \
430*344aa361SAndroid Build Coastguard Worker     BENCH_RESULT_INNER(suite_name, bench_name, metric_name,                 \
431*344aa361SAndroid Build Coastguard Worker                        formatted_value_cb, param_name_cb, check_results_cb)
432*344aa361SAndroid Build Coastguard Worker 
433*344aa361SAndroid Build Coastguard Worker #ifdef WITH_TEST_PMU
434*344aa361SAndroid Build Coastguard Worker /**
435*344aa361SAndroid Build Coastguard Worker  * bench_get_pmu_cnt - convenience function to use in BENCH_RESULT to get
436*344aa361SAndroid Build Coastguard Worker  * the value of a pmu counter for the last bench body execution.
437*344aa361SAndroid Build Coastguard Worker  *
438*344aa361SAndroid Build Coastguard Worker  * Return: The value of a pmu counter of the last completed BENCH body.
439*344aa361SAndroid Build Coastguard Worker  */
bench_get_pmu_cnt(size_t idx)440*344aa361SAndroid Build Coastguard Worker static inline int64_t bench_get_pmu_cnt(size_t idx) {
441*344aa361SAndroid Build Coastguard Worker     return bench_state.pmu.vals[idx];
442*344aa361SAndroid Build Coastguard Worker }
443*344aa361SAndroid Build Coastguard Worker #else
bench_get_pmu_cnt(size_t idx)444*344aa361SAndroid Build Coastguard Worker static inline int64_t bench_get_pmu_cnt(size_t idx) {
445*344aa361SAndroid Build Coastguard Worker     return 0;
446*344aa361SAndroid Build Coastguard Worker }
447*344aa361SAndroid Build Coastguard Worker #endif
448*344aa361SAndroid Build Coastguard Worker /**
449*344aa361SAndroid Build Coastguard Worker  * BENCH_RESULT             Dispatch BENCH_RESULT Called 3, 4 or 5 parameters.
450*344aa361SAndroid Build Coastguard Worker  * @suite_name:             Identifier of the current suite.
451*344aa361SAndroid Build Coastguard Worker  * @bench_name:             Unique identifier of the Bench in the suite.
452*344aa361SAndroid Build Coastguard Worker  * @metric_name:        Name of the metric to print in the result table.
453*344aa361SAndroid Build Coastguard Worker  * @formatted_value_cb:        [optional] A callback of
454*344aa361SAndroid Build Coastguard Worker  * trusty_bench_get_formatted_value_callback_t type for formatting the result
455*344aa361SAndroid Build Coastguard Worker  * value to a string
456*344aa361SAndroid Build Coastguard Worker  * @param_name_cb:              [optional] A callback of
457*344aa361SAndroid Build Coastguard Worker  * trusty_bench_get_param_name_callback_t type for formatting the param name
458*344aa361SAndroid Build Coastguard Worker  */
459*344aa361SAndroid Build Coastguard Worker #define BENCH_RESULT(...) \
460*344aa361SAndroid Build Coastguard Worker     CAT(BENCH_RESULT_, EVAL(NB_ARGS(__VA_ARGS__)))(__VA_ARGS__)
461*344aa361SAndroid Build Coastguard Worker 
462*344aa361SAndroid Build Coastguard Worker /**
463*344aa361SAndroid Build Coastguard Worker  * PARAM_TEST_NODES_SIMPLE -    Create the unparameterized test node lists for
464*344aa361SAndroid Build Coastguard Worker  *                              BENCH
465*344aa361SAndroid Build Coastguard Worker  * @suite_name:                 Identifier of the current suite.
466*344aa361SAndroid Build Coastguard Worker  * @bench_name:                 Unique identifier of the Bench in the suite.
467*344aa361SAndroid Build Coastguard Worker  */
468*344aa361SAndroid Build Coastguard Worker #define PARAM_TEST_NODES_SIMPLE(suite_name, bench_name)                        \
469*344aa361SAndroid Build Coastguard Worker     static struct test_list_node suite_name##_##bench_name##_bench_##_node = { \
470*344aa361SAndroid Build Coastguard Worker             .node = LIST_INITIAL_CLEARED_VALUE,                                \
471*344aa361SAndroid Build Coastguard Worker             .suite = STRINGIFY(suite_name_),                                   \
472*344aa361SAndroid Build Coastguard Worker             .name = STRINGIFY(bench_name_),                                    \
473*344aa361SAndroid Build Coastguard Worker             .func = suite_name##_##bench_name##_bench_,                        \
474*344aa361SAndroid Build Coastguard Worker             .needs_param = 0,                                                  \
475*344aa361SAndroid Build Coastguard Worker     };                                                                         \
476*344aa361SAndroid Build Coastguard Worker                                                                                \
477*344aa361SAndroid Build Coastguard Worker     __attribute__((constructor)) void                                          \
478*344aa361SAndroid Build Coastguard Worker             suite_name##_##bench_name##_bench_##_add(void) {                   \
479*344aa361SAndroid Build Coastguard Worker         list_add_tail(&_test_list,                                             \
480*344aa361SAndroid Build Coastguard Worker                       &suite_name##_##bench_name##_bench_##_node.node);        \
481*344aa361SAndroid Build Coastguard Worker     }
482*344aa361SAndroid Build Coastguard Worker 
483*344aa361SAndroid Build Coastguard Worker /**
484*344aa361SAndroid Build Coastguard Worker  * PARAM_TEST_NODES_PARAMETRIC -    Create the unparameterized test node lists
485*344aa361SAndroid Build Coastguard Worker  *                                  for BENCH
486*344aa361SAndroid Build Coastguard Worker  * @suite_name:                     Identifier of the current suite.
487*344aa361SAndroid Build Coastguard Worker  * @bench_name:                     Unique identifier of the Bench in the suite.
488*344aa361SAndroid Build Coastguard Worker  * @params:                         identifier of the param Array for parametric
489*344aa361SAndroid Build Coastguard Worker  * benches
490*344aa361SAndroid Build Coastguard Worker  */
491*344aa361SAndroid Build Coastguard Worker #define PARAM_TEST_NODES_PARAMETRIC(suite_name, bench_name, params)       \
492*344aa361SAndroid Build Coastguard Worker     static struct test_list_node                                          \
493*344aa361SAndroid Build Coastguard Worker             suite_name##_##bench_name##_bench_##params##_node = {         \
494*344aa361SAndroid Build Coastguard Worker                     .node = LIST_INITIAL_CLEARED_VALUE,                   \
495*344aa361SAndroid Build Coastguard Worker                     .suite = STRINGIFY(suite_name_##params),              \
496*344aa361SAndroid Build Coastguard Worker                     .name = STRINGIFY(bench_name_##params),               \
497*344aa361SAndroid Build Coastguard Worker                     .func = suite_name##_##bench_name##_bench_##params,   \
498*344aa361SAndroid Build Coastguard Worker                     .needs_param = 0,                                     \
499*344aa361SAndroid Build Coastguard Worker     };                                                                    \
500*344aa361SAndroid Build Coastguard Worker                                                                           \
501*344aa361SAndroid Build Coastguard Worker     __attribute__((constructor)) void                                     \
502*344aa361SAndroid Build Coastguard Worker             suite_name##_##bench_name##_bench_##params##_add(void) {      \
503*344aa361SAndroid Build Coastguard Worker         list_add_tail(                                                    \
504*344aa361SAndroid Build Coastguard Worker                 &_test_list,                                              \
505*344aa361SAndroid Build Coastguard Worker                 &suite_name##_##bench_name##_bench_##params##_node.node); \
506*344aa361SAndroid Build Coastguard Worker     }
507*344aa361SAndroid Build Coastguard Worker 
508*344aa361SAndroid Build Coastguard Worker /**
509*344aa361SAndroid Build Coastguard Worker  * set_param_metric -       Create a list of parameterized metrics out of the
510*344aa361SAndroid Build Coastguard Worker  *                          existing list of non-parameterized metric.
511*344aa361SAndroid Build Coastguard Worker  * @unparameterized_list:   List of metrics aggregated during all BENCH
512*344aa361SAndroid Build Coastguard Worker  *                          runs.
513*344aa361SAndroid Build Coastguard Worker  * @parameterized_list:     Will be filled with nb_params *
514*344aa361SAndroid Build Coastguard Worker  *                          length_of(unparameterized_list) metrics with
515*344aa361SAndroid Build Coastguard Worker  *                          appropriate param_idx value.
516*344aa361SAndroid Build Coastguard Worker  * @nb_params:              Number of parameters of the BENCH macro.
517*344aa361SAndroid Build Coastguard Worker  * Return:                  The list of parameterized metrics.
518*344aa361SAndroid Build Coastguard Worker  */
set_param_metric(struct list_node * unparameterized_list,struct list_node * parameterized_list,size_t nb_params)519*344aa361SAndroid Build Coastguard Worker static inline struct bench_metric_list_node* set_param_metric(
520*344aa361SAndroid Build Coastguard Worker         struct list_node* unparameterized_list,
521*344aa361SAndroid Build Coastguard Worker         struct list_node* parameterized_list,
522*344aa361SAndroid Build Coastguard Worker         size_t nb_params) {
523*344aa361SAndroid Build Coastguard Worker     size_t idx = 0;
524*344aa361SAndroid Build Coastguard Worker     struct bench_metric_list_node* entry;
525*344aa361SAndroid Build Coastguard Worker     struct bench_metric_list_node* list_pool =
526*344aa361SAndroid Build Coastguard Worker             calloc(nb_params * list_length(unparameterized_list),
527*344aa361SAndroid Build Coastguard Worker                    sizeof(struct bench_metric_list_node));
528*344aa361SAndroid Build Coastguard Worker     if (list_pool == NULL) {
529*344aa361SAndroid Build Coastguard Worker         TLOGE("Failed to Allocate memory for bench_metric_list_node!");
530*344aa361SAndroid Build Coastguard Worker         return NULL;
531*344aa361SAndroid Build Coastguard Worker     }
532*344aa361SAndroid Build Coastguard Worker 
533*344aa361SAndroid Build Coastguard Worker     // clear parameterized_list from previous runs
534*344aa361SAndroid Build Coastguard Worker     struct list_node* node = NULL;
535*344aa361SAndroid Build Coastguard Worker     do {
536*344aa361SAndroid Build Coastguard Worker         node = list_remove_head(parameterized_list);
537*344aa361SAndroid Build Coastguard Worker         free(node);
538*344aa361SAndroid Build Coastguard Worker     } while (node != NULL);
539*344aa361SAndroid Build Coastguard Worker 
540*344aa361SAndroid Build Coastguard Worker     list_for_every_entry(unparameterized_list, entry,
541*344aa361SAndroid Build Coastguard Worker                          struct bench_metric_list_node, node) {
542*344aa361SAndroid Build Coastguard Worker         for (size_t idx_param = 0; idx_param < nb_params; ++idx_param) {
543*344aa361SAndroid Build Coastguard Worker             struct bench_metric_node tmp_metric = {0, 0, 0, {INT32_MAX, 0, 0}};
544*344aa361SAndroid Build Coastguard Worker 
545*344aa361SAndroid Build Coastguard Worker             list_pool[idx].metric = tmp_metric;
546*344aa361SAndroid Build Coastguard Worker             list_pool[idx].name = entry->name;
547*344aa361SAndroid Build Coastguard Worker             list_pool[idx].param_idx = idx_param;
548*344aa361SAndroid Build Coastguard Worker             list_pool[idx].nb_params = nb_params;
549*344aa361SAndroid Build Coastguard Worker             list_pool[idx].bench_result = entry->bench_result;
550*344aa361SAndroid Build Coastguard Worker             list_pool[idx].formatted_value_cb = entry->formatted_value_cb;
551*344aa361SAndroid Build Coastguard Worker             list_pool[idx].param_name_cb = entry->param_name_cb;
552*344aa361SAndroid Build Coastguard Worker             list_pool[idx].check_results_cb = entry->check_results_cb;
553*344aa361SAndroid Build Coastguard Worker             list_add_tail(parameterized_list, &(list_pool[idx].node));
554*344aa361SAndroid Build Coastguard Worker             ++idx;
555*344aa361SAndroid Build Coastguard Worker         }
556*344aa361SAndroid Build Coastguard Worker     }
557*344aa361SAndroid Build Coastguard Worker     return list_pool;
558*344aa361SAndroid Build Coastguard Worker }
559*344aa361SAndroid Build Coastguard Worker 
560*344aa361SAndroid Build Coastguard Worker /**
561*344aa361SAndroid Build Coastguard Worker  * trusty_bench_get_overhead - Get Minimal overhead of the benchmark around
562*344aa361SAndroid Build Coastguard Worker  * benched function
563*344aa361SAndroid Build Coastguard Worker  *
564*344aa361SAndroid Build Coastguard Worker  * Return:        The Value of the overhead in nanoseconds.
565*344aa361SAndroid Build Coastguard Worker  */
trusty_bench_get_overhead(void)566*344aa361SAndroid Build Coastguard Worker static int64_t trusty_bench_get_overhead(void) {
567*344aa361SAndroid Build Coastguard Worker     const size_t nb_runs = 100;
568*344aa361SAndroid Build Coastguard Worker     int64_t start_time;
569*344aa361SAndroid Build Coastguard Worker     int64_t end_time;
570*344aa361SAndroid Build Coastguard Worker     int64_t res = INT64_MAX;
571*344aa361SAndroid Build Coastguard Worker 
572*344aa361SAndroid Build Coastguard Worker     for (size_t i = 0; i < nb_runs; ++i) {
573*344aa361SAndroid Build Coastguard Worker         start_time = get_current_time_ns();
574*344aa361SAndroid Build Coastguard Worker         end_time = get_current_time_ns();
575*344aa361SAndroid Build Coastguard Worker         res = MIN(end_time - start_time, res);
576*344aa361SAndroid Build Coastguard Worker     }
577*344aa361SAndroid Build Coastguard Worker     return res;
578*344aa361SAndroid Build Coastguard Worker }
579*344aa361SAndroid Build Coastguard Worker 
580*344aa361SAndroid Build Coastguard Worker /**
581*344aa361SAndroid Build Coastguard Worker  * get_extended_bench_name - Print Status of Currently Running Bench.
582*344aa361SAndroid Build Coastguard Worker  *
583*344aa361SAndroid Build Coastguard Worker  * @test_name_in:   Name of the Current Unparameterized Test.
584*344aa361SAndroid Build Coastguard Worker  * @test_name_out:  Name of the Current Unparameterized Test.
585*344aa361SAndroid Build Coastguard Worker  *                  + "_[param_idx]"
586*344aa361SAndroid Build Coastguard Worker  *
587*344aa361SAndroid Build Coastguard Worker  * Return:          When successful, returns 0
588*344aa361SAndroid Build Coastguard Worker  *                  If test_name_out allocation/print failed returns asprintf
589*344aa361SAndroid Build Coastguard Worker  *                  return code
590*344aa361SAndroid Build Coastguard Worker  */
get_extended_bench_name(const char * test_name_in,char ** test_name_out)591*344aa361SAndroid Build Coastguard Worker static inline int get_extended_bench_name(const char* test_name_in,
592*344aa361SAndroid Build Coastguard Worker                                           char** test_name_out) {
593*344aa361SAndroid Build Coastguard Worker     int res = snprintf(NULL, 0, "%s_%zu", test_name_in,
594*344aa361SAndroid Build Coastguard Worker                        bench_state.cur_param_idx);
595*344aa361SAndroid Build Coastguard Worker     *test_name_out = NULL;
596*344aa361SAndroid Build Coastguard Worker     if (res >= 0) {
597*344aa361SAndroid Build Coastguard Worker         *test_name_out = malloc(res + 1);
598*344aa361SAndroid Build Coastguard Worker         res = snprintf(*test_name_out, res + 1, "%s_%zu", test_name_in,
599*344aa361SAndroid Build Coastguard Worker                        bench_state.cur_param_idx);
600*344aa361SAndroid Build Coastguard Worker     }
601*344aa361SAndroid Build Coastguard Worker     if (res < 0) {
602*344aa361SAndroid Build Coastguard Worker         return res;
603*344aa361SAndroid Build Coastguard Worker     }
604*344aa361SAndroid Build Coastguard Worker     if (!test_name_out) {
605*344aa361SAndroid Build Coastguard Worker         TLOGE("Cannot Allocate memory for test name\n");
606*344aa361SAndroid Build Coastguard Worker         return -1;
607*344aa361SAndroid Build Coastguard Worker     }
608*344aa361SAndroid Build Coastguard Worker     return 0;
609*344aa361SAndroid Build Coastguard Worker }
610*344aa361SAndroid Build Coastguard Worker 
611*344aa361SAndroid Build Coastguard Worker #ifdef WITH_TEST_PMU
612*344aa361SAndroid Build Coastguard Worker #define BENCH_INIT_PMU(evt_arr) \
613*344aa361SAndroid Build Coastguard Worker     init_pmu_state(evt_arr, countof(evt_arr), &bench_state.pmu)
614*344aa361SAndroid Build Coastguard Worker #define PMU_START() pmu_start(&bench_state.pmu);
615*344aa361SAndroid Build Coastguard Worker #define PMU_STOP() pmu_stop(&bench_state.pmu);
616*344aa361SAndroid Build Coastguard Worker #define RESET_PMU() reset_pmu_cnts(&bench_state.pmu)
617*344aa361SAndroid Build Coastguard Worker #define CLEAN_PMU() clean_pmu(&bench_state.pmu)
618*344aa361SAndroid Build Coastguard Worker #else
619*344aa361SAndroid Build Coastguard Worker #define BENCH_INIT_PMU(evt_arr) (void)(evt_arr)
620*344aa361SAndroid Build Coastguard Worker #define PMU_START()
621*344aa361SAndroid Build Coastguard Worker #define PMU_STOP()
622*344aa361SAndroid Build Coastguard Worker #define RESET_PMU()
623*344aa361SAndroid Build Coastguard Worker #define CLEAN_PMU()
624*344aa361SAndroid Build Coastguard Worker #endif
625*344aa361SAndroid Build Coastguard Worker 
626*344aa361SAndroid Build Coastguard Worker /**
627*344aa361SAndroid Build Coastguard Worker  * BENCH_CORE -             Called by both parametrized and unparameterized
628*344aa361SAndroid Build Coastguard Worker  * BENCH for their common part
629*344aa361SAndroid Build Coastguard Worker  * @suite_name:             Identifier of the current suite.
630*344aa361SAndroid Build Coastguard Worker  * @bench_name:             Unique identifier of the Bench in the suite.
631*344aa361SAndroid Build Coastguard Worker  * @nb_runs:                The number of execution of its body for each param
632*344aa361SAndroid Build Coastguard Worker  * @nb_params:              Number of params in params array
633*344aa361SAndroid Build Coastguard Worker  * @params:                 An array T array_name[nb_params] of parameter
634*344aa361SAndroid Build Coastguard Worker  * @metric_list:            List of metric nodes to update
635*344aa361SAndroid Build Coastguard Worker  */
636*344aa361SAndroid Build Coastguard Worker #define BENCH_CORE(suite_name, bench_name, nb_runs, nb_params, params,          \
637*344aa361SAndroid Build Coastguard Worker                    metric_list)                                                 \
638*344aa361SAndroid Build Coastguard Worker     reset_vertical_print_widths();                                              \
639*344aa361SAndroid Build Coastguard Worker     trusty_bench_print_title(STRINGIFY(suite_name), STRINGIFY(bench_name),      \
640*344aa361SAndroid Build Coastguard Worker                              STRINGIFY(params));                                \
641*344aa361SAndroid Build Coastguard Worker     static trusty_bench_print_callback_t trusty_bench_print_cb =                \
642*344aa361SAndroid Build Coastguard Worker             &BENCHMARK_PRINT_CB;                                                \
643*344aa361SAndroid Build Coastguard Worker     trusty_cur_bench_nb_params = nb_params;                                     \
644*344aa361SAndroid Build Coastguard Worker     for (size_t idx_param = 0; idx_param < (nb_params * trusty_bench_nb_cpu);   \
645*344aa361SAndroid Build Coastguard Worker          ++idx_param) {                                                         \
646*344aa361SAndroid Build Coastguard Worker         bench_state.cur_param_idx = idx_param;                                  \
647*344aa361SAndroid Build Coastguard Worker         char* extended_test_name = NULL;                                        \
648*344aa361SAndroid Build Coastguard Worker         int res_alloc = get_extended_bench_name(                                \
649*344aa361SAndroid Build Coastguard Worker                 STRINGIFY(bench_name##_##params), &extended_test_name);         \
650*344aa361SAndroid Build Coastguard Worker         if (res_alloc < 0) {                                                    \
651*344aa361SAndroid Build Coastguard Worker             TLOGE("ERROR %d expanding test name\n", res_alloc);                 \
652*344aa361SAndroid Build Coastguard Worker             _test_context.all_ok = false;                                       \
653*344aa361SAndroid Build Coastguard Worker             _test_context.tests_failed++;                                       \
654*344aa361SAndroid Build Coastguard Worker             continue;                                                           \
655*344aa361SAndroid Build Coastguard Worker         }                                                                       \
656*344aa361SAndroid Build Coastguard Worker         TEST_BEGIN_FUNC(STRINGIFY(suite_name), extended_test_name);             \
657*344aa361SAndroid Build Coastguard Worker                                                                                 \
658*344aa361SAndroid Build Coastguard Worker         int rc = trusty_bench_multi_cpus_setup();                               \
659*344aa361SAndroid Build Coastguard Worker         if (rc != NO_ERROR) {                                                   \
660*344aa361SAndroid Build Coastguard Worker             _test_context.skipped = true;                                       \
661*344aa361SAndroid Build Coastguard Worker             _test_context.tests_skipped++;                                      \
662*344aa361SAndroid Build Coastguard Worker         } else {                                                                \
663*344aa361SAndroid Build Coastguard Worker             rc = suite_name##_setup();                                          \
664*344aa361SAndroid Build Coastguard Worker         }                                                                       \
665*344aa361SAndroid Build Coastguard Worker                                                                                 \
666*344aa361SAndroid Build Coastguard Worker         if (_test_context.skipped) {                                            \
667*344aa361SAndroid Build Coastguard Worker             trusty_unittest_print_status(" SKIPPED");                           \
668*344aa361SAndroid Build Coastguard Worker             continue;                                                           \
669*344aa361SAndroid Build Coastguard Worker         } else if (rc != NO_ERROR) {                                            \
670*344aa361SAndroid Build Coastguard Worker             TLOGE("ERROR %d during benchmark setup\n", rc);                     \
671*344aa361SAndroid Build Coastguard Worker             _test_context.all_ok = false;                                       \
672*344aa361SAndroid Build Coastguard Worker             _test_context.tests_failed++;                                       \
673*344aa361SAndroid Build Coastguard Worker             continue;                                                           \
674*344aa361SAndroid Build Coastguard Worker         }                                                                       \
675*344aa361SAndroid Build Coastguard Worker         int64_t overhead = trusty_bench_get_overhead();                         \
676*344aa361SAndroid Build Coastguard Worker                                                                                 \
677*344aa361SAndroid Build Coastguard Worker         PMU_START();                                                            \
678*344aa361SAndroid Build Coastguard Worker         /* Cold Run */                                                          \
679*344aa361SAndroid Build Coastguard Worker         int64_t start_time;                                                     \
680*344aa361SAndroid Build Coastguard Worker         int64_t end_time;                                                       \
681*344aa361SAndroid Build Coastguard Worker         start_time = get_current_time_ns();                                     \
682*344aa361SAndroid Build Coastguard Worker         int64_t res = suite_name##_##bench_name##_inner_##params();             \
683*344aa361SAndroid Build Coastguard Worker         end_time = get_current_time_ns();                                       \
684*344aa361SAndroid Build Coastguard Worker                                                                                 \
685*344aa361SAndroid Build Coastguard Worker         PMU_STOP();                                                             \
686*344aa361SAndroid Build Coastguard Worker                                                                                 \
687*344aa361SAndroid Build Coastguard Worker         if (res != NO_ERROR) {                                                  \
688*344aa361SAndroid Build Coastguard Worker             TLOGE("ERROR During Cold Run%" PRId64 "\n", res);                   \
689*344aa361SAndroid Build Coastguard Worker             _test_context.all_ok = false;                                       \
690*344aa361SAndroid Build Coastguard Worker             _test_context.tests_failed++;                                       \
691*344aa361SAndroid Build Coastguard Worker             continue;                                                           \
692*344aa361SAndroid Build Coastguard Worker         }                                                                       \
693*344aa361SAndroid Build Coastguard Worker                                                                                 \
694*344aa361SAndroid Build Coastguard Worker         bench_state.last_bench_body_duration = end_time - start_time;           \
695*344aa361SAndroid Build Coastguard Worker         if (5 * overhead >= bench_state.last_bench_body_duration) {             \
696*344aa361SAndroid Build Coastguard Worker             trusty_unittest_printf(                                             \
697*344aa361SAndroid Build Coastguard Worker                     "WARNING: Benchmark internal function is too fast %" PRId64 \
698*344aa361SAndroid Build Coastguard Worker                     "ns, while the benchmark overhead is %" PRId64 "ns.",       \
699*344aa361SAndroid Build Coastguard Worker                     overhead, bench_state.last_bench_body_duration);            \
700*344aa361SAndroid Build Coastguard Worker         }                                                                       \
701*344aa361SAndroid Build Coastguard Worker                                                                                 \
702*344aa361SAndroid Build Coastguard Worker         bench_state.last_bench_body_duration -= overhead;                       \
703*344aa361SAndroid Build Coastguard Worker                                                                                 \
704*344aa361SAndroid Build Coastguard Worker         if (!_test_context.hard_fail && _test_context.all_ok) {                 \
705*344aa361SAndroid Build Coastguard Worker             trusty_bench_run_metrics(&metric_list, idx_param, true);            \
706*344aa361SAndroid Build Coastguard Worker             RESET_PMU();                                                        \
707*344aa361SAndroid Build Coastguard Worker         }                                                                       \
708*344aa361SAndroid Build Coastguard Worker                                                                                 \
709*344aa361SAndroid Build Coastguard Worker         for (size_t idx_run = 0; idx_run < nb_runs; ++idx_run) {                \
710*344aa361SAndroid Build Coastguard Worker             if (!_test_context.hard_fail && _test_context.all_ok) {             \
711*344aa361SAndroid Build Coastguard Worker                 PMU_START();                                                    \
712*344aa361SAndroid Build Coastguard Worker                 start_time = get_current_time_ns();                             \
713*344aa361SAndroid Build Coastguard Worker                 res = suite_name##_##bench_name##_inner_##params();             \
714*344aa361SAndroid Build Coastguard Worker                 end_time = get_current_time_ns();                               \
715*344aa361SAndroid Build Coastguard Worker                 PMU_STOP();                                                     \
716*344aa361SAndroid Build Coastguard Worker                                                                                 \
717*344aa361SAndroid Build Coastguard Worker                 bench_state.last_bench_body_duration = end_time - start_time;   \
718*344aa361SAndroid Build Coastguard Worker                 if (overhead >= bench_state.last_bench_body_duration) {         \
719*344aa361SAndroid Build Coastguard Worker                     TLOGE("Benchmark internal function is too fast %" PRId64    \
720*344aa361SAndroid Build Coastguard Worker                           "ns, while the benchmark overhead is %" PRId64        \
721*344aa361SAndroid Build Coastguard Worker                           "ns.",                                                \
722*344aa361SAndroid Build Coastguard Worker                           overhead, bench_state.last_bench_body_duration);      \
723*344aa361SAndroid Build Coastguard Worker                 }                                                               \
724*344aa361SAndroid Build Coastguard Worker                                                                                 \
725*344aa361SAndroid Build Coastguard Worker                 bench_state.last_bench_body_duration -= overhead;               \
726*344aa361SAndroid Build Coastguard Worker                 if (res != NO_ERROR) {                                          \
727*344aa361SAndroid Build Coastguard Worker                     TLOGE("ERROR %" PRId64 "\n", res);                          \
728*344aa361SAndroid Build Coastguard Worker                 }                                                               \
729*344aa361SAndroid Build Coastguard Worker             }                                                                   \
730*344aa361SAndroid Build Coastguard Worker             if (!_test_context.hard_fail && _test_context.all_ok) {             \
731*344aa361SAndroid Build Coastguard Worker                 trusty_bench_run_metrics(&metric_list, idx_param, false);       \
732*344aa361SAndroid Build Coastguard Worker                 RESET_PMU();                                                    \
733*344aa361SAndroid Build Coastguard Worker             }                                                                   \
734*344aa361SAndroid Build Coastguard Worker         }                                                                       \
735*344aa361SAndroid Build Coastguard Worker         suite_name##_teardown();                                                \
736*344aa361SAndroid Build Coastguard Worker         rc = trusty_bench_multi_cpus_teardown();                                \
737*344aa361SAndroid Build Coastguard Worker         if (rc != NO_ERROR) {                                                   \
738*344aa361SAndroid Build Coastguard Worker             TLOGW("failed to reset CPU affinity: %d\n", rc);                    \
739*344aa361SAndroid Build Coastguard Worker         }                                                                       \
740*344aa361SAndroid Build Coastguard Worker                                                                                 \
741*344aa361SAndroid Build Coastguard Worker         if (!trusty_bench_check_metrics(&metric_list, idx_param)) {             \
742*344aa361SAndroid Build Coastguard Worker             _test_context.all_ok = false;                                       \
743*344aa361SAndroid Build Coastguard Worker             _test_context.tests_failed++;                                       \
744*344aa361SAndroid Build Coastguard Worker         }                                                                       \
745*344aa361SAndroid Build Coastguard Worker         TEST_END_FUNC();                                                        \
746*344aa361SAndroid Build Coastguard Worker         free(extended_test_name);                                               \
747*344aa361SAndroid Build Coastguard Worker         extended_test_name = NULL;                                              \
748*344aa361SAndroid Build Coastguard Worker     }                                                                           \
749*344aa361SAndroid Build Coastguard Worker     trusty_bench_print_cb(&metric_list, (nb_params * trusty_bench_nb_cpu),      \
750*344aa361SAndroid Build Coastguard Worker                           STRINGIFY(suite_name),                                \
751*344aa361SAndroid Build Coastguard Worker                           STRINGIFY(bench_name##_##params));                    \
752*344aa361SAndroid Build Coastguard Worker     trusty_bench_get_param_name_cb = NULL;                                      \
753*344aa361SAndroid Build Coastguard Worker     trusty_bench_get_formatted_value_cb = NULL;                                 \
754*344aa361SAndroid Build Coastguard Worker     CLEAN_PMU();
755*344aa361SAndroid Build Coastguard Worker 
756*344aa361SAndroid Build Coastguard Worker /**
757*344aa361SAndroid Build Coastguard Worker  * BENCH_PARAMETERIZED_PTR -Called when BENCH has 5 parameters. This allows
758*344aa361SAndroid Build Coastguard Worker  *                          to reuse Other macros for different bench by
759*344aa361SAndroid Build Coastguard Worker  * aliasing an array to a pointer
760*344aa361SAndroid Build Coastguard Worker  * @suite_name:             Identifier of the current suite.
761*344aa361SAndroid Build Coastguard Worker  * @bench_name:             Unique identifier of the Bench in the suite.
762*344aa361SAndroid Build Coastguard Worker  * @nb_runs:                The number of execution of its body for each param
763*344aa361SAndroid Build Coastguard Worker  * @params:                 An array T array_name[nb_params] of parameter
764*344aa361SAndroid Build Coastguard Worker  * @nb_params:              Number of parameters in the parameter Array
765*344aa361SAndroid Build Coastguard Worker  */
766*344aa361SAndroid Build Coastguard Worker #define BENCH_PARAMETERIZED_PTR(nb_cpu, suite_name, bench_name, nb_runs,         \
767*344aa361SAndroid Build Coastguard Worker                                 params, nb_params)                               \
768*344aa361SAndroid Build Coastguard Worker     static int suite_name##_##bench_name##_inner_##params(void);                 \
769*344aa361SAndroid Build Coastguard Worker     static void suite_name##_##bench_name##_bench_##params(void);                \
770*344aa361SAndroid Build Coastguard Worker     static struct list_node suite_name##_##bench_name##_metric_list =            \
771*344aa361SAndroid Build Coastguard Worker             LIST_INITIAL_VALUE(suite_name##_##bench_name##_metric_list);         \
772*344aa361SAndroid Build Coastguard Worker     static struct list_node suite_name##_##bench_name##_metric_##params##_list = \
773*344aa361SAndroid Build Coastguard Worker             LIST_INITIAL_VALUE(                                                  \
774*344aa361SAndroid Build Coastguard Worker                     suite_name##_##bench_name##_metric_##params##_list);         \
775*344aa361SAndroid Build Coastguard Worker                                                                                  \
776*344aa361SAndroid Build Coastguard Worker     static void suite_name##_##bench_name##_bench_##params(void) {               \
777*344aa361SAndroid Build Coastguard Worker         trusty_bench_nb_cpu = nb_cpu;                                            \
778*344aa361SAndroid Build Coastguard Worker         struct bench_metric_list_node* metric_pool = set_param_metric(           \
779*344aa361SAndroid Build Coastguard Worker                 &suite_name##_##bench_name##_metric_list,                        \
780*344aa361SAndroid Build Coastguard Worker                 &suite_name##_##bench_name##_metric_##params##_list,             \
781*344aa361SAndroid Build Coastguard Worker                 (nb_params * trusty_bench_nb_cpu));                              \
782*344aa361SAndroid Build Coastguard Worker         if (metric_pool == NULL) {                                               \
783*344aa361SAndroid Build Coastguard Worker             _test_context.hard_fail = true;                                      \
784*344aa361SAndroid Build Coastguard Worker             return;                                                              \
785*344aa361SAndroid Build Coastguard Worker         }                                                                        \
786*344aa361SAndroid Build Coastguard Worker         BENCH_CORE(suite_name, bench_name, nb_runs, nb_params, params,           \
787*344aa361SAndroid Build Coastguard Worker                    suite_name##_##bench_name##_metric_##params##_list);          \
788*344aa361SAndroid Build Coastguard Worker         free(metric_pool);                                                       \
789*344aa361SAndroid Build Coastguard Worker     }                                                                            \
790*344aa361SAndroid Build Coastguard Worker     PARAM_TEST_NODES(suite_name, bench_name, params)                             \
791*344aa361SAndroid Build Coastguard Worker                                                                                  \
792*344aa361SAndroid Build Coastguard Worker     static int suite_name##_##bench_name##_inner_##params(void)
793*344aa361SAndroid Build Coastguard Worker 
794*344aa361SAndroid Build Coastguard Worker /**
795*344aa361SAndroid Build Coastguard Worker  * BENCH_PARAMETERIZED -    Called when BENCH has 4 parameters
796*344aa361SAndroid Build Coastguard Worker  * @suite_name:             Identifier of the current suite.
797*344aa361SAndroid Build Coastguard Worker  * @bench_name:             Unique identifier of the Bench in the suite.
798*344aa361SAndroid Build Coastguard Worker  * @nb_runs:                The number of execution of its body for each param
799*344aa361SAndroid Build Coastguard Worker  * @params:                 An array T array_name[nb_params] of parameter
800*344aa361SAndroid Build Coastguard Worker  */
801*344aa361SAndroid Build Coastguard Worker #define BENCH_PARAMETERIZED(nb_cpu, suite_name, bench_name, nb_runs, params) \
802*344aa361SAndroid Build Coastguard Worker     BENCH_PARAMETERIZED_PTR(nb_cpu, suite_name, bench_name, nb_runs, params, \
803*344aa361SAndroid Build Coastguard Worker                             countof(params))
804*344aa361SAndroid Build Coastguard Worker 
805*344aa361SAndroid Build Coastguard Worker /**
806*344aa361SAndroid Build Coastguard Worker  * BENCH_SIMPLE -       Called when BENCH has only 3 parameters.
807*344aa361SAndroid Build Coastguard Worker  * @suite_name:         Identifier of the current suite.
808*344aa361SAndroid Build Coastguard Worker  * @bench_name:         Unique identifier of the Bench in the suite.
809*344aa361SAndroid Build Coastguard Worker  * @nb_runs:            The number of execution of its body.
810*344aa361SAndroid Build Coastguard Worker  */
811*344aa361SAndroid Build Coastguard Worker #define BENCH_SIMPLE(nb_cpu, suite_name, bench_name, nb_runs)                  \
812*344aa361SAndroid Build Coastguard Worker     static int suite_name##_##bench_name##_inner_(void);                       \
813*344aa361SAndroid Build Coastguard Worker     static void suite_name##_##bench_name##_bench_(void);                      \
814*344aa361SAndroid Build Coastguard Worker     static struct list_node suite_name##_##bench_name##_metric_list =          \
815*344aa361SAndroid Build Coastguard Worker             LIST_INITIAL_VALUE(suite_name##_##bench_name##_metric_list);       \
816*344aa361SAndroid Build Coastguard Worker     static struct list_node suite_name##_##bench_name##_metric_cpu##_list =    \
817*344aa361SAndroid Build Coastguard Worker             LIST_INITIAL_VALUE(suite_name##_##bench_name##_metric_cpu##_list); \
818*344aa361SAndroid Build Coastguard Worker     static void suite_name##_##bench_name##_bench_(void) {                     \
819*344aa361SAndroid Build Coastguard Worker         bench_state.cur_param_idx = 0;                                         \
820*344aa361SAndroid Build Coastguard Worker         trusty_bench_nb_cpu = nb_cpu;                                          \
821*344aa361SAndroid Build Coastguard Worker         struct bench_metric_list_node* metric_pool = set_param_metric(         \
822*344aa361SAndroid Build Coastguard Worker                 &suite_name##_##bench_name##_metric_list,                      \
823*344aa361SAndroid Build Coastguard Worker                 &suite_name##_##bench_name##_metric_cpu##_list,                \
824*344aa361SAndroid Build Coastguard Worker                 trusty_bench_nb_cpu);                                          \
825*344aa361SAndroid Build Coastguard Worker         if (metric_pool == NULL) {                                             \
826*344aa361SAndroid Build Coastguard Worker             _test_context.hard_fail = true;                                    \
827*344aa361SAndroid Build Coastguard Worker             return;                                                            \
828*344aa361SAndroid Build Coastguard Worker         }                                                                      \
829*344aa361SAndroid Build Coastguard Worker         BENCH_CORE(suite_name, bench_name, nb_runs, 1, ,                       \
830*344aa361SAndroid Build Coastguard Worker                    suite_name##_##bench_name##_metric_cpu##_list);             \
831*344aa361SAndroid Build Coastguard Worker     }                                                                          \
832*344aa361SAndroid Build Coastguard Worker                                                                                \
833*344aa361SAndroid Build Coastguard Worker     PARAM_TEST_NODES(suite_name, bench_name)                                   \
834*344aa361SAndroid Build Coastguard Worker     static int suite_name##_##bench_name##_inner_(void)
835*344aa361SAndroid Build Coastguard Worker 
836*344aa361SAndroid Build Coastguard Worker /*
837*344aa361SAndroid Build Coastguard Worker  * BENCH - Routing the BENCH macros depending on its number of parameters.
838*344aa361SAndroid Build Coastguard Worker  */
839*344aa361SAndroid Build Coastguard Worker #define BENCH_3 BENCH_SIMPLE
840*344aa361SAndroid Build Coastguard Worker #define BENCH_4 BENCH_PARAMETERIZED
841*344aa361SAndroid Build Coastguard Worker #define BENCH_5 BENCH_PARAMETERIZED_PTR
842*344aa361SAndroid Build Coastguard Worker 
843*344aa361SAndroid Build Coastguard Worker /**
844*344aa361SAndroid Build Coastguard Worker  * BENCH - Called 3, 4 or 5 parameters. This allows
845*344aa361SAndroid Build Coastguard Worker  *                          to reuse Other macros for different bench by
846*344aa361SAndroid Build Coastguard Worker  * aliasing an array to a pointer
847*344aa361SAndroid Build Coastguard Worker  * @suite_name:             Identifier of the current suite.
848*344aa361SAndroid Build Coastguard Worker  * @bench_name:             Unique identifier of the Bench in the suite.
849*344aa361SAndroid Build Coastguard Worker  * @nb_runs:                The number of execution of its body for each param
850*344aa361SAndroid Build Coastguard Worker  * @params:                 [optional] An array T array_name[nb_params] of
851*344aa361SAndroid Build Coastguard Worker  *                          parameter, or a pointer T*, in the latter case a 5th
852*344aa361SAndroid Build Coastguard Worker  *                          parameter is needed
853*344aa361SAndroid Build Coastguard Worker  * @nb_params:              [optional] if 4th parameter is a pointer, Number of
854*344aa361SAndroid Build Coastguard Worker  *                          parameters in the parameter Array
855*344aa361SAndroid Build Coastguard Worker  */
856*344aa361SAndroid Build Coastguard Worker #define BENCH(...) CAT(BENCH_, EVAL(NB_ARGS(__VA_ARGS__)))(1, __VA_ARGS__)
857*344aa361SAndroid Build Coastguard Worker 
858*344aa361SAndroid Build Coastguard Worker /**
859*344aa361SAndroid Build Coastguard Worker  * BENCH_ALL_CPU - Called 3, 4 or 5 parameters. This allows
860*344aa361SAndroid Build Coastguard Worker  *                          to reuse Other macros for different bench by
861*344aa361SAndroid Build Coastguard Worker  * aliasing an array to a pointer
862*344aa361SAndroid Build Coastguard Worker  * @suite_name:             Identifier of the current suite.
863*344aa361SAndroid Build Coastguard Worker  * @bench_name:             Unique identifier of the Bench in the suite.
864*344aa361SAndroid Build Coastguard Worker  * @nb_runs:                The number of execution of its body for each param
865*344aa361SAndroid Build Coastguard Worker  * @params:                 [optional] An array T array_name[nb_params] of
866*344aa361SAndroid Build Coastguard Worker  *                          parameter, or a pointer T*, in the latter case a 5th
867*344aa361SAndroid Build Coastguard Worker  *                          parameter is needed
868*344aa361SAndroid Build Coastguard Worker  * @nb_params:              [optional] if 4th parameter is a pointer, Number of
869*344aa361SAndroid Build Coastguard Worker  *                          parameters in the parameter Array
870*344aa361SAndroid Build Coastguard Worker  */
871*344aa361SAndroid Build Coastguard Worker #define BENCH_ALL_CPU(...) \
872*344aa361SAndroid Build Coastguard Worker     CAT(BENCH_, EVAL(NB_ARGS(__VA_ARGS__)))(SMP_MAX_CPUS, __VA_ARGS__)
873*344aa361SAndroid Build Coastguard Worker 
874*344aa361SAndroid Build Coastguard Worker /*
875*344aa361SAndroid Build Coastguard Worker  * PARAM_TEST_NODES - Routing the PARAM_TEST_NODES macros depending on its
876*344aa361SAndroid Build Coastguard Worker  * number of parameters.
877*344aa361SAndroid Build Coastguard Worker  */
878*344aa361SAndroid Build Coastguard Worker #define PARAM_TEST_NODES_2 PARAM_TEST_NODES_SIMPLE
879*344aa361SAndroid Build Coastguard Worker #define PARAM_TEST_NODES_3 PARAM_TEST_NODES_PARAMETRIC
880*344aa361SAndroid Build Coastguard Worker #define PARAM_TEST_NODES(...) \
881*344aa361SAndroid Build Coastguard Worker     CAT(PARAM_TEST_NODES_, EVAL(NB_ARGS(__VA_ARGS__)))(__VA_ARGS__)
882*344aa361SAndroid Build Coastguard Worker 
883*344aa361SAndroid Build Coastguard Worker __END_CDECLS
884