c8e88cc84e6110267d45ad0a470dac90e566777d
[muen/linux.git] / samples / bpf / lathist_user.c
1 /* Copyright (c) 2013-2015 PLUMgrid, http://plumgrid.com
2  * Copyright (c) 2015 BMW Car IT GmbH
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of version 2 of the GNU General Public
6  * License as published by the Free Software Foundation.
7  */
8 #include <stdio.h>
9 #include <unistd.h>
10 #include <stdlib.h>
11 #include <signal.h>
12 #include <linux/bpf.h>
13 #include <bpf/bpf.h>
14 #include "bpf_load.h"
15
16 #define MAX_ENTRIES     20
17 #define MAX_CPU         4
18 #define MAX_STARS       40
19
20 struct cpu_hist {
21         long data[MAX_ENTRIES];
22         long max;
23 };
24
25 static struct cpu_hist cpu_hist[MAX_CPU];
26
27 static void stars(char *str, long val, long max, int width)
28 {
29         int i;
30
31         for (i = 0; i < (width * val / max) - 1 && i < width - 1; i++)
32                 str[i] = '*';
33         if (val > max)
34                 str[i - 1] = '+';
35         str[i] = '\0';
36 }
37
38 static void print_hist(void)
39 {
40         char starstr[MAX_STARS];
41         struct cpu_hist *hist;
42         int i, j;
43
44         /* clear screen */
45         printf("\033[2J");
46
47         for (j = 0; j < MAX_CPU; j++) {
48                 hist = &cpu_hist[j];
49
50                 /* ignore CPUs without data (maybe offline?) */
51                 if (hist->max == 0)
52                         continue;
53
54                 printf("CPU %d\n", j);
55                 printf("      latency        : count     distribution\n");
56                 for (i = 1; i <= MAX_ENTRIES; i++) {
57                         stars(starstr, hist->data[i - 1], hist->max, MAX_STARS);
58                         printf("%8ld -> %-8ld : %-8ld |%-*s|\n",
59                                 (1l << i) >> 1, (1l << i) - 1,
60                                 hist->data[i - 1], MAX_STARS, starstr);
61                 }
62         }
63 }
64
65 static void get_data(int fd)
66 {
67         long key, value;
68         int c, i;
69
70         for (i = 0; i < MAX_CPU; i++)
71                 cpu_hist[i].max = 0;
72
73         for (c = 0; c < MAX_CPU; c++) {
74                 for (i = 0; i < MAX_ENTRIES; i++) {
75                         key = c * MAX_ENTRIES + i;
76                         bpf_map_lookup_elem(fd, &key, &value);
77
78                         cpu_hist[c].data[i] = value;
79                         if (value > cpu_hist[c].max)
80                                 cpu_hist[c].max = value;
81                 }
82         }
83 }
84
85 int main(int argc, char **argv)
86 {
87         char filename[256];
88
89         snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
90
91         if (load_bpf_file(filename)) {
92                 printf("%s", bpf_log_buf);
93                 return 1;
94         }
95
96         while (1) {
97                 get_data(map_fd[1]);
98                 print_hist();
99                 sleep(5);
100         }
101
102         return 0;
103 }