162306a36Sopenharmony_ci#include <linux/perf_event.h> 262306a36Sopenharmony_ci#include <perf/evlist.h> 362306a36Sopenharmony_ci#include <perf/evsel.h> 462306a36Sopenharmony_ci#include <perf/cpumap.h> 562306a36Sopenharmony_ci#include <perf/threadmap.h> 662306a36Sopenharmony_ci#include <perf/mmap.h> 762306a36Sopenharmony_ci#include <perf/core.h> 862306a36Sopenharmony_ci#include <perf/event.h> 962306a36Sopenharmony_ci#include <stdio.h> 1062306a36Sopenharmony_ci#include <unistd.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_cistatic int libperf_print(enum libperf_print_level level, 1362306a36Sopenharmony_ci const char *fmt, va_list ap) 1462306a36Sopenharmony_ci{ 1562306a36Sopenharmony_ci return vfprintf(stderr, fmt, ap); 1662306a36Sopenharmony_ci} 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ciunion u64_swap { 1962306a36Sopenharmony_ci __u64 val64; 2062306a36Sopenharmony_ci __u32 val32[2]; 2162306a36Sopenharmony_ci}; 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ciint main(int argc, char **argv) 2462306a36Sopenharmony_ci{ 2562306a36Sopenharmony_ci struct perf_evlist *evlist; 2662306a36Sopenharmony_ci struct perf_evsel *evsel; 2762306a36Sopenharmony_ci struct perf_mmap *map; 2862306a36Sopenharmony_ci struct perf_cpu_map *cpus; 2962306a36Sopenharmony_ci struct perf_event_attr attr = { 3062306a36Sopenharmony_ci .type = PERF_TYPE_HARDWARE, 3162306a36Sopenharmony_ci .config = PERF_COUNT_HW_CPU_CYCLES, 3262306a36Sopenharmony_ci .disabled = 1, 3362306a36Sopenharmony_ci .freq = 1, 3462306a36Sopenharmony_ci .sample_freq = 10, 3562306a36Sopenharmony_ci .sample_type = PERF_SAMPLE_IP|PERF_SAMPLE_TID|PERF_SAMPLE_CPU|PERF_SAMPLE_PERIOD, 3662306a36Sopenharmony_ci }; 3762306a36Sopenharmony_ci int err = -1; 3862306a36Sopenharmony_ci union perf_event *event; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci libperf_init(libperf_print); 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci cpus = perf_cpu_map__new(NULL); 4362306a36Sopenharmony_ci if (!cpus) { 4462306a36Sopenharmony_ci fprintf(stderr, "failed to create cpus\n"); 4562306a36Sopenharmony_ci return -1; 4662306a36Sopenharmony_ci } 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci evlist = perf_evlist__new(); 4962306a36Sopenharmony_ci if (!evlist) { 5062306a36Sopenharmony_ci fprintf(stderr, "failed to create evlist\n"); 5162306a36Sopenharmony_ci goto out_cpus; 5262306a36Sopenharmony_ci } 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci evsel = perf_evsel__new(&attr); 5562306a36Sopenharmony_ci if (!evsel) { 5662306a36Sopenharmony_ci fprintf(stderr, "failed to create cycles\n"); 5762306a36Sopenharmony_ci goto out_cpus; 5862306a36Sopenharmony_ci } 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci perf_evlist__add(evlist, evsel); 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci perf_evlist__set_maps(evlist, cpus, NULL); 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci err = perf_evlist__open(evlist); 6562306a36Sopenharmony_ci if (err) { 6662306a36Sopenharmony_ci fprintf(stderr, "failed to open evlist\n"); 6762306a36Sopenharmony_ci goto out_evlist; 6862306a36Sopenharmony_ci } 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci err = perf_evlist__mmap(evlist, 4); 7162306a36Sopenharmony_ci if (err) { 7262306a36Sopenharmony_ci fprintf(stderr, "failed to mmap evlist\n"); 7362306a36Sopenharmony_ci goto out_evlist; 7462306a36Sopenharmony_ci } 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci perf_evlist__enable(evlist); 7762306a36Sopenharmony_ci sleep(3); 7862306a36Sopenharmony_ci perf_evlist__disable(evlist); 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci perf_evlist__for_each_mmap(evlist, map, false) { 8162306a36Sopenharmony_ci if (perf_mmap__read_init(map) < 0) 8262306a36Sopenharmony_ci continue; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci while ((event = perf_mmap__read_event(map)) != NULL) { 8562306a36Sopenharmony_ci int cpu, pid, tid; 8662306a36Sopenharmony_ci __u64 ip, period, *array; 8762306a36Sopenharmony_ci union u64_swap u; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci array = event->sample.array; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci ip = *array; 9262306a36Sopenharmony_ci array++; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci u.val64 = *array; 9562306a36Sopenharmony_ci pid = u.val32[0]; 9662306a36Sopenharmony_ci tid = u.val32[1]; 9762306a36Sopenharmony_ci array++; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci u.val64 = *array; 10062306a36Sopenharmony_ci cpu = u.val32[0]; 10162306a36Sopenharmony_ci array++; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci period = *array; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci fprintf(stdout, "cpu %3d, pid %6d, tid %6d, ip %20llx, period %20llu\n", 10662306a36Sopenharmony_ci cpu, pid, tid, ip, period); 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci perf_mmap__consume(map); 10962306a36Sopenharmony_ci } 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci perf_mmap__read_done(map); 11262306a36Sopenharmony_ci } 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ciout_evlist: 11562306a36Sopenharmony_ci perf_evlist__delete(evlist); 11662306a36Sopenharmony_ciout_cpus: 11762306a36Sopenharmony_ci perf_cpu_map__put(cpus); 11862306a36Sopenharmony_ci return err; 11962306a36Sopenharmony_ci} 120