| #include <linux/perf_event.h> |
| #include <perf/evlist.h> |
| #include <perf/evsel.h> |
| #include <perf/cpumap.h> |
| #include <perf/threadmap.h> |
| #include <perf/mmap.h> |
| #include <perf/core.h> |
| #include <perf/event.h> |
| #include <stdio.h> |
| #include <unistd.h> |
| |
| static int libperf_print(enum libperf_print_level level, |
| const char *fmt, va_list ap) |
| { |
| return vfprintf(stderr, fmt, ap); |
| } |
| |
| union u64_swap { |
| __u64 val64; |
| __u32 val32[2]; |
| }; |
| |
| int main(int argc, char **argv) |
| { |
| struct perf_evlist *evlist; |
| struct perf_evsel *evsel; |
| struct perf_mmap *map; |
| struct perf_cpu_map *cpus; |
| struct perf_event_attr attr = { |
| .type = PERF_TYPE_HARDWARE, |
| .config = PERF_COUNT_HW_CPU_CYCLES, |
| .disabled = 1, |
| .freq = 1, |
| .sample_freq = 10, |
| .sample_type = PERF_SAMPLE_IP|PERF_SAMPLE_TID|PERF_SAMPLE_CPU|PERF_SAMPLE_PERIOD, |
| }; |
| int err = -1; |
| union perf_event *event; |
| |
| libperf_init(libperf_print); |
| |
| cpus = perf_cpu_map__new(NULL); |
| if (!cpus) { |
| fprintf(stderr, "failed to create cpus\n"); |
| return -1; |
| } |
| |
| evlist = perf_evlist__new(); |
| if (!evlist) { |
| fprintf(stderr, "failed to create evlist\n"); |
| goto out_cpus; |
| } |
| |
| evsel = perf_evsel__new(&attr); |
| if (!evsel) { |
| fprintf(stderr, "failed to create cycles\n"); |
| goto out_cpus; |
| } |
| |
| perf_evlist__add(evlist, evsel); |
| |
| perf_evlist__set_maps(evlist, cpus, NULL); |
| |
| err = perf_evlist__open(evlist); |
| if (err) { |
| fprintf(stderr, "failed to open evlist\n"); |
| goto out_evlist; |
| } |
| |
| err = perf_evlist__mmap(evlist, 4); |
| if (err) { |
| fprintf(stderr, "failed to mmap evlist\n"); |
| goto out_evlist; |
| } |
| |
| perf_evlist__enable(evlist); |
| sleep(3); |
| perf_evlist__disable(evlist); |
| |
| perf_evlist__for_each_mmap(evlist, map, false) { |
| if (perf_mmap__read_init(map) < 0) |
| continue; |
| |
| while ((event = perf_mmap__read_event(map)) != NULL) { |
| int cpu, pid, tid; |
| __u64 ip, period, *array; |
| union u64_swap u; |
| |
| array = event->sample.array; |
| |
| ip = *array; |
| array++; |
| |
| u.val64 = *array; |
| pid = u.val32[0]; |
| tid = u.val32[1]; |
| array++; |
| |
| u.val64 = *array; |
| cpu = u.val32[0]; |
| array++; |
| |
| period = *array; |
| |
| fprintf(stdout, "cpu %3d, pid %6d, tid %6d, ip %20llx, period %20llu\n", |
| cpu, pid, tid, ip, period); |
| |
| perf_mmap__consume(map); |
| } |
| |
| perf_mmap__read_done(map); |
| } |
| |
| out_evlist: |
| perf_evlist__delete(evlist); |
| out_cpus: |
| perf_cpu_map__put(cpus); |
| return err; |
| } |