Add 6 tools tracking dbus.
[platform/upstream/bcc.git] / tools / dbus-glib-tok.py
1 #!/usr/bin/python
2
3 from bcc import BPF
4 from time import sleep
5 from ctypes import c_ushort, c_int, c_ulonglong
6 from sys import argv
7
8
9 print("Hit Ctrl-C to end.")
10 count = 100
11 interval = 5
12 loop = 0
13 # load BPF program
14 bpf_text="""#include <uapi/linux/ptrace.h>
15 #include <linux/sched.h>
16
17 typedef struct pdata_T {
18         u32 pid;
19         char buf[TASK_COMM_LEN];
20         u64 drun;
21         u64 dwait;
22         u64 grun;
23         u64 gwait;
24         u64 usage;
25 }pdata_t;
26
27 BPF_HASH(timestamp_b, u64);
28 BPF_HASH(timestamp_e, u64);
29 BPF_HASH(stats, u32, pdata_t, sizeof(pdata_t));
30 BPF_HASH(run_start, u32);
31 BPF_HASH(wait_start, u32);
32
33 BPF_HISTOGRAM(dist);
34
35 int do_entry_dbus(struct pt_regs *ctx) {
36         u64 time = 0;
37         pdata_t pdata;
38         pdata_t new_pdata = {0, ' ', 0, 0, 0, 0, 0};
39         u64 ts, *tsp, delta;
40         u32 pid;
41
42         ts = bpf_ktime_get_ns() / 1000;
43         if(timestamp_b.lookup(&time) == 0){
44                 timestamp_b.update(&time, &ts);
45         }
46         timestamp_e.update(&time, &ts);
47
48         pid = bpf_get_current_pid_tgid();
49         tsp = run_start.lookup(&pid);
50         run_start.delete(&pid);
51         wait_start.update(&pid, &ts);
52         if(tsp != 0) {
53                 delta = ts -*tsp;
54         }
55         else {
56                 return 0;
57         }
58         new_pdata.pid = pid;
59         pdata = *(stats.lookup_or_init(&pid, &new_pdata));
60         pdata.drun += delta;
61         pdata.usage += delta;
62         bpf_get_current_comm(&(pdata.buf), sizeof(pdata.buf));
63         stats.update(&pid, &pdata);
64         return 0;
65 }
66
67 int do_return_dbus(struct pt_regs *ctx) {
68         u64 time = 0;
69         pdata_t pdata;
70         pdata_t new_pdata = {0, ' ', 0, 0, 0, 0, 0};
71         u64 ts, *tsp, delta;
72         u32 pid;
73
74         ts = bpf_ktime_get_ns() / 1000;
75         if(timestamp_b.lookup(&time) == 0){
76                 timestamp_b.update(&time, &ts);
77         }
78         timestamp_e.update(&time, &ts);
79
80         pid = bpf_get_current_pid_tgid();
81         tsp = wait_start.lookup(&pid);
82         wait_start.delete(&pid);
83         run_start.update(&pid, &ts);
84         if(tsp != 0) {
85                 delta = ts - *tsp;
86         }
87         else {
88                 return 0;
89         }
90         new_pdata.pid = pid;
91         pdata = *(stats.lookup_or_init(&pid, &new_pdata));
92         pdata.dwait += delta;
93         bpf_get_current_comm(&(pdata.buf), sizeof(pdata.buf));
94         stats.update(&pid, &pdata);
95         return 0;
96 }
97
98 int do_entry_glib(struct pt_regs *ctx) {
99         u64 time = 0;
100         pdata_t pdata;
101         pdata_t new_pdata = {0, ' ', 0, 0, 0, 0, 0};
102         u64 ts, *tsp, delta;
103         u32 pid;
104
105         ts = bpf_ktime_get_ns() / 1000;
106         if(timestamp_b.lookup(&time) == 0){
107                 timestamp_b.update(&time, &ts);
108         }
109         timestamp_e.update(&time, &ts);
110
111         pid = bpf_get_current_pid_tgid();
112         tsp = run_start.lookup(&pid);
113         run_start.delete(&pid);
114         wait_start.update(&pid, &ts);
115         if(tsp != 0) {
116                 delta = ts -*tsp;
117         }
118         else {
119                 return 0;
120         }
121         new_pdata.pid = pid;
122         pdata = *(stats.lookup_or_init(&pid, &new_pdata));
123         pdata.grun += delta;
124         pdata.usage += delta;
125         bpf_get_current_comm(&(pdata.buf), sizeof(pdata.buf));
126         stats.update(&pid, &pdata);
127         return 0;
128 }
129
130 int do_return_glib(struct pt_regs *ctx) {
131         u64 time = 0;
132         pdata_t pdata;
133         pdata_t new_pdata = {0, ' ', 0, 0, 0, 0, 0};
134         u64 ts, *tsp, delta;
135         u32 pid;
136
137         ts = bpf_ktime_get_ns() / 1000;
138         if(timestamp_b.lookup(&time) == 0){
139                 timestamp_b.update(&time, &ts);
140         }
141         timestamp_e.update(&time, &ts);
142
143         pid = bpf_get_current_pid_tgid();
144         tsp = wait_start.lookup(&pid);
145         wait_start.delete(&pid);
146         run_start.update(&pid, &ts);
147         if(tsp != 0) {
148                 delta = ts - *tsp;
149         }
150         else {
151                 return 0;
152         }
153         new_pdata.pid = pid;
154         pdata = *(stats.lookup_or_init(&pid, &new_pdata));
155         pdata.gwait += delta;
156         bpf_get_current_comm(&(pdata.buf), sizeof(pdata.buf));
157         stats.update(&pid, &pdata);
158         return 0;
159 }
160 """
161
162 b = BPF(text=bpf_text)
163
164 b.attach_uprobe(name="glib-2.0", sym="g_poll", fn_name="do_entry_glib")
165 b.attach_uprobe(name="dbus-1", sym="_dbus_poll", fn_name="do_entry_dbus")
166
167 b.attach_uretprobe(name="dbus-1", sym="_dbus_poll", fn_name="do_return_dbus")
168 b.attach_uretprobe(name="glib-2.0", sym="g_poll", fn_name="do_return_glib")
169
170 while (1):
171         if count > 0:
172
173                 loop += 1
174                 if loop > count:
175                         exit()
176         sleep(interval)
177         print ("%d : \n" % loop)
178         b["dist"].print_log2_hist("usecs")
179         b["dist"].clear()
180         stats_t = b["stats"]
181         timestamp = b["timestamp_e"]
182         timeframe = 0
183         for v in timestamp.values():
184                 timeframe = v.value
185         timestamp = b["timestamp_b"]
186         for v in timestamp.values():
187                 timeframe -= v.value
188         #print("%d\n" % stats_t[0].pid)
189         print ("%10s %20s %10s %10s" % ("PID", "NAME", "DBUS", "GLIB"))
190         for v in sorted(stats_t.values(), key=lambda stats_t: stats_t.usage, reverse=True):
191                 print("%10d %20s %10.6f %10.6f" % (v.pid, v.buf.encode('string-escape'), float(v.drun) / float(timeframe), float(v.grun) / float(timeframe)))