Welcome to mirror list, hosted at ThFree Co, Russian Federation.

mono-proclib-windows.c « utils « mono - github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: cc56ecbef1fccb0467ce00f309a8307a79dcec23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
 * \file
 * Windows proclib support for Mono.
 *
 * Copyright 2016 Microsoft
 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/

#include <config.h>
#include <glib.h>

#ifdef HOST_WIN32
#include <windows.h>
#include <mono/utils/mono-proclib.h>
#include <mono/utils/w32subset.h>

int
mono_process_current_pid ()
{
	return (int) GetCurrentProcessId ();
}

/**
 * mono_cpu_count:
 * \returns the number of processors on the system.
 */
int
mono_cpu_count (void)
{
	SYSTEM_INFO info;
	GetSystemInfo (&info);
	return info.dwNumberOfProcessors;
}

/*
 * This function returns the cpu usage in percentage,
 * normalized on the number of cores.
 */
#if HAVE_API_SUPPORT_WIN32_GET_SYSTEM_TIMES
gint32
mono_cpu_usage (MonoCpuUsageState *prev)
{
	gint32 cpu_usage = 0;
	gint64 cpu_total_time;
	gint64 cpu_busy_time;
	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;
	}

	if (cpu_total_time > 0 && cpu_busy_time > 0)
		cpu_usage = (gint32)(cpu_busy_time * 100 / cpu_total_time);

	return cpu_usage;
}
#elif HAVE_API_SUPPORT_WIN32_GET_SYSTEM_TIME_AS_FILE_TIME && HAVE_API_SUPPORT_WIN32_GET_PROCESS_TIMES
gint32
mono_cpu_usage (MonoCpuUsageState *prev)
{
	gint32 cpu_usage = 0;
	gint64 cpu_total_time;
	gint64 cpu_busy_time;
	guint64 idle_time;
	guint64 kernel_time;
	guint64 user_time;
	guint64 current_time;
	guint64 creation_time;
	guint64 exit_time;

	GetSystemTimeAsFileTime ((FILETIME*)&current_time);
	if (!GetProcessTimes (GetCurrentProcess (), (FILETIME*)&creation_time, (FILETIME*)&exit_time, (FILETIME*)&kernel_time, (FILETIME*)&user_time)) {
		g_error ("GetProcessTimes() failed, error code is %d\n", GetLastError ());
		return -1;
	}

	// GetProcessTimes user_time is a sum of user time spend by all threads in the process.
	// This means that the total user time can be more than real time. In order to adjust for this
	// the total available time that we can be scheduled depends on the number of available cores.
	// For example, having 2 threads running 100% on a 2 core system for 100 ms will return a user_time of 200ms
	// but the current_time - creation_time will only be 100ms but by adjusting the available time based on number of
	// of availalbe cores will gives use the total load of the process.
	guint64 total_available_time = (current_time - creation_time) * mono_cpu_count ();

	idle_time = total_available_time - (kernel_time + user_time);

	cpu_total_time = (gint64)((idle_time - (prev ? prev->idle_time : 0)) + (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;
	}

	if (cpu_total_time > 0 && cpu_busy_time > 0)
		cpu_usage = (gint32)(cpu_busy_time * 100 / cpu_total_time);

	return cpu_usage;
}
#elif !HAVE_EXTERN_DEFINED_WIN32_GET_SYSTEM_TIMES && !HAVE_EXTERN_DEFINED_WIN32_GET_SYSTEM_TIME_AS_FILE_TIME && !HAVE_EXTERN_DEFINED_WIN32_GET_PROCESS_TIMES
gint32
mono_cpu_usage (MonoCpuUsageState *prev)
{
	g_unsupported_api ("GetSystemTimes, GetSystemTimeAsFileTime, GetProcessTimes");
	SetLastError (ERROR_NOT_SUPPORTED);
	return -1;
}
#endif /* HAVE_API_SUPPORT_WIN32_GET_SYSTEM_TIMES */

#else

#include <mono/utils/mono-compiler.h>

MONO_EMPTY_SOURCE_FILE (mono_proclib_windows);

#endif /* HOST_WIN32*/