2 * Copyright (c) 2015 Nicira, Inc.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #ifndef __PERF_COUNTER_H
18 #define __PERF_COUNTER_H 1
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
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.
33 * Since there is no pre configured sample points, there is no run time
34 * over head for the released product.
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.
44 * Those are not fundamental limits, but only limited by current
47 * Function instruction counter sample point Usage
48 * ================================================
50 * There are two macros provided:
52 * Macro 'PERF_FUNCTON_COUNT_BEGIN' needs to be inserted towards the
53 * beginning of the function where local variables are declared.
55 * Macro 'PERF_FUNCTON_COUNT_END' needs to appear in the same function,
56 * some where below 'PERF_FUNCTION_COUNT_BEGIN', usually towards of
62 * int some_local_variable;
64 * PERF_FUNCTION_COUNT_BEGIN;
68 * PERF_FUNCTION_COUNT_END
71 * This will maintain the number of times 'my_func()' is called, total
72 * number of instructions '<implementation>' executed during all those calls.
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
80 * Note, there is no requirement for those macros to be balanced.
83 * void my_func(int i){
85 * PERF_FUNCTION_COUNT_BEGIN;
88 * PERF_FUNCTION_COUNT_END;
94 * will work just fine.
97 #if defined(__linux__) && defined(HAVE_LINUX_PERF_EVENT_H)
102 uint64_t total_count;
105 #define PERF_COUNTER_ONCE_INITIALIZER(name) \
113 void perf_counters_init(void);
114 void perf_counters_destroy(void);
115 void perf_counters_clear(void);
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);
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__); \
127 #define PERF_FUNCTION_END \
128 perf_counter_accumulate(&x__, start_count__);
132 #define PERF_FUNCTON_BEGIN
133 #define PERF_FUNCTON_END
135 static inline void perf_counters_init(void) {}
136 static inline void perf_counters_destroy(void) {}
137 static inline void perf_counters_clear(void) {}
139 perf_counters_to_string(void)
141 return xstrdup("Not Supported on this platform. Only available on Linux (version >= 2.6.32)");