2010-03-03 Gonzalo Paniagua Javier <gonzalo@novell.com>
[mono.git] / mono / utils / mono-counters.c
index a12a528d6d14550007c9c918149515bf038a9fe6..af77254c9bdae864b9ed6c79c046503fc448d95e 100644 (file)
@@ -13,6 +13,7 @@ struct _MonoCounter {
 
 static MonoCounter *counters = NULL;
 static int valid_mask = 0;
+static int set_mask = 0;
 
 /**
  * mono_counters_enable:
@@ -33,6 +34,8 @@ mono_counters_enable (int section_mask)
  * @addr: The address to register.
  *
  * Register addr as the address of a counter of type type.
+ * Note that @name must be a valid string at all times until
+ * mono_counters_dump () is called.
  *
  * It may be a function pointer if MONO_COUNTER_CALLBACK is specified:
  * the function should return the value and take no arguments.
@@ -51,6 +54,8 @@ mono_counters_register (const char* name, int type, void *addr)
        counter->addr = addr;
        counter->next = NULL;
 
+       set_mask |= type;
+
        /* Append */
        if (counters) {
                MonoCounter *item = counters;
@@ -70,7 +75,7 @@ typedef gssize (*PtrFunc) (void);
 typedef double (*DoubleFunc) (void);
 typedef char* (*StrFunc) (void);
 
-#define ENTRY_FMT "%-24s : "
+#define ENTRY_FMT "%-36s: "
 static void
 dump_counter (MonoCounter *counter, FILE *outfile) {
        int intval;
@@ -100,14 +105,14 @@ dump_counter (MonoCounter *counter, FILE *outfile) {
                      int64val = ((LongFunc)counter->addr) ();
              else
                      int64val = *(gint64*)counter->addr;
-             fprintf (outfile, ENTRY_FMT "%lld\n", counter->name, int64val);
+             fprintf (outfile, ENTRY_FMT "%lld\n", counter->name, (long long)int64val);
              break;
        case MONO_COUNTER_ULONG:
              if (counter->type & MONO_COUNTER_CALLBACK)
                      uint64val = ((ULongFunc)counter->addr) ();
              else
                      uint64val = *(guint64*)counter->addr;
-             fprintf (outfile, ENTRY_FMT "%llu\n", counter->name, uint64val);
+             fprintf (outfile, ENTRY_FMT "%llu\n", counter->name, (unsigned long long)uint64val);
              break;
        case MONO_COUNTER_WORD:
              if (counter->type & MONO_COUNTER_CALLBACK)
@@ -117,7 +122,7 @@ dump_counter (MonoCounter *counter, FILE *outfile) {
 #if SIZEOF_VOID_P == 8
              fprintf (outfile, ENTRY_FMT "%lld\n", counter->name, (gint64)wordval);
 #else
-             fprintf (outfile, ENTRY_FMT "%d\n", counter->name, wordval);
+             fprintf (outfile, ENTRY_FMT "%d\n", counter->name, (gint)wordval);
 #endif
              break;
        case MONO_COUNTER_DOUBLE:
@@ -172,10 +177,27 @@ mono_counters_dump (int section_mask, FILE *outfile)
        if (!counters)
                return;
        for (j = 0, i = MONO_COUNTER_JIT; i < MONO_COUNTER_LAST_SECTION; j++, i <<= 1) {
-               if (section_mask & i) {
+               if ((section_mask & i) && (set_mask & i)) {
                        fprintf (outfile, "\n%s statistics\n", section_names [j]);
                        mono_counters_dump_section (i, outfile);
                }
        }
 }
 
+/**
+ * mono_counters_cleanup:
+ *
+ * Perform any needed cleanup at process exit.
+ */
+void
+mono_counters_cleanup (void)
+{
+       MonoCounter *counter = counters;
+       while (counter) {
+               MonoCounter *tmp = counters;
+               counter = counter->next;
+               free (tmp);
+       }
+       counters = NULL;
+}
+