Merge pull request #3547 from cmp-/remove-obsolete-stack-checks-win32
[mono.git] / mono / utils / mono-proclib.c
index dc7ba95c73264a4b5fa54ac474b31e2dcc0f92fc..79da32b45118f4e6f992207c723ce14f880477c0 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright 2008-2011 Novell Inc
  * Copyright 2011 Xamarin Inc
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
 #include "config.h"
@@ -26,6 +27,7 @@
 #if defined(_POSIX_VERSION)
 #include <sys/errno.h>
 #include <sys/param.h>
+#include <errno.h>
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
 #    define kinfo_starttime_member kp_proc.p_starttime
 #    define kinfo_pid_member kp_proc.p_pid
 #    define kinfo_name_member kp_proc.p_comm
+#elif defined(__NetBSD__)
+#    define kinfo_starttime_member p_ustart_sec
+#    define kinfo_pid_member p_pid
+#    define kinfo_name_member p_comm
 #elif defined(__OpenBSD__)
 // Can not figure out how to get the proc's start time on OpenBSD
 #    undef kinfo_starttime_member 
@@ -74,7 +80,7 @@ mono_process_list (int *size)
 #ifdef KERN_PROC2
        int mib [6];
        size_t data_len = sizeof (struct kinfo_proc2) * 400;
-       struct kinfo_proc2 *processes = malloc (data_len);
+       struct kinfo_proc2 *processes = g_malloc (data_len);
 #else
        int mib [4];
        size_t data_len = sizeof (struct kinfo_proc) * 16;
@@ -99,7 +105,7 @@ mono_process_list (int *size)
 
        res = sysctl (mib, 6, processes, &data_len, NULL, 0);
        if (res < 0) {
-               free (processes);
+               g_free (processes);
                return NULL;
        }
 #else
@@ -113,10 +119,10 @@ mono_process_list (int *size)
                res = sysctl (mib, 4, NULL, &data_len, NULL, 0);
                if (res)
                        return NULL;
-               processes = (struct kinfo_proc *) malloc (data_len);
+               processes = (struct kinfo_proc *) g_malloc (data_len);
                res = sysctl (mib, 4, processes, &data_len, NULL, 0);
                if (res < 0) {
-                       free (processes);
+                       g_free (processes);
                        if (errno != ENOMEM)
                                return NULL;
                        limit --;
@@ -134,7 +140,7 @@ mono_process_list (int *size)
        buf = (void **) g_realloc (buf, res * sizeof (void*));
        for (i = 0; i < res; ++i)
                buf [i] = GINT_TO_POINTER (processes [i].kinfo_pid_member);
-       free (processes);
+       g_free (processes);
        if (size)
                *size = res;
        return buf;
@@ -315,15 +321,23 @@ mono_process_get_times (gpointer pid, gint64 *start_time, gint64 *user_time, gin
                {
                        KINFO_PROC processi;
 
-                       if (sysctl_kinfo_proc (pid, &processi))
+                       if (sysctl_kinfo_proc (pid, &processi)) {
+#if defined(__NetBSD__)
+                               struct timeval tv;
+                               tv.tv_sec = processi.kinfo_starttime_member;
+                               tv.tv_usec = processi.p_ustart_usec;
+                               *start_time = mono_100ns_datetime_from_timeval(tv);
+#else
                                *start_time = mono_100ns_datetime_from_timeval (processi.kinfo_starttime_member);
+#endif
+                       }
                }
 #endif
 
                if (*start_time == 0) {
                        static guint64 boot_time = 0;
                        if (!boot_time)
-                               boot_time = mono_100ns_datetime () - ((guint64)mono_msec_ticks ()) * 10000;
+                               boot_time = mono_100ns_datetime () - mono_msec_boottime () * 10000;
 
                        *start_time = boot_time + mono_process_get_data (pid, MONO_PROCESS_ELAPSED);
                }
@@ -354,22 +368,35 @@ get_process_stat_item (int pid, int pos, int sum, MonoProcessError *error)
        mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT, th_count;
        thread_array_t th_array;
        size_t i;
+       kern_return_t ret;
 
        if (pid == getpid ()) {
                /* task_for_pid () doesn't work on ios, even for the current process */
                task = mach_task_self ();
        } else {
-               if (task_for_pid (mach_task_self (), pid, &task) != KERN_SUCCESS)
+               do {
+                       ret = task_for_pid (mach_task_self (), pid, &task);
+               } while (ret == KERN_ABORTED);
+
+               if (ret != KERN_SUCCESS)
                        RET_ERROR (MONO_PROCESS_ERROR_NOT_FOUND);
        }
 
-       if (task_info (task, TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count) != KERN_SUCCESS) {
+       do {
+               ret = task_info (task, TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count);
+       } while (ret == KERN_ABORTED);
+
+       if (ret != KERN_SUCCESS) {
                if (pid != getpid ())
                        mach_port_deallocate (mach_task_self (), task);
                RET_ERROR (MONO_PROCESS_ERROR_OTHER);
        }
+
+       do {
+               ret = task_threads (task, &th_array, &th_count);
+       } while (ret == KERN_ABORTED);
        
-       if (task_threads(task, &th_array, &th_count) != KERN_SUCCESS) {
+       if (ret  != KERN_SUCCESS) {
                if (pid != getpid ())
                        mach_port_deallocate (mach_task_self (), task);
                RET_ERROR (MONO_PROCESS_ERROR_OTHER);
@@ -380,7 +407,11 @@ get_process_stat_item (int pid, int pos, int sum, MonoProcessError *error)
                
                struct thread_basic_info th_info;
                mach_msg_type_number_t th_info_count = THREAD_BASIC_INFO_COUNT;
-               if (thread_info(th_array[i], THREAD_BASIC_INFO, (thread_info_t)&th_info, &th_info_count) == KERN_SUCCESS) {
+               do {
+                       ret = thread_info(th_array[i], THREAD_BASIC_INFO, (thread_info_t)&th_info, &th_info_count);
+               } while (ret == KERN_ABORTED);
+
+               if (ret == KERN_SUCCESS) {
                        thread_user_time = th_info.user_time.seconds + th_info.user_time.microseconds / 1e6;
                        thread_system_time = th_info.system_time.seconds + th_info.system_time.microseconds / 1e6;
                        //thread_percent = (double)th_info.cpu_usage / TH_USAGE_SCALE;
@@ -493,16 +524,25 @@ get_pid_status_item (int pid, const char *item, MonoProcessError *error, int mul
        task_t task;
        struct task_basic_info t_info;
        mach_msg_type_number_t th_count = TASK_BASIC_INFO_COUNT;
+       kern_return_t mach_ret;
 
        if (pid == getpid ()) {
                /* task_for_pid () doesn't work on ios, even for the current process */
                task = mach_task_self ();
        } else {
-               if (task_for_pid (mach_task_self (), pid, &task) != KERN_SUCCESS)
+               do {
+                       mach_ret = task_for_pid (mach_task_self (), pid, &task);
+               } while (mach_ret == KERN_ABORTED);
+
+               if (mach_ret != KERN_SUCCESS)
                        RET_ERROR (MONO_PROCESS_ERROR_NOT_FOUND);
        }
-       
-       if (task_info (task, TASK_BASIC_INFO, (task_info_t)&t_info, &th_count) != KERN_SUCCESS) {
+
+       do {
+               mach_ret = task_info (task, TASK_BASIC_INFO, (task_info_t)&t_info, &th_count);
+       } while (mach_ret == KERN_ABORTED);
+
+       if (mach_ret != KERN_SUCCESS) {
                if (pid != getpid ())
                        mach_port_deallocate (mach_task_self (), task);
                RET_ERROR (MONO_PROCESS_ERROR_OTHER);