[counters] Add mono_counters_foreach API.
[mono.git] / mono / utils / mono-counters.c
index 75062898784e96afda217f3ebcf8705f6c7fc23e..e60520a8bed500ffc05b50544b9ac09651a3e6b3 100644 (file)
@@ -7,8 +7,6 @@
 #include <glib.h>
 #include "mono-counters.h"
 
-typedef struct _MonoCounter MonoCounter;
-
 struct _MonoCounter {
        MonoCounter *next;
        const char *name;
@@ -20,6 +18,18 @@ static MonoCounter *counters = NULL;
 static int valid_mask = 0;
 static int set_mask = 0;
 
+static int
+mono_counter_get_variance (MonoCounter *counter)
+{
+       return counter->type & MONO_COUNTER_VARIANCE_MASK;
+}
+
+static int
+mono_counter_get_unit (MonoCounter *counter)
+{
+       return counter->type & MONO_COUNTER_UNIT_MASK;
+}
+
 /**
  * mono_counters_enable:
  * @section_mask: a mask listing the sections that will be displayed
@@ -110,7 +120,10 @@ dump_counter (MonoCounter *counter, FILE *outfile) {
                      int64val = ((LongFunc)counter->addr) ();
              else
                      int64val = *(gint64*)counter->addr;
-             fprintf (outfile, ENTRY_FMT "%lld\n", counter->name, (long long)int64val);
+             if (mono_counter_get_unit (counter) == MONO_COUNTER_TIME)
+                     fprintf (outfile, ENTRY_FMT "%.2f ms\n", counter->name, (double)int64val / 10000.0);
+             else
+                     fprintf (outfile, ENTRY_FMT "%lld\n", counter->name, (long long)int64val);
              break;
        case MONO_COUNTER_ULONG:
              if (counter->type & MONO_COUNTER_CALLBACK)
@@ -124,11 +137,7 @@ dump_counter (MonoCounter *counter, FILE *outfile) {
                      wordval = ((PtrFunc)counter->addr) ();
              else
                      wordval = *(gssize*)counter->addr;
-#if SIZEOF_VOID_P == 8
-             fprintf (outfile, ENTRY_FMT "%lld\n", counter->name, (gint64)wordval);
-#else
-             fprintf (outfile, ENTRY_FMT "%d\n", counter->name, (gint)wordval);
-#endif
+             fprintf (outfile, ENTRY_FMT "%zd\n", counter->name, (gint64)wordval);
              break;
        case MONO_COUNTER_DOUBLE:
              if (counter->type & MONO_COUNTER_CALLBACK)
@@ -144,13 +153,17 @@ dump_counter (MonoCounter *counter, FILE *outfile) {
                      str = *(char**)counter->addr;
              fprintf (outfile, ENTRY_FMT "%s\n", counter->name, str);
              break;
-       case MONO_COUNTER_TIME_INTERVAL:
-           if (counter->type & MONO_COUNTER_CALLBACK)
-                     int64val = ((LongFunc)counter->addr) ();
-           else
-                     int64val = *(gint64*)counter->addr;
-           fprintf (outfile, ENTRY_FMT "%.2f ms\n", counter->name, (double)int64val / 1000.0);
-           break;
+       }
+}
+
+void
+mono_counters_foreach (CountersEnumCallback cb, gpointer user_data)
+{
+       MonoCounter *counter;
+
+       for (counter = counters; counter; counter = counter->next) {
+               if (!cb (counter, user_data))
+                       return;
        }
 }
 
@@ -160,7 +173,9 @@ section_names [][10] = {
        "GC",
        "Metadata",
        "Generics",
-       "Security"
+       "Security",
+       "Runtime",
+       "System",
 };
 
 static void
@@ -168,7 +183,7 @@ mono_counters_dump_section (int section, FILE *outfile)
 {
        MonoCounter *counter = counters;
        while (counter) {
-               if (counter->type & section)
+               if (counter->type & section && mono_counter_get_variance (counter) == MONO_COUNTER_MONOTONIC)
                        dump_counter (counter, outfile);
                counter = counter->next;
        }