Interruptible FFI calls with pthread_kill and CancelSynchronousIO. v4
[ghc-hetmet.git] / rts / win32 / GetTime.c
1 /* -----------------------------------------------------------------------------
2  *
3  * (c) The GHC Team 2005
4  *
5  * Machine-dependent time measurement functions
6  *
7  * ---------------------------------------------------------------------------*/
8
9 #include "Rts.h"
10 #include "GetTime.h"
11
12 #include <windows.h>
13
14 #ifdef HAVE_TIME_H
15 # include <time.h>
16 #endif
17
18 #define HNS_PER_SEC 10000000LL /* FILETIMES are in units of 100ns */
19 /* Convert FILETIMEs into secs */
20
21 static INLINE_ME Ticks
22 fileTimeToTicks(FILETIME ft)
23 {
24     Ticks t;
25     t = ((Ticks)ft.dwHighDateTime << 32) | ft.dwLowDateTime;
26     t = (t * TICKS_PER_SECOND) / HNS_PER_SEC;
27     return t;
28 }    
29
30 static int is_win9x = -1;
31
32 static INLINE_ME rtsBool
33 isWin9x(void)
34 {
35     if (is_win9x < 0) {
36         /* figure out whether we're on a Win9x box or not. */
37         OSVERSIONINFO oi;
38         BOOL b;
39         
40         /* Need to init the size field first.*/
41         oi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
42         b = GetVersionEx(&oi);
43       
44         is_win9x = ( (b && (oi.dwPlatformId & VER_PLATFORM_WIN32_WINDOWS)) ? 1 : 0);
45     }
46     return is_win9x;
47 }
48
49
50 void
51 getProcessTimes(Ticks *user, Ticks *elapsed)
52 {
53     *user    = getProcessCPUTime();
54     *elapsed = getProcessElapsedTime();
55 }
56
57 Ticks
58 getProcessCPUTime(void)
59 {
60     FILETIME creationTime, exitTime, userTime, kernelTime = {0,0};
61
62     if (isWin9x()) return getProcessElapsedTime();
63
64     if (!GetProcessTimes(GetCurrentProcess(), &creationTime,
65                          &exitTime, &kernelTime, &userTime)) {
66         return 0;
67     }
68
69     return fileTimeToTicks(userTime);
70 }
71
72 // getProcessElapsedTime relies on QueryPerformanceFrequency 
73 // which should be available on any Windows computer thay you
74 // would want to run Haskell on. Satnam Singh, 5 July 2010.
75
76 Ticks
77 getProcessElapsedTime(void)
78 {
79     // frequency represents the number of ticks per second
80     // used by the QueryPerformanceFrequency implementaiton
81     // and is represented by a 64-bit union type initially set to 0
82     // and updated just once (hence use of static).
83     static LARGE_INTEGER frequency = {.QuadPart = 0} ;  
84
85     // system_time is a 64-bit union type used to represent the
86     // tick count returned by QueryPerformanceCounter
87     LARGE_INTEGER system_time ;
88
89     // If this is the first time we are calling getProcessElapsedTime
90     // then record the ticks per second used by QueryPerformanceCounter
91     if (frequency.QuadPart == 0) {
92       QueryPerformanceFrequency(&frequency);
93     }
94     
95     // Get the tick count.
96     QueryPerformanceCounter(&system_time) ;
97
98     // Return the tick count as a millisecond value. 
99     // Using double to compute the intermediate value, because a 64-bit
100     // int would overflow when multiplied by TICKS_PER_SECOND in about 81 days.
101     return (Ticks)((TICKS_PER_SECOND * (double)system_time.QuadPart) / (double)frequency.QuadPart) ;
102 }
103
104 Ticks
105 getThreadCPUTime(void)
106 {
107     FILETIME creationTime, exitTime, userTime, kernelTime = {0,0};
108
109     if (isWin9x()) return getProcessCPUTime();
110
111     if (!GetThreadTimes(GetCurrentThread(), &creationTime,
112                         &exitTime, &kernelTime, &userTime)) {
113         return 0;
114     }
115
116     return fileTimeToTicks(userTime);
117 }
118
119 nat
120 getPageFaults(void)
121 {
122   /* ToDo (on NT): better, get this via the performance data
123      that's stored in the registry. */
124     return 0;
125 }