e278eccede20f27e62a11c510de17b2df351e7cd
[mono.git] / mono / utils / mono-proclib-windows-uwp.c
1 /*
2  * mono-proclib-windows-uwp.c: UWP proclib support for Mono.
3  *
4  * Copyright 2016 Microsoft
5  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
6 */
7 #include <config.h>
8 #include <glib.h>
9
10 #if G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT)
11 #include <Windows.h>
12 #include <mono/utils/mono-proclib.h>
13
14 gint32
15 mono_cpu_usage (MonoCpuUsageState *prev)
16 {
17         gint32 cpu_usage = 0;
18         gint64 cpu_total_time;
19         gint64 cpu_busy_time;
20         guint64 idle_time;
21         guint64 kernel_time;
22         guint64 user_time;
23         guint64 current_time;
24         guint64 creation_time;
25         guint64 exit_time;
26
27         GetSystemTimeAsFileTime ((FILETIME*)&current_time);
28         if (!GetProcessTimes (GetCurrentProcess (), (FILETIME*)&creation_time, (FILETIME*)&exit_time, (FILETIME*)&kernel_time, (FILETIME*)&user_time)) {
29                 g_error ("GetProcessTimes() failed, error code is %d\n", GetLastError ());
30                 return -1;
31         }
32
33         // GetProcessTimes user_time is a sum of user time spend by all threads in the process.
34         // This means that the total user time can be more than real time. In order to adjust for this
35         // the total available time that we can be scheduled depends on the number of available cores.
36         // For example, having 2 threads running 100% on a 2 core system for 100 ms will return a user_time of 200ms
37         // but the current_time - creation_time will only be 100ms but by adjusting the available time based on number of
38         // of availalbe cores will gives use the total load of the process.
39         guint64 total_available_time = (current_time - creation_time) * mono_cpu_count ();
40
41         idle_time = total_available_time - (kernel_time + user_time);
42
43         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)));
44         cpu_busy_time = (gint64)(cpu_total_time - (idle_time - (prev ? prev->idle_time : 0)));
45
46         if (prev) {
47                 prev->idle_time = idle_time;
48                 prev->kernel_time = kernel_time;
49                 prev->user_time = user_time;
50         }
51
52         if (cpu_total_time > 0 && cpu_busy_time > 0)
53                 cpu_usage = (gint32)(cpu_busy_time * 100 / cpu_total_time);
54
55         return cpu_usage;
56 }
57
58 #else /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
59
60 #ifdef _MSC_VER
61 // Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
62 void __mono_win32_mono_proclib_windows_uwp_quiet_lnk4221(void) {}
63 #endif
64 #endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */