void binary_protocol_init (const char *filename, long long limit) { #ifdef HAVE_UNISTD_H file_size_limit = limit; /* Original name length + . + pid length in hex + null terminator */ filename_or_prefix = g_strdup_printf ("%s", filename); binary_protocol_open_file (FALSE); if (binary_protocol_file == -1) { /* Another process owns the file, try adding the pid suffix to the filename */ gint32 pid = mono_process_current_pid (); g_free (filename_or_prefix); filename_or_prefix = g_strdup_printf ("%s.%x", filename, pid); binary_protocol_open_file (TRUE); } /* If we have a file size limit, we might need to open additional files */ if (file_size_limit == 0) g_free (filename_or_prefix); binary_protocol_header (PROTOCOL_HEADER_CHECK, PROTOCOL_HEADER_VERSION, SIZEOF_VOID_P, G_BYTE_ORDER == G_LITTLE_ENDIAN); #else g_error ("sgen binary protocol: not supported"); #endif }
guint32 ves_icall_System_Diagnostics_Process_GetPid_internal (void) { return mono_process_current_pid (); }
static gint64 page_faults (void) { return mono_process_get_data (GINT_TO_POINTER (mono_process_current_pid ()), MONO_PROCESS_FAULTS); }
static gint64 virtual_bytes (void) { return mono_process_get_data (GINT_TO_POINTER (mono_process_current_pid ()), MONO_PROCESS_VIRTUAL_BYTES); }
static gint64 private_bytes (void) { return mono_process_get_data (GINT_TO_POINTER (mono_process_current_pid ()), MONO_PROCESS_PRIVATE_BYTES); }
static gint64 working_set (void) { return mono_process_get_data (GINT_TO_POINTER (mono_process_current_pid ()), MONO_PROCESS_WORKING_SET); }
static gint64 total_time (void) { return mono_process_get_data (GINT_TO_POINTER (mono_process_current_pid ()), MONO_PROCESS_TOTAL_TIME); }
static gint64 system_time (void) { return mono_process_get_data (GINT_TO_POINTER (mono_process_current_pid ()), MONO_PROCESS_SYSTEM_TIME); }
static gint64 user_time (void) { return mono_process_get_data (GINT_TO_POINTER (mono_process_current_pid ()), MONO_PROCESS_USER_TIME); }
/** * mono_cpu_count: * * Return the number of processors on the system. */ 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. * Instead we use /sys entries to query the actual hardware CPU count. */ int count = 0; char buffer[8] = {'\0'}; int present = open ("/sys/devices/system/cpu/present", O_RDONLY); /* Format of the /sys entry is a cpulist of indexes which in the case * of present is always of the form "0-(n-1)" when there is more than * 1 core, n being the number of CPU cores in the system. Otherwise * the value is simply 0 */ if (present != -1 && read (present, (char*)buffer, sizeof (buffer)) > 3) count = strtol (((char*)buffer) + 2, NULL, 10); if (present != -1) close (present); if (count > 0) return count + 1; #endif #if defined(HOST_ARM) || defined (HOST_ARM64) /* * Recap from Alexander Köplinger <*****@*****.**>: * * When we merged the change from PR #2722, we started seeing random failures on ARM in * the MonoTests.System.Threading.ThreadPoolTests.SetAndGetMaxThreads and * MonoTests.System.Threading.ManualResetEventSlimTests.Constructor_Defaults tests. Both * of those tests are dealing with Environment.ProcessorCount to verify some implementation * details. * * It turns out that on the Jetson TK1 board we use on public Jenkins and on ARM kernels * in general, the value returned by sched_getaffinity (or _SC_NPROCESSORS_ONLN) doesn't * contain CPUs/cores that are powered off for power saving reasons. This is contrary to * what happens on x86, where even cores in deep-sleep state are returned [1], [2]. This * means that we would get a processor count of 1 at one point in time and a higher value * when load increases later on as the system wakes CPUs. * * Various runtime pieces like the threadpool and also user code however relies on the * value returned by Environment.ProcessorCount e.g. for deciding how many parallel tasks * to start, thereby limiting the performance when that code thinks we only have one CPU. * * Talking to a few people, this was the reason why we changed to _SC_NPROCESSORS_CONF in * mono#1688 and why we added a special case for Android in mono@de3addc to get the "real" * number of processors in the system. * * Because of those issues Android/Dalvik also switched from _ONLN to _SC_NPROCESSORS_CONF * for the Java API Runtime.availableProcessors() too [3], citing: * > Traditionally this returned the number currently online, but many mobile devices are * able to take unused cores offline to save power, so releases newer than Android 4.2 (Jelly * Bean) return the maximum number of cores that could be made available if there were no * power or heat constraints. * * The problem with sticking to _SC_NPROCESSORS_CONF however is that it breaks down in * constrained environments like Docker or with an explicit CPU affinity set by the Linux * `taskset` command, They'd get a higher CPU count than can be used, start more threads etc. * which results in unnecessary context switches and overloaded systems. That's why we need * to respect sched_getaffinity. * * So while in an ideal world we would be able to rely on sched_getaffinity/_SC_NPROCESSORS_ONLN * to return the number of theoretically available CPUs regardless of power saving measures * everywhere, we can't do this on ARM. * * I think the pragmatic solution is the following: * * use sched_getaffinity (+ fallback to _SC_NPROCESSORS_ONLN in case of error) on x86. This * ensures we're inline with what OpenJDK [4] and CoreCLR [5] do * * use _SC_NPROCESSORS_CONF exclusively on ARM (I think we could eventually even get rid of * the PLATFORM_ANDROID special case) * * Helpful links: * * [1] https://sourceware.org/ml/libc-alpha/2013-07/msg00383.html * [2] https://lists.01.org/pipermail/powertop/2012-September/000433.html * [3] https://android.googlesource.com/platform/libcore/+/750dc634e56c58d1d04f6a138734ac2b772900b5%5E1..750dc634e56c58d1d04f6a138734ac2b772900b5/ * [4] https://bugs.openjdk.java.net/browse/JDK-6515172 * [5] https://github.com/dotnet/coreclr/blob/7058273693db2555f127ce16e6b0c5b40fb04867/src/pal/src/misc/sysinfo.cpp#L148 */ #ifdef _SC_NPROCESSORS_CONF { int count = sysconf (_SC_NPROCESSORS_CONF); if (count > 0) return count; } #endif #else #ifdef HAVE_SCHED_GETAFFINITY { cpu_set_t set; if (sched_getaffinity (mono_process_current_pid (), sizeof (set), &set) == 0) return CPU_COUNT (&set); } #endif #ifdef _SC_NPROCESSORS_ONLN { int count = sysconf (_SC_NPROCESSORS_ONLN); if (count > 0) return count; } #endif #endif /* defined(HOST_ARM) || defined (HOST_ARM64) */ #ifdef USE_SYSCTL { int count; int mib [2]; size_t len = sizeof (int); mib [0] = CTL_HW; mib [1] = HW_NCPU; if (sysctl (mib, 2, &count, &len, NULL, 0) == 0) return count; } #endif #endif /* HOST_WIN32 */ /* FIXME: warn */ return 1; }