* Josh Stone ([email protected]) wrote:
> On 04/11/2011 02:19 PM, Josh Stone wrote:
> > AFAIK, the only roadblock is that our probes are argument-numbered
> > rather than variadic.  I've been thinking for a while that it would be
> > nice if we had a variadic SDT macro, e.g. STAP_PROBEV, and then UST
> > could invoke it directly.  Since you and I were brainstorming this,
> > here's a neat trick I found to count __VA_ARGS__:
> >   http://groups.google.com/group/comp.std.c/msg/346fc464319b1ee5
> > 
> > I'm going to try to adapt that for SDT, so I'll post if I get it working...
> 
> Here's what I came up with:
> 
> #define _SDT_NARG(...) __SDT_NARG(__VA_ARGS__, 10,9,8,7,6,5,4,3,2,1,0)
> #define __SDT_NARG(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10, N, ...) N
> #define _SDT_PROBE_N(provider, name, N, ...) \
>   _SDT_PROBE(provider, name, N, (__VA_ARGS__))
> #define STAP_PROBEV(provider, name, ...) \
>   _SDT_PROBE_N(provider, name, _SDT_NARG(0,##__VA_ARGS__),##__VA_ARGS__)
> 
> _SDT_NARG is actually returning the count minus one, and I call it with
> an extra arg, so we can avoid non-standard empty macro args.
> 
> Comments?

Cool! I tweaked it a bit and came up with the following. Comments ?


#include <stdio.h>

#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
#define BUILD_BUG_ON(condition) ((void)BUILD_BUG_ON_ZERO(condition))

#define __compiler_offsetof(a,b) __builtin_offsetof(a,b)

#undef offsetof
#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif

#define __stringify_1(x...)     #x
#define __stringify(x...)       __stringify_1(x)

/* for x86 64 */
#define _ASM_PTR ".quad "

#define _A0()
#define _A1(first)                                      \
        "g" (first)
#define _A2(first, args...)                             \
        "g" (first), _A1(args)
#define _A3(first, args...)                             \
        "g" (first), _A2(args)
#define _A4(first, args...)                             \
        "g" (first), _A3(args)
#define _A5(first, args...)                             \
        "g" (first), _A4(args)
#define _A6(first, args...)                             \
        "g" (first), _A5(args)
#define _A7(first, args...)                             \
        "g" (first), _A6(args)
#define _A8(first, args...)                             \
        "g" (first), _A7(args)
#define _A9(first, args...)                             \
        "g" (first), _A8(args)
#define _A10(first, args...)                            \
        "g" (first), _A9(args)

#define ___TP_NARGS(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10, N, args...) N
#define __TP_NARGS(args...)                             \
        ___TP_NARGS(args, 10,9,8,7,6,5,4,3,2,1,0)
/* Handle empty args with added 0. */
#define _TP_NARGS(args...)                              \
        __TP_NARGS(0,##args)

/* Create a section with IP and tracepoint name */
#define _TRACEPOINT_ENTRY(name)                         \
        ".section __tracepoint_strings\"aw\"\n\t"       \
        "0:\n\t"                                        \
        ".string \"" __stringify(name) "\"\n\t"         \
        ".previous\n\t"                                 \
        ".section __tracepoint_ip\"aw\"\n\t"            \
        _ASM_PTR "(0b)\n\t"                             \
        _ASM_PTR "(1f)\n\t"                             \
        ".previous\n\t"                                 \
        "1:\n\t"

/* Create macro name by pasting the result of macro evaluation */
#define __tp_sym(_a, _b)        _a##_b
#define _tp_sym(_a, _b)         __tp_sym(_a, _b)

#define tracepoint(name, args...)                       \
do {                                                    \
        asm volatile (_TRACEPOINT_ENTRY(name) : : _tp_sym(_A, 
_TP_NARGS(args))(args) : "memory");       \
        BUILD_BUG_ON(_TP_NARGS(args) > 10);             \
} while (0)

int main(int argc, char **argv)
{
        int one, two, three, four;
        unsigned long long five, six, seven, eight, nine, ten, eleven;

        //trace(name, one, two, three, four, five);
        //trace(name, one, two, three);
        tracepoint(namet1);
        tracepoint(namet2, one);
        tracepoint(namet3, one, two);
        tracepoint(namet3, one, two, three, four, five);
        tracepoint(namet3, one, two, three, four, five,
                   six, seven, eight, &nine, ten);
        //tracepoint(namet3, one, two, three, four, five,
        //         six, seven, eight, &nine, ten, eleven);

        // error trace(name, one, two, three, four, five, six);
        // error trace(name, one, two, three, four, noexist);

        return 0;
}



-- 
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com

_______________________________________________
ltt-dev mailing list
[email protected]
http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev

Reply via email to