| #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; | |
| } |