Skip to content

Commit b284ac3

Browse files
committed
debugability: Macro Metaprogramming Refactor
Added macro functions to make repetitive, nearly identical functions more maintainable via metaprogramming. They generate code in pre-compile, conceptually similar to C++17 if-constexpr. sof/trace, host/trace: rewrote _trace_event/d+ functions using preproc.h. test/cmocka/include/test_group_generator: rewrote macros to not conflict with new ones. Added unit tests to check whether more advanced and less obvious macros do in fact work. Signed-off-by: Michal Jerzy Wierzbicki <michalx.wierzbicki@linux.intel.com>
1 parent 1024e94 commit b284ac3

17 files changed

Lines changed: 1680 additions & 825 deletions

File tree

src/host/trace.c

Lines changed: 69 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
* Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
3232
*/
3333

34+
#include <sof/preproc.h>
3435
#include <stdint.h>
3536
#include <stdio.h>
3637
#include <string.h>
@@ -142,134 +143,84 @@ static char *get_trace_class(uint32_t trace_class)
142143
return "value";
143144
}
144145

145-
/* print trace event */
146-
void _trace_event0(uint32_t event)
147-
{
148-
char a, b, c;
149-
char *trace_class = NULL;
150-
151-
if (test_bench_trace > 0) {
152-
a = event & 0xff;
153-
b = (event >> 8) & 0xff;
154-
c = (event >> 16) & 0xff;
146+
#define META_SEQ_STEP_param_procD(i, _) META_CONCAT(param, i) %d
155147

156-
/* look up subsystem from trace class table */
157-
trace_class = strdup(get_trace_class(event >> 24));
158-
159-
/* print trace event stderr*/
160-
if (strcmp(trace_class, "value") == 0)
161-
fprintf(stderr, "Trace value %d\n", event);
162-
else
163-
fprintf(stderr, "Trace %s %c%c%c\n", trace_class,
164-
c, b, a);
165-
}
166-
167-
free(trace_class);
168-
}
169-
170-
void _trace_event_mbox_atomic0(uint32_t event)
171-
{
172-
_trace_event0(event);
173-
}
148+
#define HOST_TRACE_EVENT_NTH(postfix, vararg_count)\
149+
META_FUNC_WITH_VARARGS(_trace_event, postfix, void,\
150+
META_CONCAT(, uint32_t event),\
151+
vararg_count, META_SEQ_STEP_param_uint32_t)
174152

175153
/* print trace event */
176-
void _trace_event1(uint32_t event, uint32_t param)
177-
{
178-
char a, b, c;
179-
char *trace_class = NULL;
180-
181-
if (test_bench_trace > 0) {
182-
a = event & 0xff;
183-
b = (event >> 8) & 0xff;
184-
c = (event >> 16) & 0xff;
185-
186-
/* look up subsystem from trace class table */
187-
trace_class = strdup(get_trace_class(event >> 24));
188-
189-
/* print trace event stderr*/
190-
if (strcmp(trace_class, "value") == 0)
191-
fprintf(stderr, "Trace value %d, param1 %d\n", event,
192-
param);
193-
else
194-
fprintf(stderr, "Trace %s %c%c%c\n", trace_class,
195-
c, b, a);
196-
}
197-
198-
free(trace_class);
154+
#define HOST_TRACE_EVENT_NTH_IMPL(arg_count)\
155+
HOST_TRACE_EVENT_NTH(, arg_count)\
156+
{\
157+
char a, b, c;\
158+
\
159+
if (test_bench_trace > 0) {\
160+
/* look up subsystem from trace class table */\
161+
char *trace_class = strdup(get_trace_class(event >> 24));\
162+
\
163+
a = event & 0xff;\
164+
b = (event >> 8) & 0xff;\
165+
c = (event >> 16) & 0xff;\
166+
\
167+
/* print trace event stderr*/\
168+
if (!strcmp(trace_class, "value"))\
169+
fprintf(stderr,\
170+
"Trace value %d, "META_QUOTE(\
171+
META_SEQ_FROM_0_TO(\
172+
arg_count, META_SEQ_STEP_param_procD\
173+
))"\n"\
174+
, event META_SEQ_FROM_0_TO(arg_count, META_SEQ_STEP_param));\
175+
else\
176+
fprintf(stderr,\
177+
"Trace %s %c%c%c\n"\
178+
, trace_class, c, b, a);\
179+
if (trace_class)\
180+
free(trace_class);\
181+
}\
182+
}\
183+
HOST_TRACE_EVENT_NTH(_mbox_atomic, arg_count)\
184+
{\
185+
META_CONCAT(_trace_event, arg_count)\
186+
(event META_SEQ_FROM_0_TO(arg_count,META_SEQ_STEP_param));\
199187
}
200188

201-
void _trace_event_mbox_atomic1(uint32_t event, uint32_t param)
202-
{
203-
_trace_event1(event, param);
204-
}
205-
206-
/* print trace event */
207-
void _trace_event2(uint32_t event, uint32_t param1, uint32_t param2)
208-
{
209-
char a, b, c;
210-
char *trace_class = NULL;
211-
212-
if (test_bench_trace > 0) {
213-
a = event & 0xff;
214-
b = (event >> 8) & 0xff;
215-
c = (event >> 16) & 0xff;
216-
217-
/* look up subsystem from trace class table */
218-
trace_class = strdup(get_trace_class(event >> 24));
219-
220-
/* print trace event stderr*/
221-
if (strcmp(trace_class, "value") == 0)
222-
fprintf(stderr,
223-
"Trace value %d, param1 %d param2 %d\n",
224-
event, param1, param2);
225-
else
226-
fprintf(stderr, "Trace %s %c%c%c\n", trace_class,
227-
c, b, a);
228-
}
229-
230-
free(trace_class);
231-
}
232-
233-
void _trace_event_mbox_atomic2(uint32_t event, uint32_t param1,
234-
uint32_t param2)
235-
{
236-
_trace_event2(event, param1, param2);
237-
}
238-
239-
/* print trace event */
240-
void _trace_event3(uint32_t event, uint32_t param1, uint32_t param2,
241-
uint32_t param3)
242-
{
243-
char a, b, c;
244-
char *trace_class = NULL;
189+
/* Implementation of
190+
* void _trace_event0( uint32_t log_entry, uint32_t params...) {...}
191+
* void _trace_event_mbox_atomic0(uint32_t log_entry, uint32_t params...) {...}
192+
*/
193+
HOST_TRACE_EVENT_NTH_IMPL(0);
245194

246-
if (test_bench_trace > 0) {
247-
a = event & 0xff;
248-
b = (event >> 8) & 0xff;
249-
c = (event >> 16) & 0xff;
195+
/* Implementation of
196+
* void _trace_event1( uint32_t log_entry, uint32_t params...) {...}
197+
* void _trace_event_mbox_atomic1(uint32_t log_entry, uint32_t params...) {...}
198+
*/
199+
HOST_TRACE_EVENT_NTH_IMPL(1);
250200

251-
/* look up subsystem from trace class table */
252-
trace_class = strdup(get_trace_class(event >> 24));
201+
/* Implementation of
202+
* void _trace_event2( uint32_t log_entry, uint32_t params...) {...}
203+
* void _trace_event_mbox_atomic2(uint32_t log_entry, uint32_t params...) {...}
204+
*/
205+
HOST_TRACE_EVENT_NTH_IMPL(2);
253206

254-
/* print trace event stderr*/
255-
if (strcmp(trace_class, "value") == 0)
256-
fprintf
257-
(stderr,
258-
"Trace value %d, param1 %d param2 %d param3 %d\n",
259-
event, param1, param2, param3);
260-
else
261-
fprintf(stderr, "Trace %s %c%c%c\n", trace_class,
262-
c, b, a);
263-
}
207+
/* Implementation of
208+
* void _trace_event3( uint32_t log_entry, uint32_t params...) {...}
209+
* void _trace_event_mbox_atomic3(uint32_t log_entry, uint32_t params...) {...}
210+
*/
211+
HOST_TRACE_EVENT_NTH_IMPL(3);
264212

265-
free(trace_class);
266-
}
213+
/* Implementation of
214+
* void _trace_event4( uint32_t log_entry, uint32_t params...) {...}
215+
* void _trace_event_mbox_atomic4(uint32_t log_entry, uint32_t params...) {...}
216+
*/
217+
HOST_TRACE_EVENT_NTH_IMPL(4);
267218

268-
void _trace_event_mbox_atomic3(uint32_t event, uint32_t param1,
269-
uint32_t param2, uint32_t param3)
270-
{
271-
_trace_event3(event, param1, param2, param3);
272-
}
219+
/* Implementation of
220+
* void _trace_event5( uint32_t log_entry, uint32_t params...) {...}
221+
* void _trace_event_mbox_atomic5(uint32_t log_entry, uint32_t params...) {...}
222+
*/
223+
HOST_TRACE_EVENT_NTH_IMPL(5);
273224

274225
/* enable trace in testbench */
275226
void tb_enable_trace(bool enable)
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*
2+
* Copyright (c) 2016, Intel Corporation
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
* * Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* * Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
* * Neither the name of the Intel Corporation nor the
13+
* names of its contributors may be used to endorse or promote products
14+
* derived from this software without specific prior written permission.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
*
28+
* Author: Michal Jerzy Wierzbicki <michalx.wierzbicki@intel.com>
29+
*/
30+
31+
/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY */
32+
33+
#ifdef __INCLUDE_MACRO_METAPROGRAMMING_PRIVATE__
34+
/* Macros defined in this file are only helpers for the macros that are
35+
* defined in header file containing "namespace"
36+
* __INCLUDE_MACRO_METAPROGRAMMING_PRIVATE__ .
37+
* This combination of #ifdef and #ifndef should sufficently narrow
38+
* the "include-ability" of this dependent header file.
39+
* If you wish to use macros from this file directly, be *V E R Y* careful!
40+
* HIC SUNT DRACONES
41+
*/
42+
#ifndef __INCLUDE_MACRO_METAPROGRAMMING_PRIVATE_DEC__
43+
#define __INCLUDE_MACRO_METAPROGRAMMING_PRIVATE_DEC__
44+
45+
/* The only sane way I found to decrement values in cpreproc */
46+
/* for instance META_DEC(3) will be tokenized to DEC_3
47+
* and then expanded again to 2
48+
*/
49+
#define _META_DEC_0 0 // notice how we deal with underflow
50+
#define _META_DEC_1 0
51+
#define _META_DEC_2 1
52+
#define _META_DEC_3 2
53+
#define _META_DEC_4 3
54+
#define _META_DEC_5 4
55+
#define _META_DEC_6 5
56+
#define _META_DEC_7 6
57+
#define _META_DEC_8 7
58+
#define _META_DEC_9 8
59+
#define _META_DEC_10 9
60+
#define _META_DEC_11 10
61+
#define _META_DEC_12 11
62+
#define _META_DEC_13 12
63+
#define _META_DEC_14 13
64+
#define _META_DEC_15 14
65+
#define _META_DEC_16 15
66+
#define _META_DEC_17 16
67+
#define _META_DEC_18 17
68+
#define _META_DEC_19 18
69+
#define _META_DEC_20 19
70+
#define _META_DEC_21 20
71+
#define _META_DEC_22 21
72+
#define _META_DEC_23 22
73+
#define _META_DEC_24 23
74+
#define _META_DEC_25 24
75+
#define _META_DEC_26 25
76+
#define _META_DEC_27 26
77+
#define _META_DEC_28 27
78+
#define _META_DEC_29 28
79+
#define _META_DEC_30 29
80+
#define _META_DEC_31 30
81+
#define _META_DEC_32 31
82+
#define _META_DEC_33 32
83+
#define _META_DEC_34 33
84+
#define _META_DEC_35 34
85+
#define _META_DEC_36 35
86+
#define _META_DEC_37 36
87+
#define _META_DEC_38 37
88+
#define _META_DEC_39 38
89+
#define _META_DEC_40 39
90+
#define _META_DEC_41 40
91+
#define _META_DEC_42 41
92+
#define _META_DEC_43 42
93+
#define _META_DEC_44 43
94+
#define _META_DEC_45 44
95+
#define _META_DEC_46 45
96+
#define _META_DEC_47 46
97+
#define _META_DEC_48 47
98+
#define _META_DEC_49 48
99+
#define _META_DEC_50 49
100+
#define _META_DEC_51 50
101+
#define _META_DEC_52 51
102+
#define _META_DEC_53 52
103+
#define _META_DEC_54 53
104+
#define _META_DEC_55 54
105+
#define _META_DEC_56 55
106+
#define _META_DEC_57 56
107+
#define _META_DEC_58 57
108+
#define _META_DEC_59 58
109+
#define _META_DEC_60 59
110+
#define _META_DEC_61 60
111+
#define _META_DEC_62 61
112+
#define _META_DEC_63 62
113+
#define _META_DEC_64 63
114+
115+
#endif // __INCLUDE_MACRO_METAPROGRAMMING_PRIVATE_DEC__
116+
#else
117+
#error \
118+
Illegal use of header file: \
119+
can only be included from context of \
120+
__INCLUDE_MACRO_METAPROGRAMMING_PRIVATE__
121+
#endif // __INCLUDE_MACRO_METAPROGRAMMING_PRIVATE__

0 commit comments

Comments
 (0)