-/*
- * mono-perfcounters.c
+/**
+ * \file
*
* Performance counters support.
*
#include <mach/message.h>
#include <mach/mach_host.h>
#include <mach/host_info.h>
+#include <sys/sysctl.h>
#endif
-#if defined (__NetBSD__) || defined (__APPLE__)
+#if defined (__NetBSD__)
+#include <sys/param.h>
#include <sys/sysctl.h>
+#include <sys/vmmeter.h>
#endif
#include "metadata/mono-perfcounters.h"
#include "metadata/appdomain.h"
#include "utils/mono-networkinterfaces.h"
#include "utils/mono-error-internals.h"
#include "utils/atomic.h"
-#include <mono/io-layer/io-layer.h>
/* map of CounterSample.cs */
struct _MonoCounterSample {
int mib[2] = {
CTL_HW,
#ifdef __NetBSD__
- HW_PHYSMEM
+ HW_PHYSMEM64
#else
HW_MEMSIZE
#endif
#elif defined (__NetBSD__)
struct vmtotal vm_total;
guint64 page_size;
- int mib [2];
+ int mib[2];
size_t len;
+ mib[0] = CTL_VM;
+ mib[1] = VM_METER;
- mib = {
- CTL_VM,
-#if defined (VM_METER)
- VM_METER
-#else
- VM_TOTAL
-#endif
- };
len = sizeof (vm_total);
sysctl (mib, 2, &vm_total, &len, NULL, 0);
- mib = {
- CTL_HW,
- HW_PAGESIZE
- };
+ mib[0] = CTL_HW;
+ mib[1] = HW_PAGESIZE;
+
len = sizeof (page_size);
- sysctl (mib, 2, &page_size, &len, NULL, 0
+ sysctl (mib, 2, &page_size, &len, NULL, 0);
- return ((guint64) value.t_free * page_size) / 1024;
+ return ((guint64) vm_total.t_free * page_size) / 1024;
#elif defined (__APPLE__)
mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
mach_port_t host = mach_host_self();
}
static int
-id_from_string (MonoString *instance, gboolean is_process)
+id_from_string (const gchar *id_str, gboolean is_process)
{
- MonoError error;
int id = -1;
- if (mono_string_length (instance)) {
- char *id_str = mono_string_to_utf8_checked (instance, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (strcmp("", id_str) != 0) {
char *end;
id = strtol (id_str, &end, 0);
if (end == id_str && !is_process)
id = -1;
- g_free (id_str);
}
return id;
}
}
static void*
-cpu_get_impl (MonoString* counter, MonoString* instance, int *type, MonoBoolean *custom)
+cpu_get_impl (MonoString* counter, const gchar* instance, int *type, MonoBoolean *custom)
{
int id = id_from_string (instance, FALSE) << 5;
const CounterDesc *cdesc;
}
static void*
-network_get_impl (MonoString* counter, MonoString* instance, int *type, MonoBoolean *custom)
+network_get_impl (MonoString* counter, const gchar* instance, int *type, MonoBoolean *custom)
{
- MonoError error;
const CounterDesc *cdesc;
NetworkVtableArg *narg;
ImplVtable *vtable;
*custom = FALSE;
if ((cdesc = get_counter_in_category (&predef_categories [CATEGORY_NETWORK], counter))) {
- instance_name = mono_string_to_utf8_checked (instance, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ instance_name = g_strdup (instance);
narg = g_new0 (NetworkVtableArg, 1);
narg->id = cdesc->id;
narg->name = instance_name;
}
static void*
-process_get_impl (MonoString* counter, MonoString* instance, int *type, MonoBoolean *custom)
+process_get_impl (MonoString* counter, const gchar* instance, int *type, MonoBoolean *custom)
{
int id = id_from_string (instance, TRUE) << 5;
const CounterDesc *cdesc;
}
static void*
-mono_mem_get_impl (MonoString* counter, MonoString* instance, int *type, MonoBoolean *custom)
+mono_mem_get_impl (MonoString* counter, const gchar* instance, int *type, MonoBoolean *custom)
{
const CounterDesc *cdesc;
*custom = FALSE;
}
static ImplVtable*
-predef_vtable (void *arg, MonoString *instance)
+predef_vtable (void *arg, const gchar *pids)
{
- MonoError error;
MonoSharedArea *area;
PredefVtable *vtable;
- char *pids = mono_string_to_utf8_checked (instance, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
int pid;
pid = atoi (pids);
- g_free (pids);
area = load_sarea_for_pid (pid);
if (!area)
return NULL;
}
static void*
-predef_writable_get_impl (int cat, MonoString* counter, MonoString* instance, int *type, MonoBoolean *custom)
+predef_writable_get_impl (int cat, MonoString* counter, const gchar *instance, int *type, MonoBoolean *custom)
{
const CounterDesc *cdesc;
*custom = TRUE;
if ((cdesc = get_counter_in_category (&predef_categories [cat], counter))) {
*type = cdesc->type;
- if (instance == NULL || mono_string_compare_ascii (instance, "") == 0)
+ if (instance == NULL || strcmp (instance, "") == 0)
return create_vtable (GINT_TO_POINTER ((cdesc->id << 16) | cat), predef_writable_counter, predef_writable_update);
else
return predef_vtable (GINT_TO_POINTER ((cdesc->id << 16) | cat), instance);
}
static void*
-custom_get_impl (SharedCategory *cat, MonoString* counter, MonoString* instance, int *type)
+custom_get_impl (SharedCategory *cat, MonoString *counter, MonoString* instance, int *type, MonoError *error)
{
- MonoError error;
SharedCounter *scounter;
SharedInstance* inst;
char *name;
+ error_init (error);
scounter = find_custom_counter (cat, counter);
if (!scounter)
return NULL;
+ name = mono_string_to_utf8_checked (counter, error);
+ return_val_if_nok (error, NULL);
*type = simple_type_to_type [scounter->type];
- name = mono_string_to_utf8_checked (counter, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
inst = custom_get_instance (cat, scounter, name);
g_free (name);
if (!inst)
mono_perfcounter_get_impl (MonoString* category, MonoString* counter, MonoString* instance,
MonoString* machine, int *type, MonoBoolean *custom)
{
+ MonoError error;
const CategoryDesc *cdesc;
+ void *result = NULL;
/* no support for counters on other machines */
if (mono_string_compare_ascii (machine, "."))
return NULL;
if (!scat)
return NULL;
*custom = TRUE;
- return custom_get_impl (scat, counter, instance, type);
+ result = custom_get_impl (scat, counter, instance, type, &error);
+ if (mono_error_set_pending_exception (&error))
+ return NULL;
+ return result;
}
+ gchar *c_instance = mono_string_to_utf8_checked (instance, &error);
+ if (mono_error_set_pending_exception (&error))
+ return NULL;
switch (cdesc->id) {
case CATEGORY_CPU:
- return cpu_get_impl (counter, instance, type, custom);
+ result = cpu_get_impl (counter, c_instance, type, custom);
+ break;
case CATEGORY_PROC:
- return process_get_impl (counter, instance, type, custom);
+ result = process_get_impl (counter, c_instance, type, custom);
+ break;
case CATEGORY_MONO_MEM:
- return mono_mem_get_impl (counter, instance, type, custom);
+ result = mono_mem_get_impl (counter, c_instance, type, custom);
+ break;
case CATEGORY_NETWORK:
- return network_get_impl (counter, instance, type, custom);
+ result = network_get_impl (counter, c_instance, type, custom);
+ break;
case CATEGORY_JIT:
case CATEGORY_EXC:
case CATEGORY_GC:
case CATEGORY_SECURITY:
case CATEGORY_ASPNET:
case CATEGORY_THREADPOOL:
- return predef_writable_get_impl (cdesc->id, counter, instance, type, custom);
+ result = predef_writable_get_impl (cdesc->id, counter, c_instance, type, custom);
+ break;
}
- return NULL;
+ g_free (c_instance);
+ return result;
}
MonoBoolean
return TRUE;
}
+/* this is an icall */
MonoString*
mono_perfcounter_category_help (MonoString *category, MonoString *machine)
{
+ MonoError error;
+ MonoString *result = NULL;
const CategoryDesc *cdesc;
+ error_init (&error);
/* no support for counters on other machines */
if (mono_string_compare_ascii (machine, "."))
return NULL;
SharedCategory *scat = find_custom_category (category);
if (!scat)
return NULL;
- return mono_string_new (mono_domain_get (), custom_category_help (scat));
+ result = mono_string_new_checked (mono_domain_get (), custom_category_help (scat), &error);
+ if (mono_error_set_pending_exception (&error))
+ return NULL;
+ return result;
}
- return mono_string_new (mono_domain_get (), cdesc->help);
+ result = mono_string_new_checked (mono_domain_get (), cdesc->help, &error);
+ if (mono_error_set_pending_exception (&error))
+ return NULL;
+ return result;
}
/*
if (!scat)
return FALSE;
name = mono_string_to_utf8_checked (instance, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (mono_error_set_pending_exception (&error))
+ return FALSE;
sinst = find_custom_instance (scat, name);
g_free (name);
if (sinst)
return FALSE;
}
+/* this is an icall */
MonoArray*
mono_perfcounter_category_names (MonoString *machine)
{
for (i = 0; i < NUM_CATEGORIES; ++i) {
const CategoryDesc *cdesc = &predef_categories [i];
- mono_array_setref (res, i, mono_string_new (domain, cdesc->name));
+ MonoString *name = mono_string_new_checked (domain, cdesc->name, &error);
+ if (!is_ok (&error))
+ goto leave;
+ mono_array_setref (res, i, name);
}
for (tmp = custom_categories; tmp; tmp = tmp->next) {
SharedCategory *scat = (SharedCategory *)tmp->data;
- mono_array_setref (res, i, mono_string_new (domain, scat->name));
+ MonoString *name = mono_string_new_checked (domain, scat->name, &error);
+ if (!is_ok (&error))
+ goto leave;
+ mono_array_setref (res, i, name);
i++;
}
+leave:
perfctr_unlock ();
g_slist_free (custom_categories);
+ mono_error_set_pending_exception (&error);
return res;
}
return NULL;
for (i = cdesc->first_counter; i < cdesc [1].first_counter; ++i) {
const CounterDesc *desc = &predef_counters [i];
- mono_array_setref (res, i - cdesc->first_counter, mono_string_new (domain, desc->name));
+ MonoString *name = mono_string_new_checked (domain, desc->name, &error);
+ if (mono_error_set_pending_exception (&error))
+ return NULL;
+ mono_array_setref (res, i - cdesc->first_counter, name);
}
return res;
}
}
for (i = 0; i < scat->num_counters; ++i) {
- mono_array_setref (res, i, mono_string_new (domain, p + 1));
+ MonoString *str = mono_string_new_checked (domain, p + 1, &error);
+ if (!is_ok (&error))
+ goto leave;
+ mono_array_setref (res, i, str);
p += 2; /* skip counter type */
p += strlen (p) + 1; /* skip counter name */
p += strlen (p) + 1; /* skip counter help */
}
- perfctr_unlock ();
- return res;
- }
+ } else
+ res = mono_array_new_checked (domain, mono_get_string_class (), 0, &error);
+leave:
perfctr_unlock ();
- res = mono_array_new_checked (domain, mono_get_string_class (), 0, &error);
mono_error_set_pending_exception (&error);
return res;
}
{
int i;
MonoDomain *domain = mono_domain_get ();
- mono_error_init (error);
+ error_init (error);
MonoArray * res = mono_array_new_checked (mono_domain_get (), mono_get_string_class (), count, error);
return_val_if_nok (error, NULL);
for (i = 0; i < count; ++i) {
sprintf (buf, "%d", GPOINTER_TO_INT (array [i]));
p = buf;
}
- mono_array_setref (res, i, mono_string_new (domain, p));
+ MonoString *str = mono_string_new_checked (domain, p, error);
if (p != buf)
g_free (p);
+ return_val_if_nok (error, NULL);
+ mono_array_setref (res, i, str);
}
return res;
}
{
int i;
MonoDomain *domain = mono_domain_get ();
- mono_error_init (error);
+ error_init (error);
MonoArray * res = mono_array_new_checked (mono_domain_get (), mono_get_string_class (), count, error);
return_val_if_nok (error, NULL);
for (i = 0; i < count; ++i) {
char* p = (char *)array[i];
- mono_array_setref (res, i, mono_string_new (domain, p));
+ MonoString *str = mono_string_new_checked (domain, p, error);
+ return_val_if_nok (error, NULL);
+ mono_array_setref (res, i, str);
}
return res;
int res;
void **buf = NULL;
MonoArray *array;
- mono_error_init (error);
+ error_init (error);
do {
count *= 2;
g_free (buf);
void **buf = NULL;
int i, count;
MonoArray *array;
- mono_error_init (error);
+ error_init (error);
count = mono_cpu_count () + 1; /* +1 for "_Total" */
buf = g_new (void*, count);
for (i = 0; i < count; ++i)
buf [i] = GINT_TO_POINTER (i - 1); /* -1 => _Total */
array = get_string_array (buf, count, FALSE, error);
g_free (buf);
- mono_array_setref (array, 0, mono_string_new (mono_domain_get (), "_Total"));
+ MonoString *total = mono_string_new_checked (mono_domain_get (), "_Total", error);
+ return_val_if_nok (error, NULL);
+ mono_array_setref (array, 0, total);
return array;
}
MonoArray *array;
int count = 0;
void **buf = mono_process_list (&count);
- mono_error_init (error);
+ error_init (error);
if (!buf)
return get_string_array (NULL, 0, FALSE, error);
array = get_string_array (buf, count, TRUE, error);
{
MonoArray *array;
int count = 0;
- mono_error_init (error);
+ error_init (error);
void **buf = mono_networkinterface_list (&count);
if (!buf)
return get_string_array_of_strings (NULL, 0, error);
get_custom_instances (MonoString *category, MonoError *error)
{
SharedCategory *scat;
- mono_error_init (error);
+ error_init (error);
scat = find_custom_category (category);
if (scat) {
GSList *list = get_custom_instances_list (scat);
}
for (tmp = list; tmp; tmp = tmp->next) {
SharedInstance *inst = (SharedInstance *)tmp->data;
- mono_array_setref (array, i, mono_string_new (mono_domain_get (), inst->instance_name));
+ MonoString *str = mono_string_new_checked (mono_domain_get (), inst->instance_name, error);
+ if (!is_ok (error)) {
+ g_slist_free (list);
+ return NULL;
+ }
+ mono_array_setref (array, i, str);
i++;
}
g_slist_free (list);