Path: blob/master/tools/lib/perf/Documentation/libperf-counting.txt
26298 views
libperf-counting(7)1===================23NAME4----5libperf-counting - counting interface67DESCRIPTION8-----------9The counting interface provides API to measure and get count for specific perf events.1011The following test tries to explain count on `counting.c` example.1213It is by no means complete guide to counting, but shows libperf basic API for counting.1415The `counting.c` comes with libperf package and can be compiled and run like:1617[source,bash]18--19$ gcc -o counting counting.c -lperf20$ sudo ./counting21count 176792, enabled 176944, run 17694422count 176242, enabled 176242, run 17624223--2425It requires root access, because of the `PERF_COUNT_SW_CPU_CLOCK` event,26which is available only for root.2728The `counting.c` example monitors two events on the current process and displays29their count, in a nutshell it:3031* creates events32* adds them to the event list33* opens and enables events through the event list34* does some workload35* disables events36* reads and displays event counts37* destroys the event list3839The first thing you need to do before using libperf is to call init function:4041[source,c]42--438 static int libperf_print(enum libperf_print_level level,449 const char *fmt, va_list ap)4510 {4611 return vfprintf(stderr, fmt, ap);4712 }484914 int main(int argc, char **argv)5015 {51...5235 libperf_init(libperf_print);53--5455It will setup the library and sets function for debug output from library.5657The `libperf_print` callback will receive any message with its debug level,58defined as:5960[source,c]61--62enum libperf_print_level {63LIBPERF_ERR,64LIBPERF_WARN,65LIBPERF_INFO,66LIBPERF_DEBUG,67LIBPERF_DEBUG2,68LIBPERF_DEBUG3,69};70--7172Once the setup is complete we start by defining specific events using the `struct perf_event_attr`.7374We create software events for cpu and task:7576[source,c]77--7820 struct perf_event_attr attr1 = {7921 .type = PERF_TYPE_SOFTWARE,8022 .config = PERF_COUNT_SW_CPU_CLOCK,8123 .read_format = PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING,8224 .disabled = 1,8325 };8426 struct perf_event_attr attr2 = {8527 .type = PERF_TYPE_SOFTWARE,8628 .config = PERF_COUNT_SW_TASK_CLOCK,8729 .read_format = PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING,8830 .disabled = 1,8931 };90--9192The `read_format` setup tells perf to include timing details together with each count.9394Next step is to prepare threads map.9596In this case we will monitor current process, so we create threads map with single pid (0):9798[source,c]99--10037 threads = perf_thread_map__new_dummy();10138 if (!threads) {10239 fprintf(stderr, "failed to create threads\n");10340 return -1;10441 }1054210643 perf_thread_map__set_pid(threads, 0, 0);107--108109Now we create libperf's event list, which will serve as holder for the events we want:110111[source,c]112--11345 evlist = perf_evlist__new();11446 if (!evlist) {11547 fprintf(stderr, "failed to create evlist\n");11648 goto out_threads;11749 }118--119120We create libperf's events for the attributes we defined earlier and add them to the list:121122[source,c]123--12451 evsel = perf_evsel__new(&attr1);12552 if (!evsel) {12653 fprintf(stderr, "failed to create evsel1\n");12754 goto out_evlist;12855 }1295613057 perf_evlist__add(evlist, evsel);1315813259 evsel = perf_evsel__new(&attr2);13360 if (!evsel) {13461 fprintf(stderr, "failed to create evsel2\n");13562 goto out_evlist;13663 }1376413865 perf_evlist__add(evlist, evsel);139--140141Configure event list with the thread map and open events:142143[source,c]144--14567 perf_evlist__set_maps(evlist, NULL, threads);1466814769 err = perf_evlist__open(evlist);14870 if (err) {14971 fprintf(stderr, "failed to open evsel\n");15072 goto out_evlist;15173 }152--153154Both events are created as disabled (note the `disabled = 1` assignment above),155so we need to enable the whole list explicitly (both events).156157From this moment events are counting and we can do our workload.158159When we are done we disable the events list.160161[source,c]162--16375 perf_evlist__enable(evlist);1647616577 while (count--);1667816779 perf_evlist__disable(evlist);168--169170Now we need to get the counts from events, following code iterates through the171events list and read counts:172173[source,c]174--17581 perf_evlist__for_each_evsel(evlist, evsel) {17682 perf_evsel__read(evsel, 0, 0, &counts);17783 fprintf(stdout, "count %llu, enabled %llu, run %llu\n",17884 counts.val, counts.ena, counts.run);17985 }180--181182And finally cleanup.183184We close the whole events list (both events) and remove it together with the threads map:185186[source,c]187--18887 perf_evlist__close(evlist);1898819089 out_evlist:19190 perf_evlist__delete(evlist);19291 out_threads:19392 perf_thread_map__put(threads);19493 return err;19594 }196--197198REPORTING BUGS199--------------200Report bugs to <[email protected]>.201202LICENSE203-------204libperf is Free Software licensed under the GNU LGPL 2.1205206RESOURCES207---------208https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git209210SEE ALSO211--------212libperf(3), libperf-sampling(7)213214215