summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorEmilio G. Cota <cota@braap.org>2018-08-16 23:14:40 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2018-08-23 18:46:25 +0200
commit0a22777c7120deafcfc5d680227293145f6f062c (patch)
tree96d35b446e41bebe76ca18061700920328341f78
parentfe9959a275fc7b4744e49201a390627b3adda597 (diff)
downloadfocaccia-qemu-0a22777c7120deafcfc5d680227293145f6f062c.tar.gz
focaccia-qemu-0a22777c7120deafcfc5d680227293145f6f062c.zip
qsp: add sort_by option to qsp_report
Signed-off-by: Emilio G. Cota <cota@braap.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--include/qemu/qsp.h8
-rw-r--r--util/qsp.c33
2 files changed, 34 insertions, 7 deletions
diff --git a/include/qemu/qsp.h b/include/qemu/qsp.h
index 9c2bb60ff0..209480b687 100644
--- a/include/qemu/qsp.h
+++ b/include/qemu/qsp.h
@@ -13,7 +13,13 @@
 
 #include "qemu/fprintf-fn.h"
 
-void qsp_report(FILE *f, fprintf_function cpu_fprintf, size_t max);
+enum QSPSortBy {
+    QSP_SORT_BY_TOTAL_WAIT_TIME,
+    QSP_SORT_BY_AVG_WAIT_TIME,
+};
+
+void qsp_report(FILE *f, fprintf_function cpu_fprintf, size_t max,
+                enum QSPSortBy sort_by);
 
 bool qsp_is_enabled(void);
 void qsp_enable(void);
diff --git a/util/qsp.c b/util/qsp.c
index c5fce4b442..80dbd4c368 100644
--- a/util/qsp.c
+++ b/util/qsp.c
@@ -429,14 +429,34 @@ static gint qsp_tree_cmp(gconstpointer ap, gconstpointer bp, gpointer up)
 {
     const QSPEntry *a = ap;
     const QSPEntry *b = bp;
+    enum QSPSortBy sort_by = *(enum QSPSortBy *)up;
     const QSPCallSite *ca;
     const QSPCallSite *cb;
 
-    if (a->ns > b->ns) {
-        return -1;
-    } else if (a->ns < b->ns) {
-        return 1;
+    switch (sort_by) {
+    case QSP_SORT_BY_TOTAL_WAIT_TIME:
+        if (a->ns > b->ns) {
+            return -1;
+        } else if (a->ns < b->ns) {
+            return 1;
+        }
+        break;
+    case QSP_SORT_BY_AVG_WAIT_TIME:
+    {
+        double avg_a = a->n_acqs ? a->ns / a->n_acqs : 0;
+        double avg_b = b->n_acqs ? b->ns / b->n_acqs : 0;
+
+        if (avg_a > avg_b) {
+            return -1;
+        } else if (avg_a < avg_b) {
+            return 1;
+        }
+        break;
     }
+    default:
+        g_assert_not_reached();
+    }
+
     ca = a->callsite;
     cb = b->callsite;
     /* Break the tie with the object's address */
@@ -613,9 +633,10 @@ static void report_destroy(QSPReport *rep)
     g_free(rep->entries);
 }
 
-void qsp_report(FILE *f, fprintf_function cpu_fprintf, size_t max)
+void qsp_report(FILE *f, fprintf_function cpu_fprintf, size_t max,
+                enum QSPSortBy sort_by)
 {
-    GTree *tree = g_tree_new_full(qsp_tree_cmp, NULL, g_free, NULL);
+    GTree *tree = g_tree_new_full(qsp_tree_cmp, &sort_by, g_free, NULL);
     QSPReport rep;
 
     qsp_init();