1LIBPERF-COUNTING(7)             libperf Manual             LIBPERF-COUNTING(7)
2
3
4

NAME

6       libperf-counting - counting interface
7

DESCRIPTION

9       The counting interface provides API to measure and get count for
10       specific perf events.
11
12       The following test tries to explain count on counting.c example.
13
14       It is by no means complete guide to counting, but shows libperf basic
15       API for counting.
16
17       The counting.c comes with libperf package and can be compiled and run
18       like:
19
20           $ gcc -o counting counting.c -lperf
21           $ sudo ./counting
22           count 176792, enabled 176944, run 176944
23           count 176242, enabled 176242, run 176242
24
25       It requires root access, because of the PERF_COUNT_SW_CPU_CLOCK event,
26       which is available only for root.
27
28       The counting.c example monitors two events on the current process and
29       displays their count, in a nutshell it:
30
31       •   creates events
32
33       •   adds them to the event list
34
35       •   opens and enables events through the event list
36
37       •   does some workload
38
39       •   disables events
40
41       •   reads and displays event counts
42
43       •   destroys the event list
44
45       The first thing you need to do before using libperf is to call init
46       function:
47
48             8 static int libperf_print(enum libperf_print_level level,
49             9                          const char *fmt, va_list ap)
50            10 {
51            11         return vfprintf(stderr, fmt, ap);
52            12 }
53
54            14 int main(int argc, char **argv)
55            15 {
56            ...
57            35         libperf_init(libperf_print);
58
59       It will setup the library and sets function for debug output from
60       library.
61
62       The libperf_print callback will receive any message with its debug
63       level, defined as:
64
65           enum libperf_print_level {
66                   LIBPERF_ERR,
67                   LIBPERF_WARN,
68                   LIBPERF_INFO,
69                   LIBPERF_DEBUG,
70                   LIBPERF_DEBUG2,
71                   LIBPERF_DEBUG3,
72           };
73
74       Once the setup is complete we start by defining specific events using
75       the struct perf_event_attr.
76
77       We create software events for cpu and task:
78
79            20         struct perf_event_attr attr1 = {
80            21                 .type        = PERF_TYPE_SOFTWARE,
81            22                 .config      = PERF_COUNT_SW_CPU_CLOCK,
82            23                 .read_format = PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING,
83            24                 .disabled    = 1,
84            25         };
85            26         struct perf_event_attr attr2 = {
86            27                 .type        = PERF_TYPE_SOFTWARE,
87            28                 .config      = PERF_COUNT_SW_TASK_CLOCK,
88            29                 .read_format = PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING,
89            30                 .disabled    = 1,
90            31         };
91
92       The read_format setup tells perf to include timing details together
93       with each count.
94
95       Next step is to prepare threads map.
96
97       In this case we will monitor current process, so we create threads map
98       with single pid (0):
99
100            37         threads = perf_thread_map__new_dummy();
101            38         if (!threads) {
102            39                 fprintf(stderr, "failed to create threads\n");
103            40                 return -1;
104            41         }
105            42
106            43         perf_thread_map__set_pid(threads, 0, 0);
107
108       Now we create libperf’s event list, which will serve as holder for the
109       events we want:
110
111            45         evlist = perf_evlist__new();
112            46         if (!evlist) {
113            47                 fprintf(stderr, "failed to create evlist\n");
114            48                 goto out_threads;
115            49         }
116
117       We create libperf’s events for the attributes we defined earlier and
118       add them to the list:
119
120            51         evsel = perf_evsel__new(&attr1);
121            52         if (!evsel) {
122            53                 fprintf(stderr, "failed to create evsel1\n");
123            54                 goto out_evlist;
124            55         }
125            56
126            57         perf_evlist__add(evlist, evsel);
127            58
128            59         evsel = perf_evsel__new(&attr2);
129            60         if (!evsel) {
130            61                 fprintf(stderr, "failed to create evsel2\n");
131            62                 goto out_evlist;
132            63         }
133            64
134            65         perf_evlist__add(evlist, evsel);
135
136       Configure event list with the thread map and open events:
137
138            67         perf_evlist__set_maps(evlist, NULL, threads);
139            68
140            69         err = perf_evlist__open(evlist);
141            70         if (err) {
142            71                 fprintf(stderr, "failed to open evsel\n");
143            72                 goto out_evlist;
144            73         }
145
146       Both events are created as disabled (note the disabled = 1 assignment
147       above), so we need to enable the whole list explicitly (both events).
148
149       From this moment events are counting and we can do our workload.
150
151       When we are done we disable the events list.
152
153            75         perf_evlist__enable(evlist);
154            76
155            77         while (count--);
156            78
157            79         perf_evlist__disable(evlist);
158
159       Now we need to get the counts from events, following code iterates
160       through the events list and read counts:
161
162            81         perf_evlist__for_each_evsel(evlist, evsel) {
163            82                 perf_evsel__read(evsel, 0, 0, &counts);
164            83                 fprintf(stdout, "count %llu, enabled %llu, run %llu\n",
165            84                         counts.val, counts.ena, counts.run);
166            85         }
167
168       And finally cleanup.
169
170       We close the whole events list (both events) and remove it together
171       with the threads map:
172
173            87         perf_evlist__close(evlist);
174            88
175            89 out_evlist:
176            90         perf_evlist__delete(evlist);
177            91 out_threads:
178            92         perf_thread_map__put(threads);
179            93         return err;
180            94 }
181

REPORTING BUGS

183       Report bugs to <linux-perf-users@vger.kernel.org[1]>.
184

LICENSE

186       libperf is Free Software licensed under the GNU LGPL 2.1
187

RESOURCES

189       https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
190

SEE ALSO

192       libperf(3), libperf-sampling(7)
193

NOTES

195        1. linux-perf-users@vger.kernel.org
196           mailto:linux-perf-users@vger.kernel.org
197
198
199
200libperf                           11/22/2021               LIBPERF-COUNTING(7)
Impressum