Example #1
0
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
}
Example #2
0
guint32
ves_icall_System_Diagnostics_Process_GetPid_internal (void)
{
	return mono_process_current_pid ();
}
Example #3
0
static gint64
page_faults (void)
{
	return mono_process_get_data (GINT_TO_POINTER (mono_process_current_pid ()), MONO_PROCESS_FAULTS);
}
Example #4
0
static gint64
virtual_bytes (void)
{
	return mono_process_get_data (GINT_TO_POINTER (mono_process_current_pid ()), MONO_PROCESS_VIRTUAL_BYTES);
}
Example #5
0
static gint64
private_bytes (void)
{
	return mono_process_get_data (GINT_TO_POINTER (mono_process_current_pid ()), MONO_PROCESS_PRIVATE_BYTES);
}
Example #6
0
static gint64
working_set (void)
{
	return mono_process_get_data (GINT_TO_POINTER (mono_process_current_pid ()), MONO_PROCESS_WORKING_SET);
}
Example #7
0
static gint64
total_time (void)
{
	return mono_process_get_data (GINT_TO_POINTER (mono_process_current_pid ()), MONO_PROCESS_TOTAL_TIME);
}
Example #8
0
static gint64
system_time (void)
{
	return mono_process_get_data (GINT_TO_POINTER (mono_process_current_pid ()), MONO_PROCESS_SYSTEM_TIME);
}
Example #9
0
static gint64
user_time (void)
{
	return mono_process_get_data (GINT_TO_POINTER (mono_process_current_pid ()), MONO_PROCESS_USER_TIME);
}
Example #10
0
/**
 * 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;
}