Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / metadata / mono-perfcounters.c
index 8c370a9bacfc4bdce4d68498f481ec23ab7c0434..1a3123a30aad58811bbf8d07c6d0581ac029474e 100644 (file)
@@ -1,5 +1,5 @@
-/*
- * mono-perfcounters.c
+/**
+ * \file
  *
  * Performance counters support.
  *
@@ -48,6 +48,7 @@
 #include "utils/mono-networkinterfaces.h"
 #include "utils/mono-error-internals.h"
 #include "utils/atomic.h"
+#include "utils/unlocked.h"
 
 /* map of CounterSample.cs */
 struct _MonoCounterSample {
@@ -1073,52 +1074,52 @@ predef_writable_counter (ImplVtable *vtable, MonoBoolean only_value, MonoCounter
        case CATEGORY_EXC:
                switch (id) {
                case COUNTER_EXC_THROWN:
-                       sample->rawValue = mono_perfcounters->exceptions_thrown;
+                       sample->rawValue = InterlockedRead (&mono_perfcounters->exceptions_thrown);
                        return TRUE;
                }
                break;
        case CATEGORY_ASPNET:
                switch (id) {
                case COUNTER_ASPNET_REQ_Q:
-                       sample->rawValue = mono_perfcounters->aspnet_requests_queued;
+                       sample->rawValue = InterlockedRead (&mono_perfcounters->aspnet_requests_queued);
                        return TRUE;
                case COUNTER_ASPNET_REQ_TOTAL:
-                       sample->rawValue = mono_perfcounters->aspnet_requests;
+                       sample->rawValue = InterlockedRead (&mono_perfcounters->aspnet_requests);
                        return TRUE;
                }
                break;
        case CATEGORY_THREADPOOL:
                switch (id) {
                case COUNTER_THREADPOOL_WORKITEMS:
-                       sample->rawValue = mono_perfcounters->threadpool_workitems;
+                       sample->rawValue = InterlockedRead64 (&mono_perfcounters->threadpool_workitems);
                        return TRUE;
                case COUNTER_THREADPOOL_IOWORKITEMS:
-                       sample->rawValue = mono_perfcounters->threadpool_ioworkitems;
+                       sample->rawValue = InterlockedRead64 (&mono_perfcounters->threadpool_ioworkitems);
                        return TRUE;
                case COUNTER_THREADPOOL_THREADS:
-                       sample->rawValue = mono_perfcounters->threadpool_threads;
+                       sample->rawValue = InterlockedRead (&mono_perfcounters->threadpool_threads);
                        return TRUE;
                case COUNTER_THREADPOOL_IOTHREADS:
-                       sample->rawValue = mono_perfcounters->threadpool_iothreads;
+                       sample->rawValue = InterlockedRead (&mono_perfcounters->threadpool_iothreads);
                        return TRUE;
                }
                break;
        case CATEGORY_JIT:
                switch (id) {
                case COUNTER_JIT_BYTES:
-                       sample->rawValue = mono_perfcounters->jit_bytes;
+                       sample->rawValue = InterlockedRead (&mono_perfcounters->jit_bytes);
                        return TRUE;
                case COUNTER_JIT_METHODS:
-                       sample->rawValue = mono_perfcounters->jit_methods;
+                       sample->rawValue = InterlockedRead (&mono_perfcounters->jit_methods);
                        return TRUE;
                case COUNTER_JIT_TIME:
-                       sample->rawValue = mono_perfcounters->jit_time;
+                       sample->rawValue = InterlockedRead (&mono_perfcounters->jit_time);
                        return TRUE;
                case COUNTER_JIT_BYTES_PSEC:
-                       sample->rawValue = mono_perfcounters->jit_bytes;
+                       sample->rawValue = InterlockedRead (&mono_perfcounters->jit_bytes);
                        return TRUE;
                case COUNTER_JIT_FAILURES:
-                       sample->rawValue = mono_perfcounters->jit_failures;
+                       sample->rawValue = InterlockedRead (&mono_perfcounters->jit_failures);
                        return TRUE;
                }
                break;
@@ -1129,7 +1130,7 @@ predef_writable_counter (ImplVtable *vtable, MonoBoolean only_value, MonoCounter
 static gint64
 predef_writable_update (ImplVtable *vtable, MonoBoolean do_incr, gint64 value)
 {
-       guint32 *volatile ptr = NULL;
+       gint32 *volatile ptr = NULL;
        gint64 *volatile ptr64 = NULL;
        int cat_id = GPOINTER_TO_INT (vtable->arg);
        int id = cat_id >> 16;
@@ -1143,8 +1144,8 @@ predef_writable_update (ImplVtable *vtable, MonoBoolean do_incr, gint64 value)
                break;
        case CATEGORY_THREADPOOL:
                switch (id) {
-               case COUNTER_THREADPOOL_WORKITEMS: ptr64 = (gint64 *) &mono_perfcounters->threadpool_workitems; break;
-               case COUNTER_THREADPOOL_IOWORKITEMS: ptr64 = (gint64 *) &mono_perfcounters->threadpool_ioworkitems; break;
+               case COUNTER_THREADPOOL_WORKITEMS: ptr64 = &mono_perfcounters->threadpool_workitems; break;
+               case COUNTER_THREADPOOL_IOWORKITEMS: ptr64 = &mono_perfcounters->threadpool_ioworkitems; break;
                case COUNTER_THREADPOOL_THREADS: ptr = &mono_perfcounters->threadpool_threads; break;
                case COUNTER_THREADPOOL_IOTHREADS: ptr = &mono_perfcounters->threadpool_iothreads; break;
                }
@@ -1153,29 +1154,23 @@ predef_writable_update (ImplVtable *vtable, MonoBoolean do_incr, gint64 value)
        if (ptr) {
                if (do_incr) {
                        if (value == 1)
-                               return InterlockedIncrement ((gint32 *) ptr); /* FIXME: sign */
+                               return InterlockedIncrement (ptr);
                        if (value == -1)
-                               return InterlockedDecrement ((gint32 *) ptr); /* FIXME: sign */
+                               return InterlockedDecrement (ptr);
 
-                       *ptr += value;
-                       return *ptr;
+                       return InterlockedAdd(ptr, value);
                }
                /* this can be non-atomic */
                *ptr = value;
                return value;
        } else if (ptr64) {
                if (do_incr) {
-                       /* FIXME: we need to do this atomically */
-                       /* No InterlockedIncrement64() yet */
-                       /*
                        if (value == 1)
-                               return InterlockedIncrement64 (ptr);
+                               return UnlockedIncrement64 (ptr64); /* FIXME: use InterlockedIncrement64 () */
                        if (value == -1)
-                               return InterlockedDecrement64 (ptr);
-                       */
+                               return UnlockedDecrement64 (ptr64); /* FIXME: use InterlockedDecrement64 () */
 
-                       *ptr64 += value;
-                       return *ptr64;
+                       return UnlockedAdd64 (ptr64, value); /* FIXME: use InterlockedAdd64 () */
                }
                /* this can be non-atomic */
                *ptr64 = value;
@@ -1423,10 +1418,14 @@ mono_perfcounter_category_del (MonoString *name)
        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;
@@ -1435,9 +1434,15 @@ mono_perfcounter_category_help (MonoString *category, MonoString *machine)
                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;
 }
 
 /*
@@ -1596,6 +1601,7 @@ mono_perfcounter_instance_exists (MonoString *instance, MonoString *category, Mo
        return FALSE;
 }
 
+/* this is an icall */
 MonoArray*
 mono_perfcounter_category_names (MonoString *machine)
 {
@@ -1620,15 +1626,23 @@ 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;
 }
 
@@ -1654,7 +1668,10 @@ mono_perfcounter_counter_names (MonoString *category, MonoString *machine)
                        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;
        }
@@ -1670,16 +1687,18 @@ mono_perfcounter_counter_names (MonoString *category, MonoString *machine)
                }
 
                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;
 }
@@ -1702,9 +1721,11 @@ get_string_array (void **array, int count, gboolean is_process, MonoError *error
                        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;
 }
@@ -1719,7 +1740,9 @@ get_string_array_of_strings (void **array, int count, MonoError *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;
@@ -1757,7 +1780,9 @@ get_cpu_instances (MonoError *error)
                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;
 }
 
@@ -1806,7 +1831,12 @@ get_custom_instances (MonoString *category, MonoError *error)
                }
                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);