| #!/usr/bin/env python | |
| # Copyright (c) 2016 PLUMgrid | |
| # Licensed under the Apache License, Version 2.0 (the "License") | |
| import bcc | |
| import ctypes | |
| import multiprocessing | |
| import os | |
| import time | |
| import unittest | |
| class TestPerfCounter(unittest.TestCase): | |
| def test_cycles(self): | |
| text = """ | |
| BPF_PERF_ARRAY(cnt1, NUM_CPUS); | |
| BPF_ARRAY(prev, u64, NUM_CPUS); | |
| BPF_HISTOGRAM(dist); | |
| int do_sys_getuid(void *ctx) { | |
| u32 cpu = bpf_get_smp_processor_id(); | |
| u64 val = cnt1.perf_read(CUR_CPU_IDENTIFIER); | |
| if (((s64)val < 0) && ((s64)val > -256)) | |
| return 0; | |
| prev.update(&cpu, &val); | |
| return 0; | |
| } | |
| int do_ret_sys_getuid(void *ctx) { | |
| u32 cpu = bpf_get_smp_processor_id(); | |
| u64 val = cnt1.perf_read(CUR_CPU_IDENTIFIER); | |
| if (((s64)val < 0) && ((s64)val > -256)) | |
| return 0; | |
| u64 *prevp = prev.lookup(&cpu); | |
| if (prevp) { | |
| dist.increment(bpf_log2l(val - *prevp)); | |
| dist.atomic_increment(bpf_log2l(val - *prevp)); | |
| } | |
| return 0; | |
| } | |
| """ | |
| b = bcc.BPF(text=text, debug=0, | |
| cflags=["-DNUM_CPUS=%d" % multiprocessing.cpu_count()]) | |
| event_name = b.get_syscall_fnname("getuid") | |
| b.attach_kprobe(event=event_name, fn_name="do_sys_getuid") | |
| b.attach_kretprobe(event=event_name, fn_name="do_ret_sys_getuid") | |
| cnt1 = b["cnt1"] | |
| try: | |
| cnt1.open_perf_event(bcc.PerfType.HARDWARE, bcc.PerfHWConfig.CPU_CYCLES) | |
| except: | |
| if ctypes.get_errno() == 2: | |
| raise self.skipTest("hardware events unsupported") | |
| raise | |
| for i in range(0, 100): | |
| os.getuid() | |
| b["dist"].print_log2_hist() | |
| if __name__ == "__main__": | |
| unittest.main() |