File: hs_clock_win32.c

package info (click to toggle)
haskell-clock 0.8.4-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 100 kB
  • sloc: haskell: 178; ansic: 90; makefile: 2
file content (118 lines) | stat: -rw-r--r-- 2,951 bytes parent folder | download | duplicates (4)
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
#ifdef _WIN32
#include <windows.h>

#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
  #define U64(x) x##Ui64
#else
  #define U64(x) x##ULL
#endif

#define DELTA_EPOCH_IN_100NS  U64(116444736000000000)

static long ticks_to_nanos(LONGLONG subsecond_time, LONGLONG frequency)
{
    return (long)((1e9 * subsecond_time) / frequency);
}

static ULONGLONG to_quad_100ns(FILETIME ft)
{
    ULARGE_INTEGER li;
    li.LowPart = ft.dwLowDateTime;
    li.HighPart = ft.dwHighDateTime;
    return li.QuadPart;
}

static void to_timespec_from_100ns(ULONGLONG t_100ns, long long *t)
{
    t[0] = (long)(t_100ns / 10000000UL);
    t[1] = 100*(long)(t_100ns % 10000000UL);
}

/* See https://ghc.haskell.org/trac/ghc/ticket/15094 */
#if defined(_WIN32) && !defined(_WIN64)
__attribute__((optimize("-fno-expensive-optimizations")))
#endif
void hs_clock_win32_gettime_monotonic(long long* t)
{
   LARGE_INTEGER time;
   static LARGE_INTEGER frequency;
   static int hasFreq = 0;

   QueryPerformanceCounter(&time);
   if (!hasFreq)
   {
      hasFreq = 1;
      QueryPerformanceFrequency(&frequency);
   }
   // seconds
   t[0] = time.QuadPart / frequency.QuadPart;
   // nanos =
   t[1] = ticks_to_nanos(time.QuadPart % frequency.QuadPart, frequency.QuadPart);
}

void hs_clock_win32_gettime_realtime(long long* t)
{
    FILETIME ft;
    ULONGLONG tmp;

    GetSystemTimeAsFileTime(&ft);

    tmp = to_quad_100ns(ft);
    tmp -= DELTA_EPOCH_IN_100NS;

    to_timespec_from_100ns(tmp, t);
}

void hs_clock_win32_gettime_processtime(long long* t)
{
    FILETIME creation_time, exit_time, kernel_time, user_time;
    ULONGLONG time;

    GetProcessTimes(GetCurrentProcess(), &creation_time, &exit_time, &kernel_time, &user_time);
    // Both kernel and user, acc. to http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_117

    time = to_quad_100ns(user_time) + to_quad_100ns(kernel_time);
    to_timespec_from_100ns(time, t);
}

void hs_clock_win32_gettime_threadtime(long long* t)
{
    FILETIME creation_time, exit_time, kernel_time, user_time;
    ULONGLONG time;

    GetThreadTimes(GetCurrentThread(), &creation_time, &exit_time, &kernel_time, &user_time);
    // Both kernel and user, acc. to http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_117

    time = to_quad_100ns(user_time) + to_quad_100ns(kernel_time);
    to_timespec_from_100ns(time, t);
}

void hs_clock_win32_getres_monotonic(long long* t)
{
    LARGE_INTEGER frequency;
    QueryPerformanceFrequency(&frequency);

    ULONGLONG resolution = U64(1000000000)/frequency.QuadPart;
    t[0] = resolution / U64(1000000000);
    t[1] = resolution % U64(1000000000);
}

void hs_clock_win32_getres_realtime(long long* t)
{
    t[0] = 0;
    t[1] = 100;
}

void hs_clock_win32_getres_processtime(long long* t)
{
    t[0] = 0;
    t[1] = 100;
}

void hs_clock_win32_getres_threadtime(long long* t)
{
    t[0] = 0;
    t[1] = 100;
}

#endif	/* _WIN32 */