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 12static int libperf_print(enum libperf_print_level level, 13 const char *fmt, va_list ap) 14{ 15 return vfprintf(stderr, fmt, ap); 16} 17 18union u64_swap { 19 __u64 val64; 20 __u32 val32[2]; 21}; 22 23int 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(NULL); 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 114out_evlist: 115 perf_evlist__delete(evlist); 116out_cpus: 117 perf_cpu_map__put(cpus); 118 return err; 119} 120