X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mono%2Futils%2Fmono-proclib.c;h=f1a28444425eadb87c55a6626e1f70d173458e8f;hb=bccf7177f77968774052ea46627706bf2fec5d3a;hp=c53af96454a79e84a98239ad450d0e9f8658154d;hpb=56ad8f4e5dfb8198e4671f631a3103b1e8b83dd3;p=mono.git diff --git a/mono/utils/mono-proclib.c b/mono/utils/mono-proclib.c index c53af96454a..f1a28444425 100644 --- a/mono/utils/mono-proclib.c +++ b/mono/utils/mono-proclib.c @@ -19,14 +19,10 @@ #include #endif -#ifdef HOST_WIN32 -#include -#include -#endif - #if defined(_POSIX_VERSION) #include #include +#include #ifdef HAVE_SYS_TYPES_H #include #endif @@ -47,6 +43,10 @@ # 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 @@ -60,6 +60,21 @@ #define USE_SYSCTL 1 #endif +#ifdef HAVE_SCHED_GETAFFINITY +# ifndef GLIBC_HAS_CPU_COUNT +static int +CPU_COUNT(cpu_set_t *set) +{ + int i, count = 0; + + for (int i = 0; i < CPU_SETSIZE; i++) + if (CPU_ISSET(i, set)) + count++; + return count; +} +# endif +#endif + /** * mono_process_list: * @size: a pointer to a location where the size of the returned array is stored @@ -75,7 +90,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; @@ -100,7 +115,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 @@ -114,10 +129,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 --; @@ -135,7 +150,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; @@ -182,7 +197,7 @@ get_pid_status_item_buf (int pid, const char *item, char *rbuf, int blen, MonoPr char buf [256]; char *s; FILE *f; - int len = strlen (item); + size_t len = strlen (item); g_snprintf (buf, sizeof (buf), "/proc/%d/status", pid); f = fopen (buf, "r"); @@ -281,7 +296,7 @@ mono_process_get_name (gpointer pid, char *buf, int len) char fname [128]; FILE *file; char *p; - int r; + size_t r; sprintf (fname, "/proc/%d/cmdline", GPOINTER_TO_INT (pid)); buf [0] = 0; file = fopen (fname, "r"); @@ -316,15 +331,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); } @@ -355,22 +378,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); @@ -381,7 +417,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; @@ -413,7 +453,8 @@ get_process_stat_item (int pid, int pos, int sum, MonoProcessError *error) char buf [512]; char *s, *end; FILE *f; - int len, i; + size_t len; + int i; gint64 value; g_snprintf (buf, sizeof (buf), "/proc/%d/stat", pid); @@ -494,16 +535,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); @@ -598,31 +648,27 @@ mono_process_get_data (gpointer pid, MonoProcessData data) return mono_process_get_data_with_error (pid, data, &error); } +#ifndef HOST_WIN32 int mono_process_current_pid () { #if defined(HAVE_UNISTD_H) return (int) getpid (); -#elif defined(HOST_WIN32) - return (int) GetCurrentProcessId (); #else #error getpid #endif } +#endif /* !HOST_WIN32 */ /** * mono_cpu_count: * * Return the number of processors on the system. */ +#ifndef HOST_WIN32 int mono_cpu_count (void) { -#ifdef HOST_WIN32 - SYSTEM_INFO info; - GetSystemInfo (&info); - return info.dwNumberOfProcessors; -#else #ifdef PLATFORM_ANDROID /* Android tries really hard to save power by powering off CPUs on SMP phones which * means the normal way to query cpu count returns a wrong value with userspace API. @@ -740,10 +786,10 @@ mono_cpu_count (void) return count; } #endif -#endif /* HOST_WIN32 */ /* FIXME: warn */ return 1; } +#endif /* !HOST_WIN32 */ static void get_cpu_times (int cpu_id, gint64 *user, gint64 *systemt, gint64 *irq, gint64 *sirq, gint64 *idle) @@ -850,14 +896,13 @@ mono_atexit (void (*func)(void)) * battery and performance reasons, shut down cores and * lie about the number of active cores. */ +#ifndef HOST_WIN32 gint32 mono_cpu_usage (MonoCpuUsageState *prev) { gint32 cpu_usage = 0; gint64 cpu_total_time; gint64 cpu_busy_time; - -#ifndef HOST_WIN32 struct rusage resource_usage; gint64 current_time; gint64 kernel_time; @@ -880,28 +925,10 @@ mono_cpu_usage (MonoCpuUsageState *prev) prev->user_time = user_time; prev->current_time = current_time; } -#else - guint64 idle_time; - guint64 kernel_time; - guint64 user_time; - - if (!GetSystemTimes ((FILETIME*) &idle_time, (FILETIME*) &kernel_time, (FILETIME*) &user_time)) { - g_error ("GetSystemTimes() failed, error code is %d\n", GetLastError ()); - return -1; - } - - cpu_total_time = (gint64)((user_time - (prev ? prev->user_time : 0)) + (kernel_time - (prev ? prev->kernel_time : 0))); - cpu_busy_time = (gint64)(cpu_total_time - (idle_time - (prev ? prev->idle_time : 0))); - - if (prev) { - prev->idle_time = idle_time; - prev->kernel_time = kernel_time; - prev->user_time = user_time; - } -#endif if (cpu_total_time > 0 && cpu_busy_time > 0) cpu_usage = (gint32)(cpu_busy_time * 100 / cpu_total_time); return cpu_usage; } +#endif /* !HOST_WIN32 */