-
-
Save luhenry/9606786 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/mono/mini/driver.c b/mono/mini/driver.c | |
index d71c077..a15cdbc 100644 | |
--- a/mono/mini/driver.c | |
+++ b/mono/mini/driver.c | |
@@ -47,6 +47,7 @@ | |
#include <mono/metadata/coree.h> | |
#include <mono/metadata/attach.h> | |
#include "mono/utils/mono-counters.h" | |
+#include <mono/utils/mono-counters-internals.h> | |
#include "mono/utils/mono-hwcap.h" | |
#include "mini.h" | |
@@ -1382,7 +1383,7 @@ mono_jit_parse_options (int argc, char * argv[]) | |
opt->break_on_exc = TRUE; | |
} else if (strcmp (argv [i], "--stats") == 0) { | |
- mono_counters_enable (-1); | |
+ mono_counters_enable(1); | |
mono_stats.enabled = TRUE; | |
mono_jit_stats.enabled = TRUE; | |
} else if (strcmp (argv [i], "--break") == 0) { | |
@@ -1653,7 +1654,7 @@ mono_main (int argc, char* argv[]) | |
} else if (strcmp (argv [i], "--print-vtable") == 0) { | |
mono_print_vtable = TRUE; | |
} else if (strcmp (argv [i], "--stats") == 0) { | |
- mono_counters_enable (-1); | |
+ mono_counters_enable(1); | |
mono_stats.enabled = TRUE; | |
mono_jit_stats.enabled = TRUE; | |
#ifndef DISABLE_AOT | |
diff --git a/mono/mini/mini.c b/mono/mini/mini.c | |
index 616d696..2fa748f 100644 | |
--- a/mono/mini/mini.c | |
+++ b/mono/mini/mini.c | |
@@ -53,6 +53,7 @@ | |
#include <mono/utils/mono-math.h> | |
#include <mono/utils/mono-compiler.h> | |
#include <mono/utils/mono-counters.h> | |
+#include <mono/utils/mono-counters-internals.h> | |
#include <mono/utils/mono-logger-internal.h> | |
#include <mono/utils/mono-mmap.h> | |
#include <mono/utils/mono-path.h> | |
diff --git a/mono/utils/Makefile.am b/mono/utils/Makefile.am | |
index 1a4f6ac..2e7961c 100644 | |
--- a/mono/utils/Makefile.am | |
+++ b/mono/utils/Makefile.am | |
@@ -21,7 +21,7 @@ monoutils_sources = \ | |
dlmalloc.c \ | |
mono-counters.c \ | |
mono-compiler.h \ | |
- mono-counters-internals.h \ | |
+ mono-compiler-internals.h \ | |
mono-dl.c \ | |
mono-dl.h \ | |
mono-internal-hash.c \ | |
@@ -69,6 +69,7 @@ monoutils_sources = \ | |
monobitset.h \ | |
mono-codeman.h \ | |
mono-counters.h \ | |
+ mono-counters-internals.h \ | |
mono-digest.h \ | |
mono-error.h \ | |
mono-machine.h \ | |
@@ -111,7 +112,9 @@ monoutils_sources = \ | |
mono-hwcap.c \ | |
bsearch.h \ | |
bsearch.c \ | |
- mono-signal-handler.h | |
+ mono-signal-handler.h \ | |
+ mono-counters-agent.c \ | |
+ mono-counters-agent.h | |
arch_sources = | |
diff --git a/mono/utils/mono-counters-agent.c b/mono/utils/mono-counters-agent.c | |
new file mode 100644 | |
index 0000000..3738b81 | |
--- /dev/null | |
+++ b/mono/utils/mono-counters-agent.c | |
@@ -0,0 +1,283 @@ | |
+/* | |
+ * Copyright 2014 Xamarin Inc | |
+ */ | |
+ | |
+#include <stdlib.h> | |
+#include <stdio.h> | |
+#include <errno.h> | |
+#include <pthread.h> | |
+#include <glib.h> | |
+#include <unistd.h> | |
+#include <arpa/inet.h> | |
+#include <netinet/in.h> | |
+#include <netinet/tcp.h> | |
+#include <sys/socket.h> | |
+#include <sys/time.h> | |
+#include <sys/types.h> | |
+#include "mono-counters.h" | |
+#include "mono-counters-internals.h" | |
+#include "mono-counters-agent.h" | |
+#include "mono-time.h" | |
+ | |
+/** | |
+ * Protocol : | |
+ * | Headers | Values | Values | ... [Infinity] | |
+ * | |
+ * Headers : | |
+ * | Count (2) | Counter | Counter | ... [Count] | |
+ * | |
+ * Counter : | |
+ * | Category (4) | Name Length (8) | Name (Name Length) | Type (4) | Unit (4) | Variance (4) | Index (2) | | |
+ * | |
+ * Values : | |
+ * | Timestamp (8) | Value | Value | ... | -1 (2) | | |
+ * | |
+ * Value : | |
+ * | Index (2) | Size (2) | Value (Size) | | |
+ */ | |
+ | |
+typedef struct MonoCounterAgent { | |
+ MonoCounter* counter; | |
+ // MonoCounterAgent specific data : | |
+ void* value; | |
+ short index; | |
+} MonoCounterAgent; | |
+ | |
+static pthread_t agent_thread; | |
+ | |
+static GSList* counters; | |
+ | |
+static const gchar* inspector_ip; | |
+static int inspector_port; | |
+static int frequency; | |
+ | |
+static int enable; | |
+ | |
+int | |
+parse_counters_all (MonoCounter* counter, void** args) | |
+{ | |
+ static short index = 0; | |
+ | |
+ MonoCounterAgent* _counter = g_malloc(sizeof(MonoCounterAgent)); | |
+ _counter->counter = counter; | |
+ _counter->value = NULL; | |
+ _counter->index = index; | |
+ | |
+ counters = g_slist_append (counters, _counter); | |
+ index += 1; | |
+ | |
+ return 1; | |
+} | |
+ | |
+void | |
+parse_counters_names (const char *counters_names) | |
+{ | |
+ if (!counters_names) { | |
+ mono_counters_foreach(parse_counters_all, NULL); | |
+ } else { | |
+ short index = 0; | |
+ gchar **names = g_strsplit (counters_names, ";", -1), **ptr; | |
+ | |
+ for (ptr = names; *ptr; ++ptr) { | |
+ gchar **split = g_strsplit(*ptr, "/", 2); | |
+ if (!split[0] || !split[1]) | |
+ continue; //FIXME warning | |
+ | |
+ MonoCounterCategory category = mono_counters_category_name_to_id (split[0]); | |
+ MonoCounter* counter = mono_counters_get (category, split[1]); | |
+ if (!counter) | |
+ continue; // FIXME warning= | |
+ | |
+ MonoCounterAgent* _counter = g_malloc(sizeof(MonoCounterAgent)); | |
+ _counter->counter = counter; | |
+ _counter->index = index; | |
+ _counter->value = NULL; | |
+ | |
+ counters = g_slist_append (counters, _counter); | |
+ index += 1; | |
+ | |
+ g_strfreev(split); | |
+ } | |
+ g_strfreev (names); | |
+ } | |
+} | |
+ | |
+void | |
+parse_address (const char *address) | |
+{ | |
+ if (!address) { | |
+ inspector_ip = "127.0.0.1"; | |
+ inspector_port = 8888; | |
+ } else { | |
+ gchar **split = g_strsplit(address, ":", 2); | |
+ | |
+ inspector_ip = (split[0]) ? g_strdup(split[0]) : "127.0.0.1"; | |
+ inspector_port = (split[1]) ? strtol(split[1], NULL, 10) : 8888; | |
+ | |
+ g_strfreev(split); | |
+ } | |
+} | |
+ | |
+int | |
+write_buffer_to_socket(int socketfd, char* buffer, ssize_t size) | |
+{ | |
+ ssize_t left = size, sent; | |
+ | |
+ while (left > 0) { | |
+ sent = send(socketfd, buffer + (size - left), left, 0); | |
+ if (sent <= 0) | |
+ return 0; | |
+ left -= sent; | |
+ } | |
+ | |
+ return 1; | |
+} | |
+ | |
+static void* | |
+mono_counters_agent_sampling_thread (void* ptr) | |
+{ | |
+ int socketfd = 0; | |
+ struct sockaddr_in inspector_addr; | |
+ | |
+ if ((socketfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { | |
+ g_printf("mono-counters-agent | error with socket : %s", strerror(errno)); | |
+ return NULL; | |
+ } | |
+ | |
+ memset(&inspector_addr, 0, sizeof(inspector_addr)); | |
+ | |
+ inspector_addr.sin_family = AF_INET; | |
+ inspector_addr.sin_port = htons(inspector_port); | |
+ | |
+ if (!inet_pton(AF_INET, inspector_ip, &inspector_addr.sin_addr)) { | |
+ g_printf("mono-counters-agent | error with inet_pton : %s", strerror(errno)); | |
+ return NULL; | |
+ } | |
+ | |
+ if (connect(socketfd, (struct sockaddr*)&inspector_addr, sizeof(inspector_addr)) < 0) { | |
+ g_printf("mono-counters-agent | error with connect : %s", strerror(errno)); | |
+ return NULL; | |
+ } | |
+ | |
+ GSList* item; | |
+ char* buffer = g_malloc(8); | |
+ | |
+ short count = 0; | |
+ for (item = counters; item; item = item->next) | |
+ count += 1; | |
+ | |
+ if (!write_buffer_to_socket(socketfd, (char*)&count, 2)) | |
+ goto cleanup; | |
+ | |
+ for (item = counters; item; item = item->next) { | |
+ MonoCounterAgent* counter = item->data; | |
+ | |
+ int len = strlen(counter->counter->name); | |
+ | |
+ if (!write_buffer_to_socket(socketfd, (char*)&counter->counter->category, 4) | |
+ || !write_buffer_to_socket(socketfd, (char*)&len, 4) | |
+ || !write_buffer_to_socket(socketfd, (char*) counter->counter->name, len) | |
+ || !write_buffer_to_socket(socketfd, (char*)&counter->counter->type, 4) | |
+ || !write_buffer_to_socket(socketfd, (char*)&counter->counter->unit, 4) | |
+ || !write_buffer_to_socket(socketfd, (char*)&counter->counter->variance, 4) | |
+ || !write_buffer_to_socket(socketfd, (char*)&counter->index, 2)) | |
+ goto cleanup; // FIXME error | |
+ } | |
+ | |
+ while (enable) { | |
+ gint64 timestamp = mono_100ns_ticks(); | |
+ if (!write_buffer_to_socket(socketfd, (char*)×tamp, 8)) | |
+ goto cleanup; // FIXME error | |
+ | |
+ for (item = counters; item; item = item->next) { | |
+ MonoCounterAgent* counter = item->data; | |
+ | |
+ if (!counter) | |
+ continue; // FIXME warning | |
+ | |
+ int size = mono_counters_size(counter->counter); | |
+ if (size < 0) | |
+ goto cleanup; | |
+ | |
+ if (mono_counters_sample (counter->counter, buffer, size) != size) | |
+ goto cleanup; | |
+ | |
+ if (!counter->value) | |
+ counter->value = g_malloc(size); | |
+ else if (memcmp(counter->value, buffer, size) == 0) | |
+ continue; | |
+ | |
+ memcpy(counter->value, buffer, size); | |
+ | |
+ if (!write_buffer_to_socket(socketfd, (char*)&counter->index, 2) | |
+ || !write_buffer_to_socket(socketfd, (char*)&size, 2) | |
+ || !write_buffer_to_socket(socketfd, (char*) buffer, size)) | |
+ goto cleanup; | |
+ } | |
+ | |
+ short end = -1; | |
+ if (!write_buffer_to_socket(socketfd, (char*)&end, 2)) | |
+ goto cleanup; // FIXME error | |
+ | |
+ usleep (1000000 / frequency); | |
+ } | |
+ | |
+cleanup: | |
+ close(socketfd); | |
+ g_free(buffer); | |
+ | |
+ return NULL; | |
+} | |
+ | |
+void | |
+parse_configuration (const gchar* configuration) | |
+{ | |
+ const char *counters_names = NULL; | |
+ const char *address = NULL; | |
+ | |
+ if (configuration == NULL) | |
+ return; | |
+ | |
+ gchar **opts = g_strsplit (configuration, ",", -1), **ptr; | |
+ for (ptr = opts; *ptr; ++ptr) { | |
+ const char *opt = *ptr; | |
+ if (g_str_has_prefix (opt, "address=")) { | |
+ opt = strchr (opt, '=') + 1; | |
+ address = g_strdup(opt); | |
+ } else if (g_str_has_prefix (opt, "counters=")) { | |
+ opt = strchr (opt, '=') + 1; | |
+ counters_names = g_strdup(opt); | |
+ } else if (g_str_has_prefix (opt, "frequency=")) { | |
+ opt = strchr (opt, '=') + 1; | |
+ frequency = strtol (opt, NULL, 10); | |
+ } | |
+ } | |
+ | |
+ parse_counters_names(counters_names); | |
+ parse_address(address); | |
+ | |
+ g_free((void*)counters_names); | |
+ g_free((void*)address); | |
+ g_strfreev(opts); | |
+} | |
+ | |
+void | |
+mono_counters_agent_start (void) | |
+{ | |
+ enable = 1; | |
+ | |
+ // counters = g_slist_alloc(); | |
+ | |
+ parse_configuration(g_getenv ("MONO_PERF_AGENT")); | |
+ pthread_create(&agent_thread, NULL, mono_counters_agent_sampling_thread, NULL); | |
+} | |
+ | |
+void | |
+mono_counters_agent_stop(void) | |
+{ | |
+ enable = 0; | |
+ | |
+ g_slist_free(counters); | |
+ | |
+ pthread_join(agent_thread, NULL); | |
+} | |
\ No newline at end of file | |
diff --git a/mono/utils/mono-counters-agent.h b/mono/utils/mono-counters-agent.h | |
new file mode 100644 | |
index 0000000..c7e275a | |
--- /dev/null | |
+++ b/mono/utils/mono-counters-agent.h | |
@@ -0,0 +1,7 @@ | |
+#ifndef __MONO_COUNTERS_AGENTS_H__ | |
+#define __MONO_COUNTERS_AGENTS_H__ | |
+ | |
+MONO_API void mono_counters_agent_start (void); | |
+MONO_API void mono_counters_agent_stop (void); | |
+ | |
+#endif /* __MONO_COUNTERS_AGENTS_H__ */ | |
\ No newline at end of file | |
diff --git a/mono/utils/mono-counters-internals.h b/mono/utils/mono-counters-internals.h | |
index a8cbfef..ceed67e 100644 | |
--- a/mono/utils/mono-counters-internals.h | |
+++ b/mono/utils/mono-counters-internals.h | |
@@ -1,6 +1,7 @@ | |
#ifndef __MONO_COUNTERS_INTERNALS_H__ | |
#define __MONO_COUNTERS_INTERNALS_H__ | |
+#include <glib.h> | |
#include "mono-counters.h" | |
#include "mono-compiler.h" | |
@@ -41,7 +42,16 @@ typedef enum { | |
MONO_COUNTER_UNIT_VARIABLE, /* This counter value can be anything on each sampling */ | |
} MonoCounterVariance; | |
-typedef struct _MonoCounter MonoCounter; | |
+typedef struct _MonoCounter { | |
+ const char* name; | |
+ void* addr; | |
+ MonoCounterType type; | |
+ MonoCounterCategory category; | |
+ MonoCounterUnit unit; | |
+ MonoCounterVariance variance; | |
+ gboolean is_callback; | |
+} MonoCounter; | |
+ | |
/* | |
Limitations: | |
The old-style string counter type won't work as they cannot be safely sampled during execution. | |
@@ -68,5 +78,16 @@ mono_counters_register_full (MonoCounterCategory category, const char *name, Mon | |
#define mono_counters_new_long_const(cat,name,unit,value) do { gint64 *__ptr = mono_counters_new(cat,name,MONO_COUNTER_TYPE_INT,unit,variance); *__ptr = value; } while (0) | |
#define mono_counters_new_double_const(cat,name,unit,value) do { double *__ptr = mono_counters_new(cat,name,MONO_COUNTER_TYPE_INT,unit,variance); *__ptr = value; } while (0) | |
+MONO_API MonoCounter* mono_counters_get (MonoCounterCategory category, const char* name); | |
+MONO_API int mono_counters_sample (MonoCounter* counter, char* buffer, int size); | |
+MONO_API int mono_counters_size (MonoCounter* counter); | |
+ | |
+MONO_API MonoCounterCategory mono_counters_category_name_to_id (const char* name); | |
+MONO_API const char* mono_counters_category_id_to_name (MonoCounterCategory id); | |
+ | |
+typedef int (*MonoCountersForeachFunc) (MonoCounter* counter, void** args); | |
+MONO_API void mono_counters_foreach(MonoCountersForeachFunc func, void** args); | |
+ | |
+ | |
+#endif /* __MONO_COUNTERS_INTERNALS_H__ */ | |
-#endif | |
diff --git a/mono/utils/mono-counters.c b/mono/utils/mono-counters.c | |
index 9f22e01..3c04c56 100644 | |
--- a/mono/utils/mono-counters.c | |
+++ b/mono/utils/mono-counters.c | |
@@ -5,21 +5,12 @@ | |
#include <stdlib.h> | |
#include <glib.h> | |
+#include "mono-counters.h" | |
#include "mono-counters-internals.h" | |
-struct _MonoCounter { | |
- MonoCounter *next; | |
- const char *name; | |
- void *addr; | |
- MonoCounterType type; | |
- MonoCounterCategory category; | |
- MonoCounterUnit unit; | |
- MonoCounterVariance variance; | |
- gboolean is_callback; | |
-}; | |
+static GSList *counters = NULL; | |
-static MonoCounter *counters = NULL; | |
-static int valid_mask = 0; | |
+static int enable = 0; | |
/** | |
* mono_counters_enable: | |
@@ -28,9 +19,9 @@ static int valid_mask = 0; | |
* This is used to track which counters will be displayed. | |
*/ | |
void | |
-mono_counters_enable (int section_mask) | |
+mono_counters_enable (int mask) | |
{ | |
- valid_mask = section_mask & MONO_COUNTER_SECTION_MASK; | |
+ enable = 1; | |
} | |
MonoCounter* | |
@@ -46,17 +37,9 @@ mono_counters_register_full (MonoCounterCategory category, const char *name, Mon | |
counter->category = category; | |
counter->unit = unit; | |
counter->variance = variance; | |
- counter->next = NULL; | |
- | |
- /* Append */ | |
- if (counters) { | |
- MonoCounter *item = counters; | |
- while (item->next) | |
- item = item->next; | |
- item->next = counter; | |
- } else { | |
- counters = counter; | |
- } | |
+ | |
+ counters = g_slist_append (counters, counter); | |
+ | |
return counter; | |
} | |
@@ -153,6 +136,8 @@ mono_counters_register (const char* name, int type, void *addr) | |
counter = mono_counters_register_full (cat, name, counter_type, unit, MONO_COUNTER_UNIT_VARIABLE, addr); | |
if (counter && type & MONO_COUNTER_CALLBACK) | |
counter->is_callback = TRUE; | |
+ else | |
+ counter->is_callback = FALSE; | |
} | |
@@ -220,11 +205,12 @@ section_names [][10] = { | |
static void | |
mono_counters_dump_category (MonoCounterCategory category, FILE *outfile) | |
{ | |
- MonoCounter *counter = counters; | |
- while (counter) { | |
+ GSList *item = counters; | |
+ while (item) { | |
+ MonoCounter* counter = item->data; | |
if (counter->category == category) | |
dump_counter (counter, outfile); | |
- counter = counter->next; | |
+ item = item->next; | |
} | |
} | |
@@ -238,15 +224,15 @@ mono_counters_dump_category (MonoCounterCategory category, FILE *outfile) | |
void | |
mono_counters_dump (int section_mask, FILE *outfile) | |
{ | |
+ if (!enable) | |
+ return; | |
+ | |
int i, j; | |
- section_mask &= valid_mask; | |
if (!counters) | |
return; | |
for (j = 0, i = MONO_COUNTER_JIT; i < MONO_COUNTER_LAST_SECTION; j++, i <<= 1) { | |
- if ((section_mask & i)) { | |
- fprintf (outfile, "\n%s statistics\n", section_names [j]); | |
- mono_counters_dump_category (section_to_category (i), outfile); | |
- } | |
+ fprintf (outfile, "\n%s statistics\n", section_names [j]); | |
+ mono_counters_dump_category (section_to_category (i), outfile); | |
} | |
fflush (outfile); | |
@@ -260,13 +246,8 @@ mono_counters_dump (int section_mask, FILE *outfile) | |
void | |
mono_counters_cleanup (void) | |
{ | |
- MonoCounter *counter = counters; | |
- counters = NULL; | |
- while (counter) { | |
- MonoCounter *tmp = counter; | |
- counter = counter->next; | |
- free (tmp); | |
- } | |
+ if (counters) | |
+ g_slist_free(counters); | |
} | |
static MonoResourceCallback limit_reached = NULL; | |
@@ -334,4 +315,162 @@ mono_runtime_resource_set_callback (MonoResourceCallback callback) | |
limit_reached = callback; | |
} | |
+MonoCounter* | |
+mono_counters_get (MonoCounterCategory category, const char* name) | |
+{ | |
+ if (!counters) | |
+ return NULL; | |
+ | |
+ GSList* item = counters; | |
+ | |
+ do { | |
+ MonoCounter* counter = item->data; | |
+ if (counter->category == category && strcmp(counter->name, name) ==0) | |
+ return counter; | |
+ } while ((item = item->next)); | |
+ | |
+ return NULL; | |
+} | |
+ | |
+int | |
+mono_counters_sample (MonoCounter* counter, char* buffer, int size) | |
+{ | |
+ switch (counter->type) { | |
+ case MONO_COUNTER_TYPE_INT: | |
+#if SIZEOF_VOID_P == 4 | |
+ case MONO_COUNTER_TYPE_WORD: | |
+#endif | |
+ if (size < 4) | |
+ return -1; | |
+ | |
+ if (counter->is_callback) { | |
+ int value = ((IntFunc)counter->addr) (); | |
+ memcpy(buffer, &value, 4); | |
+ } else { | |
+ memcpy(buffer, counter->addr, 4); | |
+ } | |
+ | |
+ return 4; | |
+ case MONO_COUNTER_TYPE_LONG: | |
+#if SIZEOF_VOID_P == 8 | |
+ case MONO_COUNTER_TYPE_WORD: | |
+#endif | |
+ if (size < 8) | |
+ return -1; | |
+ | |
+ if (counter->is_callback) { | |
+ long value = ((LongFunc)counter->addr) (); | |
+ memcpy(buffer, &value, 8); | |
+ } else { | |
+ memcpy(buffer, counter->addr, 8); | |
+ } | |
+ | |
+ return 8; | |
+ case MONO_COUNTER_DOUBLE: | |
+ if (size < 8) | |
+ return -1; | |
+ | |
+ if (counter->is_callback) { | |
+ double value = ((DoubleFunc)counter->addr) (); | |
+ memcpy(buffer, &value, 8); | |
+ } else { | |
+ memcpy(buffer, counter->addr, 8); | |
+ } | |
+ | |
+ return 8; | |
+ } | |
+ | |
+ return -1; | |
+} | |
+ | |
+int | |
+mono_counters_size (MonoCounter* counter) | |
+{ | |
+ switch (counter->type) { | |
+ case MONO_COUNTER_TYPE_INT: | |
+#if SIZEOF_VOID_P == 4 | |
+ case MONO_COUNTER_TYPE_WORD: | |
+#endif | |
+ return 4; | |
+ case MONO_COUNTER_TYPE_LONG: | |
+#if SIZEOF_VOID_P == 8 | |
+ case MONO_COUNTER_TYPE_WORD: | |
+#endif | |
+ case MONO_COUNTER_DOUBLE: | |
+ return 8; | |
+ } | |
+ | |
+ return -1; | |
+} | |
+ | |
+MonoCounterCategory | |
+mono_counters_category_name_to_id (const char* name) | |
+{ | |
+ if (strcmp("Mono JIT", name) == 0) { | |
+ return MONO_COUNTER_CAT_JIT; | |
+ } else if (strcmp("Mono GC", name) == 0) { | |
+ return MONO_COUNTER_CAT_GC; | |
+ } else if (strcmp("Mono Metadata", name) == 0) { | |
+ return MONO_COUNTER_CAT_METADATA; | |
+ } else if (strcmp("Mono Generics", name) == 0) { | |
+ return MONO_COUNTER_CAT_GENERICS; | |
+ } else if (strcmp("Mono Security", name) == 0) { | |
+ return MONO_COUNTER_CAT_SECURITY; | |
+ } else if (strcmp("Mono Remoting", name) == 0) { | |
+ return MONO_COUNTER_CAT_REMOTING; | |
+ } else if (strcmp("Mono EXC", name) == 0) { | |
+ return MONO_COUNTER_CAT_EXC; | |
+ } else if (strcmp("Mono Thread", name) == 0) { | |
+ return MONO_COUNTER_CAT_THREAD; | |
+ } else if (strcmp("Mono Threadpool", name) == 0) { | |
+ return MONO_COUNTER_CAT_THREADPOOL; | |
+ } else if (strcmp("Mono IO", name) == 0) { | |
+ return MONO_COUNTER_CAT_IO; | |
+ } else { | |
+ return -1; | |
+ } | |
+} | |
+ | |
+const char* | |
+mono_counters_category_id_to_name (MonoCounterCategory id) | |
+{ | |
+ switch (id) { | |
+ case MONO_COUNTER_CAT_JIT: | |
+ return "Mono JIT"; | |
+ case MONO_COUNTER_CAT_GC: | |
+ return "Mono GC"; | |
+ case MONO_COUNTER_CAT_METADATA: | |
+ return "Mono Metadata"; | |
+ case MONO_COUNTER_CAT_GENERICS: | |
+ return "Mono Generics"; | |
+ case MONO_COUNTER_CAT_SECURITY: | |
+ return "Mono Security"; | |
+ case MONO_COUNTER_CAT_REMOTING: | |
+ return "Mono Remoting"; | |
+ case MONO_COUNTER_CAT_EXC: | |
+ return "Mono EXC"; | |
+ case MONO_COUNTER_CAT_THREAD: | |
+ return "Mono Thread"; | |
+ case MONO_COUNTER_CAT_THREADPOOL: | |
+ return "Mono Threadpool"; | |
+ case MONO_COUNTER_CAT_IO: | |
+ return "Mono IO"; | |
+ default: | |
+ return NULL; | |
+ } | |
+} | |
+ | |
+void | |
+mono_counters_foreach(MonoCountersForeachFunc func, void** args) | |
+{ | |
+ if (!counters) | |
+ return; | |
+ | |
+ GSList* item = counters; | |
+ | |
+ do { | |
+ if (!func(item->data, args)) | |
+ return; | |
+ } while ((item = item->next)); | |
+} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment