Merge pull request #2869 from BrzVlad/feature-mod-union-opt
[mono.git] / mono / metadata / mono-perfcounters.c
index 445df5c8334ef7931c3c373c82a5168d71d8842b..fb205e80eaff2781966cdb448262ac85e9bac19f 100644 (file)
@@ -502,7 +502,12 @@ mono_determine_physical_ram_available_size (void)
        mach_port_t host = mach_host_self();
        vm_size_t page_size;
        vm_statistics_data_t vmstat;
-       if (KERN_SUCCESS != host_statistics(host, HOST_VM_INFO, (host_info_t)&vmstat, &count)) {
+       kern_return_t ret;
+       do {
+               ret = host_statistics(host, HOST_VM_INFO, (host_info_t)&vmstat, &count);
+       } while (ret == KERN_ABORTED);
+
+       if (ret != KERN_SUCCESS) {
                g_warning ("Mono was unable to retrieve memory usage!");
                return 0;
        }
@@ -1585,16 +1590,25 @@ mono_perfcounter_instance_exists (MonoString *instance, MonoString *category, Mo
 MonoArray*
 mono_perfcounter_category_names (MonoString *machine)
 {
+       MonoError error;
        int i;
        MonoArray *res;
        MonoDomain *domain = mono_domain_get ();
        GSList *custom_categories, *tmp;
        /* no support for counters on other machines */
-       if (mono_string_compare_ascii (machine, "."))
-               return mono_array_new (domain, mono_get_string_class (), 0);
+       if (mono_string_compare_ascii (machine, ".")) {
+               res = mono_array_new_checked (domain, mono_get_string_class (), 0, &error);
+               mono_error_set_pending_exception (&error);
+               return res;
+       }
        perfctr_lock ();
        custom_categories = get_custom_categories ();
-       res = mono_array_new (domain, mono_get_string_class (), NUM_CATEGORIES + g_slist_length (custom_categories));
+       res = mono_array_new_checked (domain, mono_get_string_class (), NUM_CATEGORIES + g_slist_length (custom_categories), &error);
+       if (mono_error_set_pending_exception (&error)) {
+               perfctr_unlock ();
+               return NULL;
+       }
+
        for (i = 0; i < NUM_CATEGORIES; ++i) {
                const CategoryDesc *cdesc = &predef_categories [i];
                mono_array_setref (res, i, mono_string_new (domain, cdesc->name));
@@ -1612,17 +1626,23 @@ mono_perfcounter_category_names (MonoString *machine)
 MonoArray*
 mono_perfcounter_counter_names (MonoString *category, MonoString *machine)
 {
+       MonoError error;
        int i;
        SharedCategory *scat;
        const CategoryDesc *cdesc;
        MonoArray *res;
        MonoDomain *domain = mono_domain_get ();
        /* no support for counters on other machines */
-       if (mono_string_compare_ascii (machine, "."))
-               return mono_array_new (domain, mono_get_string_class (), 0);
+       if (mono_string_compare_ascii (machine, ".")) {
+               res =  mono_array_new_checked (domain, mono_get_string_class (), 0, &error);
+               mono_error_set_pending_exception (&error);
+               return res;
+       }
        cdesc = find_category (category);
        if (cdesc) {
-               res = mono_array_new (domain, mono_get_string_class (), cdesc [1].first_counter - cdesc->first_counter);
+               res = mono_array_new_checked (domain, mono_get_string_class (), cdesc [1].first_counter - cdesc->first_counter, &error);
+               if (mono_error_set_pending_exception (&error))
+                       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));
@@ -1634,7 +1654,12 @@ mono_perfcounter_counter_names (MonoString *category, MonoString *machine)
        if (scat) {
                char *p = custom_category_counters (scat);
                int i;
-               res = mono_array_new (domain, mono_get_string_class (), scat->num_counters);
+               res = mono_array_new_checked (domain, mono_get_string_class (), scat->num_counters, &error);
+               if (mono_error_set_pending_exception (&error)) {
+                       perfctr_unlock ();
+                       return NULL;
+               }
+
                for (i = 0; i < scat->num_counters; ++i) {
                        mono_array_setref (res, i, mono_string_new (domain, p + 1));
                        p += 2; /* skip counter type */
@@ -1645,15 +1670,19 @@ mono_perfcounter_counter_names (MonoString *category, MonoString *machine)
                return res;
        }
        perfctr_unlock ();
-       return mono_array_new (domain, mono_get_string_class (), 0);
+       res = mono_array_new_checked (domain, mono_get_string_class (), 0, &error);
+       mono_error_set_pending_exception (&error);
+       return res;
 }
 
 static MonoArray*
-get_string_array (void **array, int count, gboolean is_process)
+get_string_array (void **array, int count, gboolean is_process, MonoError *error)
 {
        int i;
        MonoDomain *domain = mono_domain_get ();
-       MonoArray * res = mono_array_new (mono_domain_get (), mono_get_string_class (), count);
+       mono_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 buf [128];
                char *p;
@@ -1672,11 +1701,13 @@ get_string_array (void **array, int count, gboolean is_process)
 }
 
 static MonoArray*
-get_string_array_of_strings (void **array, int count)
+get_string_array_of_strings (void **array, int count, MonoError *error)
 {
        int i;
        MonoDomain *domain = mono_domain_get ();
-       MonoArray * res = mono_array_new (mono_domain_get (), mono_get_string_class (), count);
+       mono_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));
@@ -1686,76 +1717,84 @@ get_string_array_of_strings (void **array, int count)
 }
 
 static MonoArray*
-get_mono_instances (void)
+get_mono_instances (MonoError *error)
 {
        int count = 64;
        int res;
        void **buf = NULL;
        MonoArray *array;
+       mono_error_init (error);
        do {
                count *= 2;
                g_free (buf);
                buf = g_new (void*, count);
                res = mono_shared_area_instances (buf, count);
        } while (res == count);
-       array = get_string_array (buf, res, TRUE);
+       array = get_string_array (buf, res, TRUE, error);
        g_free (buf);
        return array;
 }
 
 static MonoArray*
-get_cpu_instances (void)
+get_cpu_instances (MonoError *error)
 {
        void **buf = NULL;
        int i, count;
        MonoArray *array;
-
+       mono_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);
+       array = get_string_array (buf, count, FALSE, error);
        g_free (buf);
        mono_array_setref (array, 0, mono_string_new (mono_domain_get (), "_Total"));
        return array;
 }
 
 static MonoArray*
-get_processes_instances (void)
+get_processes_instances (MonoError *error)
 {
        MonoArray *array;
        int count = 0;
        void **buf = mono_process_list (&count);
+       mono_error_init (error);
        if (!buf)
-               return get_string_array (NULL, 0, FALSE);
-       array = get_string_array (buf, count, TRUE);
+               return get_string_array (NULL, 0, FALSE, error);
+       array = get_string_array (buf, count, TRUE, error);
        g_free (buf);
        return array;
 }
 
 static MonoArray*
-get_networkinterface_instances (void)
+get_networkinterface_instances (MonoError *error)
 {
        MonoArray *array;
        int count = 0;
+       mono_error_init (error);
        void **buf = mono_networkinterface_list (&count);
        if (!buf)
-               return get_string_array_of_strings (NULL, 0);
-       array = get_string_array_of_strings (buf, count);
+               return get_string_array_of_strings (NULL, 0, error);
+       array = get_string_array_of_strings (buf, count, error);
        g_strfreev ((char **) buf);
        return array;
 }
 
 static MonoArray*
-get_custom_instances (MonoString *category)
+get_custom_instances (MonoString *category, MonoError *error)
 {
        SharedCategory *scat;
+       mono_error_init (error);
        scat = find_custom_category (category);
        if (scat) {
                GSList *list = get_custom_instances_list (scat);
                GSList *tmp;
                int i = 0;
-               MonoArray *array = mono_array_new (mono_domain_get (), mono_get_string_class (), g_slist_length (list));
+               MonoArray *array = mono_array_new_checked (mono_domain_get (), mono_get_string_class (), g_slist_length (list), error);
+               if (!is_ok (error)) {
+                       g_slist_free (list);
+                       return NULL;
+               }
                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));
@@ -1764,31 +1803,46 @@ get_custom_instances (MonoString *category)
                g_slist_free (list);
                return array;
        }
-       return mono_array_new (mono_domain_get (), mono_get_string_class (), 0);
+       return mono_array_new_checked (mono_domain_get (), mono_get_string_class (), 0, error);
 }
 
 MonoArray*
 mono_perfcounter_instance_names (MonoString *category, MonoString *machine)
 {
+       MonoError error;
        const CategoryDesc* cat;
-       if (mono_string_compare_ascii (machine, "."))
-               return mono_array_new (mono_domain_get (), mono_get_string_class (), 0);
+       MonoArray *result = NULL;
+       if (mono_string_compare_ascii (machine, ".")) {
+               result = mono_array_new_checked (mono_domain_get (), mono_get_string_class (), 0, &error);
+               mono_error_set_pending_exception (&error);
+               return result;
+       }
+       
        cat = find_category (category);
-       if (!cat)
-               return get_custom_instances (category);
+       if (!cat) {
+               MonoArray *result = get_custom_instances (category, &error);
+               mono_error_set_pending_exception (&error);
+               return result;
+       }
        switch (cat->instance_type) {
        case MonoInstance:
-               return get_mono_instances ();
+               result = get_mono_instances (&error);
+               break;
        case CPUInstance:
-               return get_cpu_instances ();
+               result = get_cpu_instances (&error);
+               break;
        case ProcessInstance:
-               return get_processes_instances ();
+               result = get_processes_instances (&error);
+               break;
        case NetworkInterfaceInstance:
-               return get_networkinterface_instances ();
+               result = get_networkinterface_instances (&error);
+               break;
        case ThreadInstance:
        default:
-               return mono_array_new (mono_domain_get (), mono_get_string_class (), 0);
+               result = mono_array_new_checked (mono_domain_get (), mono_get_string_class (), 0, &error);
        }
+       mono_error_set_pending_exception (&error);
+       return result;
 }
 
 typedef struct {