diff options
author | Jonathan <hermanjl@hermanjl-Aspire-5553G.(none)> | 2012-03-08 20:23:53 -0500 |
---|---|---|
committer | Jonathan <hermanjl@hermanjl-Aspire-5553G.(none)> | 2012-03-08 20:23:53 -0500 |
commit | 11c9b6cac9c5cfb72ecaa88d6f5ab0c6cd0034ae (patch) | |
tree | c456d1d9b5aebcbe67042995dfe10f1d1e961512 | |
parent | 8b715d53a1737e16f1c7c04b6c5b03feb1ebaed9 (diff) |
rt-graph: rt cpus have all basic features implemented
-rw-r--r-- | rt-plot-cpu.c | 461 | ||||
-rw-r--r-- | rt-plot-cpu.h | 20 | ||||
-rw-r--r-- | rt-plot-task.c | 16 | ||||
-rw-r--r-- | trace-graph.h | 6 |
4 files changed, 491 insertions, 12 deletions
diff --git a/rt-plot-cpu.c b/rt-plot-cpu.c new file mode 100644 index 0000000..6884286 --- /dev/null +++ b/rt-plot-cpu.c | |||
@@ -0,0 +1,461 @@ | |||
1 | #include "trace-graph.h" | ||
2 | #include "cpu.h" | ||
3 | |||
4 | #define DEBUG_LEVEL 0 | ||
5 | #if DEBUG_LEVEL > 0 | ||
6 | #define dprintf(l, x...) \ | ||
7 | do { \ | ||
8 | if (l <= DEBUG_LEVEL) \ | ||
9 | printf(x); \ | ||
10 | } while (0) | ||
11 | #else | ||
12 | #define dprintf(l, x...) do { if (0) printf(x); } while (0) | ||
13 | #endif | ||
14 | |||
15 | static struct record* | ||
16 | next_sa_record(struct graph_info *ginfo, struct rt_cpu_info *rtc_info, | ||
17 | unsigned long long time, int *out_pid) | ||
18 | { | ||
19 | struct pevent *pevent; | ||
20 | struct record *ret = NULL, *record; | ||
21 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
22 | unsigned long long max_ts, dull; | ||
23 | int pid, dint, match; | ||
24 | |||
25 | max_ts = time + SEARCH_PERIODS * rtg_info->max_period; | ||
26 | pevent = ginfo->pevent; | ||
27 | |||
28 | set_cpu_to_rts(ginfo, time, rtc_info->cpu); | ||
29 | |||
30 | while ((record = tracecmd_read_data(ginfo->handle, rtc_info->cpu))) { | ||
31 | if (get_rts(ginfo, record) > max_ts) { | ||
32 | free_record(record); | ||
33 | break; | ||
34 | } | ||
35 | match = rt_graph_check_switch_away(rtg_info, pevent, record, | ||
36 | &pid, &dint, &dull); | ||
37 | if (match) { | ||
38 | ret = record; | ||
39 | *out_pid = pid; | ||
40 | break; | ||
41 | } | ||
42 | free_record(record); | ||
43 | } | ||
44 | return ret; | ||
45 | } | ||
46 | |||
47 | static struct record* | ||
48 | find_record(struct graph_info *ginfo, int cpu, unsigned long long time) | ||
49 | { | ||
50 | struct record *record = NULL; | ||
51 | set_cpu_to_rts(ginfo, time, cpu); | ||
52 | |||
53 | while ((record = tracecmd_read_data(ginfo->handle, cpu))) { | ||
54 | if (get_rts(ginfo, record) >= time) | ||
55 | break; | ||
56 | free_record(record); | ||
57 | } | ||
58 | return record; | ||
59 | } | ||
60 | |||
61 | |||
62 | static void update_pid(struct rt_cpu_info *rtc_info, int pid) | ||
63 | { | ||
64 | rtc_info->fresh = FALSE; | ||
65 | if (pid != rtc_info->run_pid) { | ||
66 | rtc_info->run_pid = pid; | ||
67 | snprintf(rtc_info->label, LLABEL, "%d", rtc_info->run_pid); | ||
68 | } | ||
69 | } | ||
70 | |||
71 | static int | ||
72 | try_switch_away(struct graph_info *ginfo, struct rt_cpu_info *rtc_info, | ||
73 | struct record *record, struct plot_info *info) | ||
74 | { | ||
75 | int job, pid, match; | ||
76 | unsigned long long ts; | ||
77 | |||
78 | match = rt_graph_check_switch_away(&ginfo->rtg_info, ginfo->pevent, | ||
79 | record, &pid, &job, &ts); | ||
80 | if (match) { | ||
81 | update_pid(rtc_info, pid); | ||
82 | if (rtc_info->run_time && rtc_info->run_time < ts) { | ||
83 | info->box = TRUE; | ||
84 | info->bcolor = hash_pid(rtc_info->run_pid); | ||
85 | info->bfill = TRUE; | ||
86 | info->bstart = rtc_info->run_time; | ||
87 | info->bend = ts; | ||
88 | info->blabel = rtc_info->label; | ||
89 | } | ||
90 | rtc_info->run_pid = 0; | ||
91 | rtc_info->run_time = 0Ull; | ||
92 | } | ||
93 | return match; | ||
94 | } | ||
95 | |||
96 | static int | ||
97 | try_switch_to(struct graph_info *ginfo, struct rt_cpu_info *rtc_info, | ||
98 | struct record *record, struct plot_info *info) | ||
99 | { | ||
100 | int job, pid, match; | ||
101 | unsigned long long ts; | ||
102 | |||
103 | match = rt_graph_check_switch_to(&ginfo->rtg_info, ginfo->pevent, | ||
104 | record, &pid, &job, &ts); | ||
105 | if (match) { | ||
106 | update_pid(rtc_info, pid); | ||
107 | rtc_info->run_time = ts; | ||
108 | } | ||
109 | return match; | ||
110 | } | ||
111 | |||
112 | static int | ||
113 | try_completion(struct graph_info *ginfo, struct rt_cpu_info *rtc_info, | ||
114 | struct record *record, struct plot_info *info) | ||
115 | { | ||
116 | int pid, job, match; | ||
117 | unsigned long long ts; | ||
118 | |||
119 | match = rt_graph_check_task_completion(&ginfo->rtg_info, ginfo->pevent, | ||
120 | record, &pid, &job, &ts); | ||
121 | if (match) { | ||
122 | info->completion = TRUE; | ||
123 | info->ctime = ts; | ||
124 | } | ||
125 | return match; | ||
126 | } | ||
127 | |||
128 | static void do_plot_end(struct graph_info *ginfo, struct rt_cpu_info *rtc_info, | ||
129 | struct plot_info *info) | ||
130 | { | ||
131 | int pid; | ||
132 | struct record *record; | ||
133 | |||
134 | if (rtc_info->run_time && rtc_info->run_pid) { | ||
135 | info->box = TRUE; | ||
136 | info->bcolor = hash_pid(rtc_info->run_pid); | ||
137 | info->bfill = TRUE; | ||
138 | info->bstart = rtc_info->run_time; | ||
139 | info->bend = ginfo->view_end_time; | ||
140 | info->blabel = rtc_info->label; | ||
141 | rtc_info->fresh = FALSE; | ||
142 | } else if (rtc_info->fresh) { | ||
143 | record = next_sa_record(ginfo, rtc_info, | ||
144 | ginfo->view_end_time, | ||
145 | &pid); | ||
146 | if (record) { | ||
147 | update_pid(rtc_info, pid); | ||
148 | info->box = TRUE; | ||
149 | info->bcolor = hash_pid(pid); | ||
150 | info->bfill = TRUE; | ||
151 | info->blabel = rtc_info->label; | ||
152 | info->bstart = ginfo->view_start_time; | ||
153 | info->bend = ginfo->view_end_time; | ||
154 | rtc_info->fresh = FALSE; | ||
155 | } | ||
156 | free_record(record); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | static int rt_cpu_plot_match_time(struct graph_info *ginfo, | ||
161 | struct graph_plot *plot, | ||
162 | unsigned long long time) | ||
163 | { | ||
164 | int ret = 0; | ||
165 | struct rt_cpu_info *rtc_info = plot->private; | ||
166 | struct record = find_record(ginfo, rtc_info->cpu, time); | ||
167 | |||
168 | if (record && get_rts(ginfo, record) == time) | ||
169 | ret = 1; | ||
170 | free_record(record); | ||
171 | |||
172 | return ret; | ||
173 | } | ||
174 | |||
175 | static void rt_cpu_plot_start(struct graph_info *ginfo, struct graph_plot *plot, | ||
176 | unsigned long long time) | ||
177 | { | ||
178 | struct rt_cpu_info *rtc_info = plot->private; | ||
179 | |||
180 | rtc_info->run_time = time; | ||
181 | rtc_info->run_pid = 0; | ||
182 | rtc_info->fresh = TRUE; | ||
183 | } | ||
184 | |||
185 | static int rt_cpu_plot_event(struct graph_info *ginfo, struct graph_plot *plot, | ||
186 | struct record *record, struct plot_info *info) | ||
187 | { | ||
188 | int pid, eid, match; | ||
189 | unsigned long long ts; | ||
190 | struct rt_cpu_info *rtc_info = plot->private; | ||
191 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
192 | const char *comm; | ||
193 | |||
194 | if (!record) { | ||
195 | do_plot_end(ginfo, rtc_info, info); | ||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | if (record->cpu != rtc_info->cpu) | ||
200 | return 0; | ||
201 | |||
202 | match = try_switch_away(ginfo, rtc_info, record, info) || | ||
203 | try_switch_to(ginfo, rtc_info, record, info) || | ||
204 | try_completion(ginfo, rtc_info, record, info) || | ||
205 | trace_graph_check_sched_switch(ginfo, record, | ||
206 | &pid, &comm); | ||
207 | if (!match) { | ||
208 | rt_graph_check_any(rtg_info, ginfo->pevent, record, | ||
209 | &pid, &eid, &ts); | ||
210 | info->line = TRUE; | ||
211 | info->lcolor = hash_pid(pid); | ||
212 | info->ltime = ts; | ||
213 | } | ||
214 | return 1; | ||
215 | } | ||
216 | |||
217 | static int | ||
218 | rt_cpu_plot_display_last_event(struct graph_info *ginfo, struct graph_plot *plot, | ||
219 | struct trace_seq *s, unsigned long long time) | ||
220 | { | ||
221 | struct rt_cpu_info *rtc_info = plot->private; | ||
222 | struct event_format *event; | ||
223 | struct record *record; | ||
224 | unsigned long long offset; | ||
225 | int eid, cpu; | ||
226 | |||
227 | cpu = rtc_info->cpu; | ||
228 | record = tracecmd_peek_data(ginfo->handle, cpu); | ||
229 | if (record) | ||
230 | offset = record->offset; | ||
231 | |||
232 | record = find_record(ginfo, cpu, time); | ||
233 | |||
234 | if (offset) | ||
235 | tracecmd_set_cursor(ginfo->handle, cpu, offset); | ||
236 | if (!record) | ||
237 | return 0; | ||
238 | |||
239 | eid = pevent_data_type(ginfo->pevent, record); | ||
240 | event = pevent_data_event_from_type(ginfo->pevent, eid); | ||
241 | if (event) { | ||
242 | trace_seq_puts(s, event->name); | ||
243 | trace_seq_printf(s, "\n"); /* Doesn't work otherwise */ | ||
244 | } else | ||
245 | trace_seq_printf(s, "UNKNOWN EVENT %d\n", eid); | ||
246 | free_record(record); | ||
247 | |||
248 | return 1; | ||
249 | } | ||
250 | |||
251 | |||
252 | struct record* | ||
253 | rt_cpu_plot_find_record(struct graph_info *ginfo, struct graph_plot *plot, | ||
254 | unsigned long long time) | ||
255 | { | ||
256 | struct rt_cpu_info *rtc_info = plot->private; | ||
257 | return find_record(ginfo, rtc_info->cpu, time); | ||
258 | } | ||
259 | |||
260 | static int get_time_info(struct graph_info *ginfo, | ||
261 | struct rt_cpu_info *rtc_info, | ||
262 | unsigned long long time, | ||
263 | int *out_pid, int *out_job, | ||
264 | struct record **out_record) | ||
265 | { | ||
266 | struct record *record; | ||
267 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
268 | unsigned long long dull, max_ts; | ||
269 | int cpu, is_running, pid, job; | ||
270 | |||
271 | cpu = rtc_info->cpu; | ||
272 | *out_pid = *out_job = is_running = 0; | ||
273 | |||
274 | record = find_record(ginfo, cpu, time); | ||
275 | *out_record = record; | ||
276 | if (!record) | ||
277 | goto out; | ||
278 | |||
279 | max_ts = time + SEARCH_PERIODS * rtg_info->max_period; | ||
280 | do { | ||
281 | if (get_rts(ginfo, record) > max_ts) | ||
282 | break; | ||
283 | |||
284 | #define ARG rtg_info, ginfo->pevent, record, &pid, &job, &dull | ||
285 | if (rt_graph_check_switch_to(ARG)) { | ||
286 | /* Nothing is running */ | ||
287 | goto out; | ||
288 | } else if (rt_graph_check_switch_away(ARG)) { | ||
289 | is_running = 1; | ||
290 | *out_pid = pid; | ||
291 | *out_job = job; | ||
292 | goto out; | ||
293 | } | ||
294 | if (*out_record != record) | ||
295 | free_record(record); | ||
296 | #undef ARG | ||
297 | } while ((record = tracecmd_read_data(ginfo->handle, cpu))); | ||
298 | out: | ||
299 | if (*out_record != record) | ||
300 | free_record(record); | ||
301 | return is_running; | ||
302 | } | ||
303 | |||
304 | static int | ||
305 | rt_cpu_plot_display_info(struct graph_info *ginfo, struct graph_plot *plot, | ||
306 | struct trace_seq *s, unsigned long long time) | ||
307 | { | ||
308 | struct rt_cpu_info *rtc_info = plot->private; | ||
309 | unsigned long long msec, nsec, rts; | ||
310 | int pid, eid, job, is_running; | ||
311 | struct record *record; | ||
312 | struct event_format *event; | ||
313 | const char *comm; | ||
314 | |||
315 | is_running = get_time_info(ginfo, rtc_info, time, | ||
316 | &pid, &job, &record); | ||
317 | |||
318 | if (is_running) { | ||
319 | comm = pevent_data_comm_from_pid(ginfo->pevent, pid); | ||
320 | trace_seq_printf(s, "%s-%d:%d\n", comm, pid, job); | ||
321 | } | ||
322 | |||
323 | if (record) { | ||
324 | rts = get_rts(ginfo, record); | ||
325 | if (in_res(ginfo, rts, time)) { | ||
326 | eid = pevent_data_type(ginfo->pevent, record); | ||
327 | event = pevent_data_event_from_type(ginfo->pevent, eid); | ||
328 | if (event) { | ||
329 | trace_seq_putc(s, '\n'); | ||
330 | trace_seq_puts(s, event->name); | ||
331 | trace_seq_putc(s, '\n'); | ||
332 | pevent_event_info(s, event, record); | ||
333 | } else | ||
334 | trace_seq_printf(s, "\nUNKNOWN EVENT %d\n", eid); | ||
335 | } | ||
336 | free_record(record); | ||
337 | } | ||
338 | trace_seq_putc(s, '\n'); | ||
339 | nano_to_milli(time, &msec, &nsec); | ||
340 | trace_seq_printf(s, "%llu.%06llu ms CPU: %03d", | ||
341 | msec, nsec, rtc_info->cpu); | ||
342 | |||
343 | return 1; | ||
344 | } | ||
345 | |||
346 | static void rt_cpu_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot) | ||
347 | { | ||
348 | struct rt_cpu_info *rtc_info = plot->private; | ||
349 | |||
350 | trace_graph_plot_remove_all_recs(ginfo, plot); | ||
351 | free(rtc_info->label); | ||
352 | free(rtc_info); | ||
353 | } | ||
354 | |||
355 | |||
356 | static const struct plot_callbacks rt_cpu_cb = { | ||
357 | .start = rt_cpu_plot_start, | ||
358 | .destroy = rt_cpu_plot_destroy, | ||
359 | .plot_event = rt_cpu_plot_event, | ||
360 | .display_last_event = rt_cpu_plot_display_last_event, | ||
361 | .display_info = rt_cpu_plot_display_info, | ||
362 | .match_time = rt_cpu_plot_match_time, | ||
363 | .find_record = rt_cpu_plot_find_record, | ||
364 | }; | ||
365 | |||
366 | void rt_plot_cpus_update_callback(gboolean accept, | ||
367 | gboolean all_cpus, | ||
368 | guint64 *selected_cpu_mask, | ||
369 | gpointer data) | ||
370 | { | ||
371 | struct graph_info *ginfo = data; | ||
372 | struct rt_cpu_info *rtc_info; | ||
373 | struct graph_plot *plot; | ||
374 | gboolean old_all_cpus; | ||
375 | guint64 *old_cpu_mask; | ||
376 | int i; | ||
377 | |||
378 | if (!accept) | ||
379 | return; | ||
380 | |||
381 | /* Get the current status */ | ||
382 | rt_plot_cpus_plotted(ginfo, &old_all_cpus, &old_cpu_mask); | ||
383 | |||
384 | if (old_all_cpus == all_cpus || | ||
385 | (selected_cpu_mask && | ||
386 | cpus_equal(old_cpu_mask, selected_cpu_mask, ginfo->cpus))) { | ||
387 | /* Nothing to do */ | ||
388 | g_free(old_cpu_mask); | ||
389 | return; | ||
390 | } | ||
391 | |||
392 | if (!all_cpus) { | ||
393 | /* | ||
394 | * Remove any plots not selected. | ||
395 | * Go backwards, since removing a plot shifts the | ||
396 | * array from current position back. | ||
397 | */ | ||
398 | for (i = ginfo->plots - 1; i >= 0; i--) { | ||
399 | plot = ginfo->plot_array[i]; | ||
400 | if (plot->type != PLOT_TYPE_CPU) | ||
401 | continue; | ||
402 | rtc_info = plot->private; | ||
403 | if (!cpu_isset(selected_cpu_mask, rtc_info->cpu)) | ||
404 | trace_graph_plot_remove(ginfo, plot); | ||
405 | } | ||
406 | } | ||
407 | |||
408 | /* Now add any plots not set */ | ||
409 | for (i = 0; i < ginfo->cpus; i++) { | ||
410 | if (!all_cpus && !cpu_isset(selected_cpu_mask, i)) | ||
411 | continue; | ||
412 | if (cpu_isset(old_cpu_mask, i)) | ||
413 | continue; | ||
414 | rt_plot_cpu(ginfo, i); | ||
415 | } | ||
416 | |||
417 | g_free(old_cpu_mask); | ||
418 | |||
419 | trace_graph_refresh(ginfo); | ||
420 | } | ||
421 | |||
422 | void rt_plot_cpus_plotted(struct graph_info *ginfo, | ||
423 | gboolean *all_cpus, guint64 **cpu_mask) | ||
424 | { | ||
425 | struct rt_cpu_info *rtc_info; | ||
426 | struct graph_plot *plot; | ||
427 | int i; | ||
428 | |||
429 | *cpu_mask = g_new0(guint64, (ginfo->cpus >> 6) + 1); | ||
430 | g_assert(*cpu_mask); | ||
431 | |||
432 | for (i = 0; i < ginfo->plots; i++) { | ||
433 | plot = ginfo->plot_array[i]; | ||
434 | if (plot->type != PLOT_TYPE_RT_CPU) | ||
435 | continue; | ||
436 | rtc_info = plot->private; | ||
437 | cpu_set(*cpu_mask, rtc_info->cpu); | ||
438 | } | ||
439 | |||
440 | *all_cpus = cpu_weight(*cpu_mask, ginfo->cpus) == ginfo->cpus ? | ||
441 | TRUE : FALSE; | ||
442 | } | ||
443 | |||
444 | |||
445 | void rt_plot_cpu(struct graph_info *ginfo, int cpu) | ||
446 | { | ||
447 | struct rt_cpu_info *rtc_info; | ||
448 | struct graph_plot *plot; | ||
449 | char label[100]; | ||
450 | |||
451 | rtc_info = malloc_or_die(sizeof(*rtc_info)); | ||
452 | memset(rtc_info, 0, sizeof(*rtc_info)); | ||
453 | rtc_info->cpu = cpu; | ||
454 | rtc_info->label = malloc_or_die(LLABEL); | ||
455 | |||
456 | snprintf(label, 100, "*CPU %d", cpu); | ||
457 | |||
458 | plot = trace_graph_plot_append(ginfo, label, PLOT_TYPE_RT_CPU, | ||
459 | TIME_TYPE_RT, &rt_cpu_cb, rtc_info); | ||
460 | trace_graph_plot_add_all_recs(ginfo, plot); | ||
461 | } | ||
diff --git a/rt-plot-cpu.h b/rt-plot-cpu.h new file mode 100644 index 0000000..320bf53 --- /dev/null +++ b/rt-plot-cpu.h | |||
@@ -0,0 +1,20 @@ | |||
1 | #ifndef __RT_PLOT_CPU_H | ||
2 | #define __RT_PLOT_CPU_H | ||
3 | |||
4 | struct rt_cpu_info { | ||
5 | int cpu; | ||
6 | unsigned long long run_time; | ||
7 | int run_pid; | ||
8 | gboolean fresh; | ||
9 | char *label; | ||
10 | }; | ||
11 | |||
12 | void rt_plot_cpu(struct graph_info *ginfo, int cpu); | ||
13 | void rt_plot_cpus_plotted(struct graph_info *ginfo, | ||
14 | gboolean *all_cpus, guint64 **cpu_mask); | ||
15 | void rt_plot_cpus_update_callback(gboolean accept, | ||
16 | gboolean all_cpus, | ||
17 | guint64 *selected_cpu_mask, | ||
18 | gpointer data); | ||
19 | |||
20 | #endif | ||
diff --git a/rt-plot-task.c b/rt-plot-task.c index 48bcdde..f8d29ed 100644 --- a/rt-plot-task.c +++ b/rt-plot-task.c | |||
@@ -93,11 +93,8 @@ __find_record(struct graph_info *ginfo, gint pid, guint64 time, int display) | |||
93 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | 93 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; |
94 | 94 | ||
95 | set_cpus_to_rts(ginfo, time); | 95 | set_cpus_to_rts(ginfo, time); |
96 | do { | 96 | while ((record = tracecmd_read_next_data(ginfo->handle, &next_cpu))) { |
97 | free_record(record); | 97 | free_record(record); |
98 | record = tracecmd_read_next_data(ginfo->handle, &next_cpu); | ||
99 | if (!record) | ||
100 | return NULL; | ||
101 | match = record_matches_pid(ginfo, record, pid); | 98 | match = record_matches_pid(ginfo, record, pid); |
102 | if (display) { | 99 | if (display) { |
103 | eid = pevent_data_type(ginfo->pevent, record); | 100 | eid = pevent_data_type(ginfo->pevent, record); |
@@ -109,7 +106,9 @@ __find_record(struct graph_info *ginfo, gint pid, guint64 time, int display) | |||
109 | eid == rtg_info->task_release_id); | 106 | eid == rtg_info->task_release_id); |
110 | } | 107 | } |
111 | ignored = ignored && eid == ginfo->event_sched_switch_id; | 108 | ignored = ignored && eid == ginfo->event_sched_switch_id; |
112 | } while (!(get_rts(ginfo, record) > time && match && !ignored)); | 109 | if (get_rts(ginfo, record) >= time && match && !ignored) |
110 | break; | ||
111 | }; | ||
113 | 112 | ||
114 | return record; | 113 | return record; |
115 | } | 114 | } |
@@ -593,13 +592,6 @@ static int rt_task_plot_display_last_event(struct graph_info *ginfo, | |||
593 | return 1; | 592 | return 1; |
594 | } | 593 | } |
595 | 594 | ||
596 | static inline int in_res(struct graph_info *ginfo, unsigned long long time, | ||
597 | unsigned long target) | ||
598 | { | ||
599 | return time > target - 2/ginfo->resolution && | ||
600 | time < target + 2/ginfo->resolution; | ||
601 | } | ||
602 | |||
603 | static int rt_task_plot_display_info(struct graph_info *ginfo, | 595 | static int rt_task_plot_display_info(struct graph_info *ginfo, |
604 | struct graph_plot *plot, | 596 | struct graph_plot *plot, |
605 | struct trace_seq *s, | 597 | struct trace_seq *s, |
diff --git a/trace-graph.h b/trace-graph.h index ffd7cf5..33bdde2 100644 --- a/trace-graph.h +++ b/trace-graph.h | |||
@@ -433,5 +433,11 @@ static inline int hash_cpu(int cpu) | |||
433 | return trace_hash(cpu); | 433 | return trace_hash(cpu); |
434 | } | 434 | } |
435 | 435 | ||
436 | static inline int in_res(struct graph_info *ginfo, unsigned long long time, | ||
437 | unsigned long target) | ||
438 | { | ||
439 | return time > target - 2/ginfo->resolution && | ||
440 | time < target + 2/ginfo->resolution; | ||
441 | } | ||
436 | 442 | ||
437 | #endif /* _TRACE_GRAPH_H */ | 443 | #endif /* _TRACE_GRAPH_H */ |