diff options
| author | Jonathan <hermanjl@hermanjl-Aspire-5553G.(none)> | 2012-03-07 14:48:41 -0500 |
|---|---|---|
| committer | Jonathan <hermanjl@hermanjl-Aspire-5553G.(none)> | 2012-03-07 14:48:41 -0500 |
| commit | 9d7a60b58d0fbb48a5e3a0d868aa7e4ccd6ba24b (patch) | |
| tree | 201a7c2f9e78a7dc8d7630a2fd3879a4f4894802 | |
| parent | 3a8b1a1467696a093f740bd99e7a5a01f5e61b2d (diff) | |
rt-graph: event names added to plot, fixed logic for finding current job
| -rw-r--r-- | rt-graph.c | 2 | ||||
| -rw-r--r-- | rt-plot-task.c | 133 | ||||
| -rw-r--r-- | rt-plot-task.h | 2 | ||||
| -rw-r--r-- | trace-graph.c | 2 |
4 files changed, 108 insertions, 31 deletions
| @@ -1,7 +1,7 @@ | |||
| 1 | #include "rt-graph.h" | 1 | #include "rt-graph.h" |
| 2 | #include "trace-hash.h" | 2 | #include "trace-hash.h" |
| 3 | 3 | ||
| 4 | #define DEBUG_LEVEL 4 | 4 | #define DEBUG_LEVEL 0 |
| 5 | #if DEBUG_LEVEL > 0 | 5 | #if DEBUG_LEVEL > 0 |
| 6 | #define dprintf(l, x...) \ | 6 | #define dprintf(l, x...) \ |
| 7 | do { \ | 7 | do { \ |
diff --git a/rt-plot-task.c b/rt-plot-task.c index 0b10d91..c549e3c 100644 --- a/rt-plot-task.c +++ b/rt-plot-task.c | |||
| @@ -150,16 +150,18 @@ find_record(struct graph_info *ginfo, gint pid, guint64 time) | |||
| 150 | /* | 150 | /* |
| 151 | * Update current job in @rtt_info, ensuring monotonic increase | 151 | * Update current job in @rtt_info, ensuring monotonic increase |
| 152 | */ | 152 | */ |
| 153 | static void update_job(struct rt_task_info *rtt_info, int job) | 153 | static int update_job(struct rt_task_info *rtt_info, int job) |
| 154 | { | 154 | { |
| 155 | if (job < rtt_info->last_job) { | 155 | if (job < rtt_info->last_job) { |
| 156 | die("Inconsistent job state for %d:%d -> %d\n", | 156 | printf("Inconsistent job state for %d:%d -> %d\n", |
| 157 | rtt_info->base.pid, rtt_info->last_job, job); | 157 | rtt_info->base.pid, rtt_info->last_job, job); |
| 158 | return 0; | ||
| 158 | } else if (job > rtt_info->last_job) { | 159 | } else if (job > rtt_info->last_job) { |
| 159 | rtt_info->last_job = job; | 160 | rtt_info->last_job = job; |
| 160 | snprintf(rtt_info->label, LLABEL, "%d:%d", | 161 | snprintf(rtt_info->label, LLABEL, "%d:%d", |
| 161 | rtt_info->base.pid, rtt_info->last_job); | 162 | rtt_info->base.pid, rtt_info->last_job); |
| 162 | } | 163 | } |
| 164 | return 1; | ||
| 163 | } | 165 | } |
| 164 | 166 | ||
| 165 | static int try_param(struct graph_info *ginfo, struct rt_task_info *rtt_info, | 167 | static int try_param(struct graph_info *ginfo, struct rt_task_info *rtt_info, |
| @@ -343,6 +345,55 @@ static int try_other(struct graph_info *ginfo, struct rt_task_info *rtt_info, | |||
| 343 | } | 345 | } |
| 344 | 346 | ||
| 345 | /* | 347 | /* |
| 348 | * Find the information for the last release of @rtt_info on @cpu before @time. | ||
| 349 | * @min_ts: the minimum time stamp to parse | ||
| 350 | * | ||
| 351 | * Returns release record and @out_job, @out_release, and @out_deadline if a | ||
| 352 | * release was found after @mints matching @time. | ||
| 353 | */ | ||
| 354 | static struct record* | ||
| 355 | get_previous_release(struct graph_info *ginfo, struct rt_task_info *rtt_info, | ||
| 356 | int cpu, | ||
| 357 | unsigned long long min_ts, unsigned long long time, | ||
| 358 | int *out_job, | ||
| 359 | unsigned long long *out_release, | ||
| 360 | unsigned long long *out_deadline) | ||
| 361 | { | ||
| 362 | int pid, job, match; | ||
| 363 | unsigned long long release, deadline; | ||
| 364 | struct record *last_record, *record, *ret = NULL; | ||
| 365 | struct rt_graph_info *rtg_info = &ginfo->rtinfo; | ||
| 366 | |||
| 367 | last_record = tracecmd_peek_data(ginfo->handle, cpu); | ||
| 368 | if (!last_record) | ||
| 369 | return NULL; | ||
| 370 | last_record->ref_count++; | ||
| 371 | |||
| 372 | while ((record = tracecmd_read_prev(ginfo->handle, last_record))) { | ||
| 373 | if (record->ts < min_ts) { | ||
| 374 | free_record(record); | ||
| 375 | goto out; | ||
| 376 | } | ||
| 377 | match = rt_graph_check_task_release(rtg_info, ginfo->pevent, | ||
| 378 | record, &pid, &job, | ||
| 379 | &release, &deadline); | ||
| 380 | free_record(last_record); | ||
| 381 | last_record = record; | ||
| 382 | if (match && (pid == rtt_info->base.pid) && release <= time) { | ||
| 383 | ret = record; | ||
| 384 | last_record = NULL; | ||
| 385 | *out_job = job; | ||
| 386 | *out_release = release; | ||
| 387 | *out_deadline = deadline; | ||
| 388 | break; | ||
| 389 | } | ||
| 390 | }; | ||
| 391 | out: | ||
| 392 | free_record(last_record); | ||
| 393 | return ret; | ||
| 394 | } | ||
| 395 | |||
| 396 | /* | ||
| 346 | * Return information for @time, returns @job, @release, @deadline, and @record. | 397 | * Return information for @time, returns @job, @release, @deadline, and @record. |
| 347 | * @job: Job number at this time | 398 | * @job: Job number at this time |
| 348 | * @release: Job's release time | 399 | * @release: Job's release time |
| @@ -358,40 +409,36 @@ static int get_time_info(struct graph_info *ginfo, | |||
| 358 | struct record **out_record) | 409 | struct record **out_record) |
| 359 | 410 | ||
| 360 | { | 411 | { |
| 361 | int pid, job, match, found_job = 0; | 412 | int cpu, job; |
| 362 | unsigned long long release, deadline; | 413 | unsigned long long release, deadline, min_ts; |
| 363 | struct record *record, *last_record; | 414 | struct record *record; |
| 364 | struct rt_graph_info *rtg_info = &ginfo->rtinfo; | 415 | struct offset_cache *offsets; |
| 365 | 416 | ||
| 366 | /* Seek CPUs to first record after this time */ | 417 | /* Seek CPUs to first record after this time */ |
| 367 | *out_record = find_record(ginfo, rtt_info->base.pid, time); | 418 | *out_record = find_record(ginfo, rtt_info->base.pid, time); |
| 368 | if (!*out_record) | 419 | if (!*out_record) |
| 369 | goto out; | 420 | goto out; |
| 370 | 421 | ||
| 371 | last_record = *out_record; | 422 | min_ts = time - 2*rtt_info->wcet; |
| 372 | last_record->ref_count++; | 423 | *out_job = 0; |
| 373 | 424 | *out_release = 0; | |
| 374 | /* Read backwards for a release record */ | 425 | *out_deadline = 0; |
| 375 | while ((record = tracecmd_read_prev(ginfo->handle, last_record))) { | 426 | |
| 376 | match = rt_graph_check_task_release(rtg_info, ginfo->pevent, | 427 | offsets = save_offsets(ginfo); |
| 377 | record, &pid, &job, | 428 | for (cpu = 0; cpu < ginfo->cpus; cpu++) { |
| 378 | &release, &deadline); | 429 | record = get_previous_release(ginfo, rtt_info, cpu, min_ts, |
| 379 | free_record(last_record); | 430 | time, &job, &release, &deadline); |
| 380 | last_record = record; | 431 | if (record && record->ts > min_ts) { |
| 381 | if (match && pid == rtt_info->base.pid && release <= time) { | 432 | *out_job = job; |
| 382 | found_job = TRUE; | 433 | *out_release = release; |
| 383 | break; | 434 | *out_deadline = deadline; |
| 435 | min_ts = record->ts; | ||
| 384 | } | 436 | } |
| 437 | free_record(record); | ||
| 385 | } | 438 | } |
| 386 | free_record(last_record); | 439 | restore_offsets(ginfo, offsets); |
| 387 | |||
| 388 | if (found_job) { | ||
| 389 | *out_job = job; | ||
| 390 | *out_release = release; | ||
| 391 | *out_deadline = deadline; | ||
| 392 | } | ||
| 393 | out: | 440 | out: |
| 394 | return found_job; | 441 | return (min_ts == 0); |
| 395 | } | 442 | } |
| 396 | 443 | ||
| 397 | static inline int in_res(struct graph_info *ginfo, unsigned long long time, | 444 | static inline int in_res(struct graph_info *ginfo, unsigned long long time, |
| @@ -476,6 +523,7 @@ static void rt_task_plot_start(struct graph_info *ginfo, struct graph_plot *plot | |||
| 476 | static void rt_task_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot) | 523 | static void rt_task_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot) |
| 477 | { | 524 | { |
| 478 | struct rt_task_info *rtt_info = plot->private; | 525 | struct rt_task_info *rtt_info = plot->private; |
| 526 | printf("Destroying plot %d\n", rtt_info->base.pid); | ||
| 479 | free(rtt_info->label); | 527 | free(rtt_info->label); |
| 480 | task_plot_destroy(ginfo, plot); | 528 | task_plot_destroy(ginfo, plot); |
| 481 | } | 529 | } |
| @@ -485,8 +533,28 @@ static int rt_task_plot_display_last_event(struct graph_info *ginfo, | |||
| 485 | struct trace_seq *s, | 533 | struct trace_seq *s, |
| 486 | unsigned long long time) | 534 | unsigned long long time) |
| 487 | { | 535 | { |
| 488 | trace_seq_printf(s, "Displaying last event at %llu\n", | 536 | int eid; |
| 489 | time); | 537 | struct event_format *event; |
| 538 | struct record *record; | ||
| 539 | struct offset_cache *offsets; | ||
| 540 | struct rt_task_info *rtt_info = plot->private; | ||
| 541 | |||
| 542 | offsets = save_offsets(ginfo); | ||
| 543 | record = find_record(ginfo, rtt_info->base.pid, time); | ||
| 544 | restore_offsets(ginfo, offsets); | ||
| 545 | if (!record) | ||
| 546 | return 0; | ||
| 547 | |||
| 548 | eid = pevent_data_type(ginfo->pevent, record); | ||
| 549 | event = pevent_data_event_from_type(ginfo->pevent, eid); | ||
| 550 | if (event) | ||
| 551 | trace_seq_puts(s, event->name); | ||
| 552 | else | ||
| 553 | trace_seq_printf(s, "UNKNOWN EVENT %d\n", eid); | ||
| 554 | trace_seq_putc(s, '\n'); | ||
| 555 | trace_seq_printf(s, "CPU %d\n", record->cpu); | ||
| 556 | free_record(record); | ||
| 557 | |||
| 490 | return 1; | 558 | return 1; |
| 491 | } | 559 | } |
| 492 | 560 | ||
| @@ -502,9 +570,12 @@ static int rt_task_plot_display_info(struct graph_info *ginfo, | |||
| 502 | unsigned long usec, sec; | 570 | unsigned long usec, sec; |
| 503 | unsigned long long release, deadline, rts; | 571 | unsigned long long release, deadline, rts; |
| 504 | struct rt_task_info *rtt_info = plot->private; | 572 | struct rt_task_info *rtt_info = plot->private; |
| 573 | struct offset_cache *offsets; | ||
| 505 | 574 | ||
| 575 | offsets = save_offsets(ginfo); | ||
| 506 | get_time_info(ginfo, rtt_info, time, | 576 | get_time_info(ginfo, rtt_info, time, |
| 507 | &job, &release, &deadline, &record); | 577 | &job, &release, &deadline, &record); |
| 578 | restore_offsets(ginfo, offsets); | ||
| 508 | show_rel = in_res(ginfo, release, time); | 579 | show_rel = in_res(ginfo, release, time); |
| 509 | show_dead = in_res(ginfo, deadline, time); | 580 | show_dead = in_res(ginfo, deadline, time); |
| 510 | 581 | ||
| @@ -586,6 +657,10 @@ void rt_plot_task(struct graph_info *ginfo, int pid, int pos) | |||
| 586 | len = strlen(comm) + 100; | 657 | len = strlen(comm) + 100; |
| 587 | label = malloc_or_die(len); | 658 | label = malloc_or_die(len); |
| 588 | snprintf(label, len, "*%s-%d", comm, pid); | 659 | snprintf(label, len, "*%s-%d", comm, pid); |
| 660 | rtt_info->pid = pid; | ||
| 661 | |||
| 662 | printf("Created plot for %s-%d / %d %p\n", comm, pid, rtt_info->base.pid, | ||
| 663 | rtt_info); | ||
| 589 | 664 | ||
| 590 | plot = trace_graph_plot_insert(ginfo, pos, label, PLOT_TYPE_TASK, | 665 | plot = trace_graph_plot_insert(ginfo, pos, label, PLOT_TYPE_TASK, |
| 591 | &rt_task_cb, rtt_info); | 666 | &rt_task_cb, rtt_info); |
diff --git a/rt-plot-task.h b/rt-plot-task.h index 40971fd..7cdda67 100644 --- a/rt-plot-task.h +++ b/rt-plot-task.h | |||
| @@ -6,6 +6,8 @@ | |||
| 6 | struct rt_task_info { | 6 | struct rt_task_info { |
| 7 | struct task_plot_info base; | 7 | struct task_plot_info base; |
| 8 | 8 | ||
| 9 | int pid; | ||
| 10 | |||
| 9 | unsigned long long wcet; | 11 | unsigned long long wcet; |
| 10 | unsigned long long period; | 12 | unsigned long long period; |
| 11 | 13 | ||
diff --git a/trace-graph.c b/trace-graph.c index f94ad50..2cf7a95 100644 --- a/trace-graph.c +++ b/trace-graph.c | |||
| @@ -76,7 +76,7 @@ static int convert_time_to_x(struct graph_info *ginfo, guint64 time) | |||
| 76 | return 0; | 76 | return 0; |
| 77 | return (time - ginfo->view_start_time) * ginfo->resolution; | 77 | return (time - ginfo->view_start_time) * ginfo->resolution; |
| 78 | } | 78 | } |
| 79 | r | 79 | |
| 80 | static guint64 convert_x_to_time(struct graph_info *ginfo, gint x) | 80 | static guint64 convert_x_to_time(struct graph_info *ginfo, gint x) |
| 81 | { | 81 | { |
| 82 | double d = x; | 82 | double d = x; |
