| 1 | #include <linux/perf_event.h>
|
| 2 | #include <perf/evlist.h>
|
| 3 | #include <perf/evsel.h>
|
| 4 | #include <perf/cpumap.h>
|
| 5 | #include <perf/threadmap.h>
|
| 6 | #include <perf/mmap.h>
|
| 7 | #include <perf/core.h>
|
| 8 | #include <perf/event.h>
|
| 9 | #include <stdio.h>
|
| 10 | #include <unistd.h>
|
| 11 |
|
| 12 | static int libperf_print(enum libperf_print_level level,
|
| 13 | const char *fmt, va_list ap)
|
| 14 | {
|
| 15 | return vfprintf(stderr, fmt, ap);
|
| 16 | }
|
| 17 |
|
| 18 | union u64_swap {
|
| 19 | __u64 val64;
|
| 20 | __u32 val32[2];
|
| 21 | };
|
| 22 |
|
| 23 | int main(int argc, char **argv)
|
| 24 | {
|
| 25 | struct perf_evlist *evlist;
|
| 26 | struct perf_evsel *evsel;
|
| 27 | struct perf_mmap *map;
|
| 28 | struct perf_cpu_map *cpus;
|
| 29 | struct perf_event_attr attr = {
|
| 30 | .type = PERF_TYPE_HARDWARE,
|
| 31 | .config = PERF_COUNT_HW_CPU_CYCLES,
|
| 32 | .disabled = 1,
|
| 33 | .freq = 1,
|
| 34 | .sample_freq = 10,
|
| 35 | .sample_type = PERF_SAMPLE_IP|PERF_SAMPLE_TID|PERF_SAMPLE_CPU|PERF_SAMPLE_PERIOD,
|
| 36 | };
|
| 37 | int err = -1;
|
| 38 | union perf_event *event;
|
| 39 |
|
| 40 | libperf_init(libperf_print);
|
| 41 |
|
| 42 | cpus = perf_cpu_map__new_online_cpus();
|
| 43 | if (!cpus) {
|
| 44 | fprintf(stderr, "failed to create cpus\n");
|
| 45 | return -1;
|
| 46 | }
|
| 47 |
|
| 48 | evlist = perf_evlist__new();
|
| 49 | if (!evlist) {
|
| 50 | fprintf(stderr, "failed to create evlist\n");
|
| 51 | goto out_cpus;
|
| 52 | }
|
| 53 |
|
| 54 | evsel = perf_evsel__new(&attr);
|
| 55 | if (!evsel) {
|
| 56 | fprintf(stderr, "failed to create cycles\n");
|
| 57 | goto out_cpus;
|
| 58 | }
|
| 59 |
|
| 60 | perf_evlist__add(evlist, evsel);
|
| 61 |
|
| 62 | perf_evlist__set_maps(evlist, cpus, NULL);
|
| 63 |
|
| 64 | err = perf_evlist__open(evlist);
|
| 65 | if (err) {
|
| 66 | fprintf(stderr, "failed to open evlist\n");
|
| 67 | goto out_evlist;
|
| 68 | }
|
| 69 |
|
| 70 | err = perf_evlist__mmap(evlist, 4);
|
| 71 | if (err) {
|
| 72 | fprintf(stderr, "failed to mmap evlist\n");
|
| 73 | goto out_evlist;
|
| 74 | }
|
| 75 |
|
| 76 | perf_evlist__enable(evlist);
|
| 77 | sleep(3);
|
| 78 | perf_evlist__disable(evlist);
|
| 79 |
|
| 80 | perf_evlist__for_each_mmap(evlist, map, false) {
|
| 81 | if (perf_mmap__read_init(map) < 0)
|
| 82 | continue;
|
| 83 |
|
| 84 | while ((event = perf_mmap__read_event(map)) != NULL) {
|
| 85 | int cpu, pid, tid;
|
| 86 | __u64 ip, period, *array;
|
| 87 | union u64_swap u;
|
| 88 |
|
| 89 | array = event->sample.array;
|
| 90 |
|
| 91 | ip = *array;
|
| 92 | array++;
|
| 93 |
|
| 94 | u.val64 = *array;
|
| 95 | pid = u.val32[0];
|
| 96 | tid = u.val32[1];
|
| 97 | array++;
|
| 98 |
|
| 99 | u.val64 = *array;
|
| 100 | cpu = u.val32[0];
|
| 101 | array++;
|
| 102 |
|
| 103 | period = *array;
|
| 104 |
|
| 105 | fprintf(stdout, "cpu %3d, pid %6d, tid %6d, ip %20llx, period %20llu\n",
|
| 106 | cpu, pid, tid, ip, period);
|
| 107 |
|
| 108 | perf_mmap__consume(map);
|
| 109 | }
|
| 110 |
|
| 111 | perf_mmap__read_done(map);
|
| 112 | }
|
| 113 |
|
| 114 | out_evlist:
|
| 115 | perf_evlist__delete(evlist);
|
| 116 | out_cpus:
|
| 117 | perf_cpu_map__put(cpus);
|
| 118 | return err;
|
| 119 | }
|