overlay: Couple wait begin/end events together to fix accounting
authorChris Wilson <chris@chris-wilson.co.uk>
Sat, 17 Aug 2013 21:22:21 +0000 (22:22 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Sat, 17 Aug 2013 21:22:21 +0000 (22:22 +0100)
Since the events may be processed out of order (due to per-cpu
ringbuffers) we need to be careful to associated wait pairs in order to
compute the correct elapsed time.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
overlay/gpu-perf.c
overlay/gpu-perf.h
overlay/overlay.c

index ef17090..653148b 100644 (file)
@@ -229,12 +229,21 @@ static int wait_begin(struct gpu_perf *gp, const void *event)
 {
        const struct sample_event *sample = event;
        struct gpu_perf_comm *comm;
+       struct gpu_perf_wait *wait;
 
        comm = lookup_comm(gp, sample->pid);
        if (comm == NULL)
                return 0;
 
-       comm->wait_begin = sample->time;
+       wait = malloc(sizeof(*wait));
+       if (wait == NULL)
+               return 0;
+
+       wait->seqno = sample->raw[3];
+       wait->time = sample->time;
+       wait->next = comm->wait;
+       comm->wait = wait;
+
        return 0;
 }
 
@@ -242,12 +251,22 @@ static int wait_end(struct gpu_perf *gp, const void *event)
 {
        const struct sample_event *sample = event;
        struct gpu_perf_comm *comm;
+       struct gpu_perf_wait *wait, **prev;
 
        comm = lookup_comm(gp, sample->pid);
        if (comm == NULL)
                return 0;
 
-       comm->wait_time += sample->time - comm->wait_begin;
+       for (prev = &comm->wait; (wait = *prev) != NULL; prev = &wait->next) {
+               if (wait->seqno != sample->raw[3])
+                       continue;
+
+               comm->wait_time += sample->time - wait->time;
+               *prev = wait->next;
+               free(wait);
+               return 1;
+       }
+
        return 0;
 }
 
index 5c3e242..476bbaa 100644 (file)
@@ -14,6 +14,11 @@ struct gpu_perf {
        int flip_complete;
        struct gpu_perf_comm {
                struct gpu_perf_comm *next;
+               struct gpu_perf_wait {
+                       struct gpu_perf_wait *next;
+                       uint32_t seqno;
+                       uint64_t time;
+               } *wait;
                char name[256];
                pid_t pid;
                int nr_requests[4];
index b41dfc4..bd327ab 100644 (file)
@@ -266,10 +266,21 @@ static void show_gpu_perf(struct overlay_context *ctx, struct overlay_gpu_perf *
                        need_comma = true;
                }
                if (comm->wait_time) {
-                       if (comm->wait_time > 100) {
+                       buf[0] = '\0';
+                       if (comm->wait_time > 1000*1000) {
+                               sprintf(buf, "%s %.1f ms waiting",
+                                       need_comma ? "," : "",
+                                       comm->wait_time / (1000*1000.));
+                       } else if (comm->wait_time > 100) {
                                sprintf(buf, "%s %.1f us waiting",
                                        need_comma ? "," : "",
                                        comm->wait_time / 1000.);
+                       } else {
+                               sprintf(buf, "%s %.0f ns waiting",
+                                       need_comma ? "," : "",
+                                       (double)comm->wait_time);
+                       }
+                       if (buf[0] != '\0') {
                                cairo_show_text(ctx->cr, buf);
                                need_comma = true;
                        }