3 #include "mono-counters.h"
5 typedef struct _MonoCounter MonoCounter;
14 static MonoCounter *counters = NULL;
15 static int valid_mask = 0;
16 static int set_mask = 0;
19 * mono_counters_enable:
20 * @section_mask: a mask listing the sections that will be displayed
22 * This is used to track which counters will be displayed.
25 mono_counters_enable (int section_mask)
27 valid_mask = section_mask & MONO_COUNTER_SECTION_MASK;
31 * mono_counters_register:
32 * @name: The name for this counters.
33 * @type: One of the possible MONO_COUNTER types, or MONO_COUNTER_CALLBACK for a function pointer.
34 * @addr: The address to register.
36 * Register addr as the address of a counter of type type.
37 * Note that @name must be a valid string at all times until
38 * mono_counters_dump () is called.
40 * It may be a function pointer if MONO_COUNTER_CALLBACK is specified:
41 * the function should return the value and take no arguments.
44 mono_counters_register (const char* name, int type, void *addr)
47 if (!(type & valid_mask))
49 counter = malloc (sizeof (MonoCounter));
61 MonoCounter *item = counters;
70 typedef int (*IntFunc) (void);
71 typedef guint (*UIntFunc) (void);
72 typedef gint64 (*LongFunc) (void);
73 typedef guint64 (*ULongFunc) (void);
74 typedef gssize (*PtrFunc) (void);
75 typedef double (*DoubleFunc) (void);
76 typedef char* (*StrFunc) (void);
78 #define ENTRY_FMT "%-36s: "
80 dump_counter (MonoCounter *counter, FILE *outfile) {
88 switch (counter->type & MONO_COUNTER_TYPE_MASK) {
89 case MONO_COUNTER_INT:
90 if (counter->type & MONO_COUNTER_CALLBACK)
91 intval = ((IntFunc)counter->addr) ();
93 intval = *(int*)counter->addr;
94 fprintf (outfile, ENTRY_FMT "%d\n", counter->name, intval);
96 case MONO_COUNTER_UINT:
97 if (counter->type & MONO_COUNTER_CALLBACK)
98 uintval = ((UIntFunc)counter->addr) ();
100 uintval = *(guint*)counter->addr;
101 fprintf (outfile, ENTRY_FMT "%u\n", counter->name, uintval);
103 case MONO_COUNTER_LONG:
104 if (counter->type & MONO_COUNTER_CALLBACK)
105 int64val = ((LongFunc)counter->addr) ();
107 int64val = *(gint64*)counter->addr;
108 fprintf (outfile, ENTRY_FMT "%lld\n", counter->name, int64val);
110 case MONO_COUNTER_ULONG:
111 if (counter->type & MONO_COUNTER_CALLBACK)
112 uint64val = ((ULongFunc)counter->addr) ();
114 uint64val = *(guint64*)counter->addr;
115 fprintf (outfile, ENTRY_FMT "%llu\n", counter->name, uint64val);
117 case MONO_COUNTER_WORD:
118 if (counter->type & MONO_COUNTER_CALLBACK)
119 wordval = ((PtrFunc)counter->addr) ();
121 wordval = *(gssize*)counter->addr;
122 #if SIZEOF_VOID_P == 8
123 fprintf (outfile, ENTRY_FMT "%lld\n", counter->name, (gint64)wordval);
125 fprintf (outfile, ENTRY_FMT "%d\n", counter->name, wordval);
128 case MONO_COUNTER_DOUBLE:
129 if (counter->type & MONO_COUNTER_CALLBACK)
130 dval = ((DoubleFunc)counter->addr) ();
132 dval = *(double*)counter->addr;
133 fprintf (outfile, ENTRY_FMT "%.2f\n", counter->name, dval);
135 case MONO_COUNTER_STRING:
136 if (counter->type & MONO_COUNTER_CALLBACK)
137 str = ((StrFunc)counter->addr) ();
139 str = *(char**)counter->addr;
140 fprintf (outfile, ENTRY_FMT "%s\n", counter->name, str);
146 section_names [][10] = {
155 mono_counters_dump_section (int section, FILE *outfile)
157 MonoCounter *counter = counters;
159 if (counter->type & section)
160 dump_counter (counter, outfile);
161 counter = counter->next;
166 * mono_counters_dump:
167 * @section_mask: The sections to dump counters for
168 * @outfile: a FILE to dump the results to
170 * Displays the counts of all the enabled counters registered.
173 mono_counters_dump (int section_mask, FILE *outfile)
176 section_mask &= valid_mask;
179 for (j = 0, i = MONO_COUNTER_JIT; i < MONO_COUNTER_LAST_SECTION; j++, i <<= 1) {
180 if ((section_mask & i) && (set_mask & i)) {
181 fprintf (outfile, "\n%s statistics\n", section_names [j]);
182 mono_counters_dump_section (i, outfile);
188 * mono_counters_cleanup:
190 * Perform any needed cleanup at process exit.
193 mono_counters_cleanup (void)
195 MonoCounter *counter = counters;
197 MonoCounter *tmp = counters;
198 counter = counter->next;