~ubuntu-branches/ubuntu/wily/openvswitch/wily

« back to all changes in this revision

Viewing changes to lib/perf-counter.h

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2015-08-10 11:35:15 UTC
  • mfrom: (1.1.30)
  • Revision ID: package-import@ubuntu.com-20150810113515-575vj06oq29emxsn
Tags: 2.4.0~git20150810.97bab95-0ubuntu1
* New upstream snapshot from 2.4 branch:
  - d/*: Align any relevant packaging changes with upstream.
* d/*: wrap-and-sort.
* d/openvswitch-{common,vswitch}.install: Correct install location for
  bash completion files.
* d/tests/openflow.py: Explicitly use ovs-testcontroller as provided
  by 2.4.0 release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2015 Nicira, Inc.
 
3
 *
 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
 
5
 * you may not use this file except in compliance with the License.
 
6
 * You may obtain a copy of the License at:
 
7
 *
 
8
 *     http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
10
 * Unless required by applicable law or agreed to in writing, software
 
11
 * distributed under the License is distributed on an "AS IS" BASIS,
 
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
 * See the License for the specific language governing permissions and
 
14
 * limitations under the License.
 
15
 */
 
16
 
 
17
#ifndef __PERF_COUNTER_H
 
18
#define __PERF_COUNTER_H 1
 
19
 
 
20
/* Motivation
 
21
 * ==========
 
22
 *
 
23
 * It is sometimes desirable to gain performance insights of a program
 
24
 * by using hardware counters.  Recent Linux kernels started to support
 
25
 * a set of portable API for configuring and access those counter across
 
26
 * multiple platforms.
 
27
 *
 
28
 * APIs provided by perf-counter.h provides a set of APIs that are
 
29
 * semi-integrated into OVS user spaces. The infrastructure that initializes,
 
30
 * cleanup, display and clear them at run time is provided. However the
 
31
 * sample points are not. A programmer needs insert sample points when needed.
 
32
 *
 
33
 * Since there is no pre configured sample points, there is no run time
 
34
 * over head for the released product.
 
35
 *
 
36
 * Limitations
 
37
 * ===========
 
38
 * - Hard coded to sample CPU cycle count in user space only.
 
39
 * - Only one counter is sampled.
 
40
 * - Useful macros are only provided for function profiling.
 
41
 * - show and clear command applies to all counters, there is no way
 
42
 *   to select a sub-set of counter.
 
43
 *
 
44
 * Those are not fundamental limits, but only limited by current
 
45
 * implementation.
 
46
 *
 
47
 * Function instruction counter sample point Usage
 
48
 * ================================================
 
49
 *
 
50
 * There are two macros provided:
 
51
 *
 
52
 * Macro 'PERF_FUNCTON_COUNT_BEGIN' needs to be inserted towards the
 
53
 * beginning of the function where local variables are declared.
 
54
 *
 
55
 * Macro 'PERF_FUNCTON_COUNT_END' needs to appear in the same function,
 
56
 * some where below 'PERF_FUNCTION_COUNT_BEGIN', usually towards of
 
57
 * a function.
 
58
 *
 
59
 * For example:
 
60
 *
 
61
 *    void my_func() {
 
62
 *      int some_local_variable;
 
63
 *
 
64
 *      PERF_FUNCTION_COUNT_BEGIN;
 
65
 *
 
66
 *      < implementation >
 
67
 *
 
68
 *      PERF_FUNCTION_COUNT_END
 
69
 *    }
 
70
 *
 
71
 * This will maintain the number of times 'my_func()' is called, total
 
72
 * number of instructions '<implementation>' executed during all those calls.
 
73
 *
 
74
 * Currently there are two limitation:
 
75
 * 1). At most one pair can appear in the same variable scope.
 
76
 * 2). The Macros use function name as the counter name for display.
 
77
 *     Thus, all functions in one annotation session are required to
 
78
 *     have unique names.
 
79
 *
 
80
 * Note, there is no requirement for those macros to be balanced.
 
81
 * For example:
 
82
 *
 
83
 *    void my_func(int i){
 
84
 *
 
85
 *      PERF_FUNCTION_COUNT_BEGIN;
 
86
 *
 
87
 *      if (i == 300) {
 
88
 *          PERF_FUNCTION_COUNT_END;
 
89
 *          return;
 
90
 *      } else {
 
91
 *           <some code>
 
92
 *      }
 
93
 *    }
 
94
 * will work just fine.
 
95
 */
 
96
 
 
97
#if defined(__linux__) && defined(HAVE_LINUX_PERF_EVENT_H)
 
98
struct perf_counter {
 
99
    const char *name;
 
100
    bool once;
 
101
    uint64_t n_events;
 
102
    uint64_t total_count;
 
103
};
 
104
 
 
105
#define PERF_COUNTER_ONCE_INITIALIZER(name)  \
 
106
    {                                        \
 
107
        name,                                \
 
108
        false,                               \
 
109
        0,                                   \
 
110
        0,                                   \
 
111
    }
 
112
 
 
113
void perf_counters_init(void);
 
114
void perf_counters_destroy(void);
 
115
void perf_counters_clear(void);
 
116
 
 
117
uint64_t perf_counter_read(uint64_t *counter);
 
118
void perf_counter_accumulate(struct perf_counter *counter,
 
119
                             uint64_t start_count);
 
120
char *perf_counters_to_string(void);
 
121
 
 
122
/* User access macros. */
 
123
#define PERF_FUNCTION_BEGIN \
 
124
    static struct perf_counter x__ = PERF_COUNTER_ONCE_INITIALIZER(__func__); \
 
125
    uint64_t start_count__ = perf_counter_read(&start_count__);               \
 
126
 
 
127
#define PERF_FUNCTION_END \
 
128
    perf_counter_accumulate(&x__, start_count__);
 
129
 
 
130
#else
 
131
 
 
132
#define PERF_FUNCTON_BEGIN
 
133
#define PERF_FUNCTON_END
 
134
 
 
135
static inline void perf_counters_init(void) {}
 
136
static inline void perf_counters_destroy(void) {}
 
137
static inline void perf_counters_clear(void) {}
 
138
static inline char *
 
139
perf_counters_to_string(void)
 
140
{
 
141
    return xstrdup("Not Supported on this platform. Only available on Linux (version >= 2.6.32)");
 
142
}
 
143
 
 
144
#endif
 
145
 
 
146
#endif