[PATCH 2/2] perf tools: Make Power7 events available for perf

David Laight David.Laight at ACULAB.COM
Thu Jun 20 20:57:15 EST 2013


> I think we should be able to do something better using the C
> preprocessor, this is exactly the sort of thing it's good at.
> 
> What I mean is something like we do with arch/powerpc/include/asm/systbl.h,
> where we define the list of syscalls once, and then include it in
> multiple places, using different macro definitions to get different
> outputs.

There is a 'neat' trick - you can pass a #define macro the
name of another #define - which is then expanded after the
initial expansion. A description I happen to have is pasted below.

	David

Consider what happens when #define foo(x) x(args) is expanded: foo(bar)
clearly becomes bar(args). If we also have #define bar(args) then bar()
is expanded AFTER foo() allowing us to generate any text including args.
So we have passed the name of one #define as a parameter to a different #define.

If we replace the definition of foo with
#define foo(x) x(args1) x(args2) then foo(bar) is equivalent to
bar(args1) bar(args2).
This is useful because foo(baz) expands to baz(args1) baz(args2)
allowing us to feed the same set of arguments to more than one #define.

A simple example:
	#define lights(x) x(red) x(orange) x(green)
	#define xx(colour) LIGHT_##colour,
	enum { lights(xx) NUM_LIGHTS };
	#undef xx
	#define xx(colour) #colour,
	static const char light_names[] = { lights(xx) };
	#undef xx

This expands to:
	enum { LIGHT_red, LIGHT_orange, LIGHT_green, NUM_LIGHTS };
	static const char light_names[] = { ”red”, ”orange”, ”green”, };
(We needed to add NUM_LIGHTS because a trailing comma isn’t valid in a C++ enum.)




More information about the Linuxppc-dev mailing list