svn path=/trunk/mono/; revision=64203
[mono-project.git] / mono / utils / mono-counters.c
bloba12a528d6d14550007c9c918149515bf038a9fe6
1 #include <stdlib.h>
2 #include <glib.h>
3 #include "mono-counters.h"
5 typedef struct _MonoCounter MonoCounter;
7 struct _MonoCounter {
8 MonoCounter *next;
9 const char *name;
10 void *addr;
11 int type;
14 static MonoCounter *counters = NULL;
15 static int valid_mask = 0;
17 /**
18 * mono_counters_enable:
19 * @section_mask: a mask listing the sections that will be displayed
21 * This is used to track which counters will be displayed.
23 void
24 mono_counters_enable (int section_mask)
26 valid_mask = section_mask & MONO_COUNTER_SECTION_MASK;
29 /**
30 * mono_counters_register:
31 * @name: The name for this counters.
32 * @type: One of the possible MONO_COUNTER types, or MONO_COUNTER_CALLBACK for a function pointer.
33 * @addr: The address to register.
35 * Register addr as the address of a counter of type type.
37 * It may be a function pointer if MONO_COUNTER_CALLBACK is specified:
38 * the function should return the value and take no arguments.
40 void
41 mono_counters_register (const char* name, int type, void *addr)
43 MonoCounter *counter;
44 if (!(type & valid_mask))
45 return;
46 counter = malloc (sizeof (MonoCounter));
47 if (!counter)
48 return;
49 counter->name = name;
50 counter->type = type;
51 counter->addr = addr;
52 counter->next = NULL;
54 /* Append */
55 if (counters) {
56 MonoCounter *item = counters;
57 while (item->next)
58 item = item->next;
59 item->next = counter;
60 } else {
61 counters = counter;
65 typedef int (*IntFunc) (void);
66 typedef guint (*UIntFunc) (void);
67 typedef gint64 (*LongFunc) (void);
68 typedef guint64 (*ULongFunc) (void);
69 typedef gssize (*PtrFunc) (void);
70 typedef double (*DoubleFunc) (void);
71 typedef char* (*StrFunc) (void);
73 #define ENTRY_FMT "%-24s : "
74 static void
75 dump_counter (MonoCounter *counter, FILE *outfile) {
76 int intval;
77 guint uintval;
78 gint64 int64val;
79 guint64 uint64val;
80 gssize wordval;
81 double dval;
82 const char *str;
83 switch (counter->type & MONO_COUNTER_TYPE_MASK) {
84 case MONO_COUNTER_INT:
85 if (counter->type & MONO_COUNTER_CALLBACK)
86 intval = ((IntFunc)counter->addr) ();
87 else
88 intval = *(int*)counter->addr;
89 fprintf (outfile, ENTRY_FMT "%d\n", counter->name, intval);
90 break;
91 case MONO_COUNTER_UINT:
92 if (counter->type & MONO_COUNTER_CALLBACK)
93 uintval = ((UIntFunc)counter->addr) ();
94 else
95 uintval = *(guint*)counter->addr;
96 fprintf (outfile, ENTRY_FMT "%u\n", counter->name, uintval);
97 break;
98 case MONO_COUNTER_LONG:
99 if (counter->type & MONO_COUNTER_CALLBACK)
100 int64val = ((LongFunc)counter->addr) ();
101 else
102 int64val = *(gint64*)counter->addr;
103 fprintf (outfile, ENTRY_FMT "%lld\n", counter->name, int64val);
104 break;
105 case MONO_COUNTER_ULONG:
106 if (counter->type & MONO_COUNTER_CALLBACK)
107 uint64val = ((ULongFunc)counter->addr) ();
108 else
109 uint64val = *(guint64*)counter->addr;
110 fprintf (outfile, ENTRY_FMT "%llu\n", counter->name, uint64val);
111 break;
112 case MONO_COUNTER_WORD:
113 if (counter->type & MONO_COUNTER_CALLBACK)
114 wordval = ((PtrFunc)counter->addr) ();
115 else
116 wordval = *(gssize*)counter->addr;
117 #if SIZEOF_VOID_P == 8
118 fprintf (outfile, ENTRY_FMT "%lld\n", counter->name, (gint64)wordval);
119 #else
120 fprintf (outfile, ENTRY_FMT "%d\n", counter->name, wordval);
121 #endif
122 break;
123 case MONO_COUNTER_DOUBLE:
124 if (counter->type & MONO_COUNTER_CALLBACK)
125 dval = ((DoubleFunc)counter->addr) ();
126 else
127 dval = *(double*)counter->addr;
128 fprintf (outfile, ENTRY_FMT "%.2f\n", counter->name, dval);
129 break;
130 case MONO_COUNTER_STRING:
131 if (counter->type & MONO_COUNTER_CALLBACK)
132 str = ((StrFunc)counter->addr) ();
133 else
134 str = *(char**)counter->addr;
135 fprintf (outfile, ENTRY_FMT "%s\n", counter->name, str);
136 break;
140 static const char
141 section_names [][10] = {
142 "JIT",
143 "GC",
144 "Metadata",
145 "Generics",
146 "Security"
149 static void
150 mono_counters_dump_section (int section, FILE *outfile)
152 MonoCounter *counter = counters;
153 while (counter) {
154 if (counter->type & section)
155 dump_counter (counter, outfile);
156 counter = counter->next;
161 * mono_counters_dump:
162 * @section_mask: The sections to dump counters for
163 * @outfile: a FILE to dump the results to
165 * Displays the counts of all the enabled counters registered.
167 void
168 mono_counters_dump (int section_mask, FILE *outfile)
170 int i, j;
171 section_mask &= valid_mask;
172 if (!counters)
173 return;
174 for (j = 0, i = MONO_COUNTER_JIT; i < MONO_COUNTER_LAST_SECTION; j++, i <<= 1) {
175 if (section_mask & i) {
176 fprintf (outfile, "\n%s statistics\n", section_names [j]);
177 mono_counters_dump_section (i, outfile);