summaryrefslogtreecommitdiff
path: root/src/util/virprobe.h
blob: 80a5f48ec8b9ee23d840b8833966ff0f46b7d8b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
 * virprobe.h: dynamic operation tracing
 *
 * Copyright (C) 2006-2014 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 */

#pragma once

#include "internal.h"
#include "virlog.h"

#if WITH_DTRACE_PROBES
# ifndef LIBVIRT_PROBES_H
#  define LIBVIRT_PROBES_H
#  include "libvirt_probes.h"
# endif /* LIBVIRT_PROBES_H */

/* Systemtap 1.2 headers have a bug where they cannot handle a
 * variable declared with array type.  Work around this by casting all
 * arguments.  This is some gross use of the preprocessor because
 * PROBE is a var-arg macro, but it is better than the alternative of
 * making all callers to PROBE have to be aware of the issues.  And
 * hopefully, if we ever add a call to PROBE with other than 9
 * end arguments, you can figure out the pattern to extend this hack.
 */
# define VIR_COUNT_ARGS(...) VIR_ARG11(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
# define VIR_ARG11(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, ...) _11
# define VIR_ADD_CAST_EXPAND(a, b, ...) VIR_ADD_CAST_PASTE(a, b, __VA_ARGS__)
# define VIR_ADD_CAST_PASTE(a, b, ...) a##b(__VA_ARGS__)

/* The double cast is necessary to silence gcc warnings; any pointer
 * can safely go to intptr_t and back to void *, which collapses
 * arrays into pointers; while any integer can be widened to intptr_t
 * then cast to void *.  */
# define VIR_ADD_CAST(a) ((void *)(intptr_t)(a))
# define VIR_ADD_CAST1(a) \
    VIR_ADD_CAST(a)
# define VIR_ADD_CAST2(a, b) \
    VIR_ADD_CAST(a), VIR_ADD_CAST(b)
# define VIR_ADD_CAST3(a, b, c) \
    VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c)
# define VIR_ADD_CAST4(a, b, c, d) \
    VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c), \
    VIR_ADD_CAST(d)
# define VIR_ADD_CAST5(a, b, c, d, e) \
    VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c), \
    VIR_ADD_CAST(d), VIR_ADD_CAST(e)
# define VIR_ADD_CAST6(a, b, c, d, e, f) \
    VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c), \
    VIR_ADD_CAST(d), VIR_ADD_CAST(e), VIR_ADD_CAST(f)
# define VIR_ADD_CAST7(a, b, c, d, e, f, g) \
    VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c), \
    VIR_ADD_CAST(d), VIR_ADD_CAST(e), VIR_ADD_CAST(f), \
    VIR_ADD_CAST(g)
# define VIR_ADD_CAST8(a, b, c, d, e, f, g, h) \
    VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c), \
    VIR_ADD_CAST(d), VIR_ADD_CAST(e), VIR_ADD_CAST(f), \
    VIR_ADD_CAST(g), VIR_ADD_CAST(h)
# define VIR_ADD_CAST9(a, b, c, d, e, f, g, h, i) \
    VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c), \
    VIR_ADD_CAST(d), VIR_ADD_CAST(e), VIR_ADD_CAST(f), \
    VIR_ADD_CAST(g), VIR_ADD_CAST(h), VIR_ADD_CAST(i)

# define VIR_ADD_CASTS(...) \
    VIR_ADD_CAST_EXPAND(VIR_ADD_CAST, VIR_COUNT_ARGS(__VA_ARGS__), \
                        __VA_ARGS__)

# define PROBE_EXPAND(NAME, ARGS) NAME(ARGS)
# define PROBE(NAME, FMT, ...) \
    VIR_INFO_INT(&virLogSelf, \
                  __FILE__, __LINE__, __func__, \
                  #NAME ": " FMT, __VA_ARGS__); \
    if (LIBVIRT_ ## NAME ## _ENABLED()) { \
        PROBE_EXPAND(LIBVIRT_ ## NAME, \
                     VIR_ADD_CASTS(__VA_ARGS__)); \
    }

# define PROBE_QUIET(NAME, FMT, ...) \
    if (LIBVIRT_ ## NAME ## _ENABLED()) { \
        PROBE_EXPAND(LIBVIRT_ ## NAME, \
                     VIR_ADD_CASTS(__VA_ARGS__)); \
    }
#else
# define PROBE(NAME, FMT, ...) \
    VIR_INFO_INT(&virLogSelf, \
                 __FILE__, __LINE__, __func__, \
                 #NAME ": " FMT, __VA_ARGS__);

# define PROBE_QUIET(NAME, FMT, ...)
#endif