winverbs/nd: do not convert timeout status value
[mirror/winof/.git] / etc / user / gtod.c
1 /*\r
2  * This software is available to you under the OpenFabrics.org BSD license\r
3  * below:\r
4  *\r
5  *     Redistribution and use in source and binary forms, with or\r
6  *     without modification, are permitted provided that the following\r
7  *     conditions are met:\r
8  *\r
9  *      - Redistributions of source code must retain the above\r
10  *        copyright notice, this list of conditions and the following\r
11  *        disclaimer.\r
12  *\r
13  *      - Redistributions in binary form must reproduce the above\r
14  *        copyright notice, this list of conditions and the following\r
15  *        disclaimer in the documentation and/or other materials\r
16  *        provided with the distribution.\r
17  *\r
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
21  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
22  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
23  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
24  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
25  * SOFTWARE.\r
26  */\r
27 \r
28 #ifndef _GTOD_C_\r
29 #define _GTOD_C_\r
30 \r
31 /*\r
32  * int gettimeofday(struct timeval *ptv, void *ignored)\r
33  */\r
34 \r
35 #include <windows.h>\r
36 #include <winsock2.h>\r
37 \r
38 \r
39 static __inline\r
40 void FileTimeToTimeval(LPFILETIME pft, struct timeval * ptv)\r
41 { /* Note that LONGLONG is a 64-bit value */\r
42         LONGLONG ll;\r
43 \r
44         if(!pft || !ptv) {\r
45                 ptv->tv_sec = 0;\r
46                 ptv->tv_usec = 0;\r
47                 return;\r
48         }\r
49 \r
50         ll = ((LONGLONG) pft->dwHighDateTime << 32);\r
51         ll += (LONGLONG) pft->dwLowDateTime;\r
52         ll -= 116444736000000000;\r
53 \r
54         ptv->tv_sec = (long) (ll / 10000000);\r
55         ptv->tv_usec = (long) (ll - ((LONGLONG)(ptv->tv_sec) * 10000000)) / 10;\r
56 }\r
57 \r
58 \r
59 // static __inline\r
60 int gettimeofday(struct timeval *ptv, void *ignored)\r
61 {\r
62         static int QueryCounter = 2;\r
63         FILETIME CurrentTime;\r
64         UNREFERENCED_PARAMETER(ignored);     \r
65 \r
66         if(!ptv) return -1;\r
67 \r
68         if(QueryCounter)\r
69         {\r
70                 static LARGE_INTEGER Frequency;\r
71                 static LARGE_INTEGER Offset; /* counter offset for right time*/\r
72                 static LARGE_INTEGER LastCounter;\r
73                 LARGE_INTEGER Time;\r
74                 LARGE_INTEGER Counter;\r
75         \r
76                 GetSystemTimeAsFileTime(&CurrentTime);\r
77                 QueryPerformanceCounter(&Counter);\r
78         \r
79                 if(QueryCounter == 2)\r
80                 {\r
81                         QueryCounter = 1;\r
82                         if(!QueryPerformanceFrequency(&Frequency))\r
83                         {\r
84                                 QueryCounter = 0;\r
85                                 Frequency.QuadPart = 10000000; /* prevent division by 0 */\r
86                         }\r
87         \r
88                         /* get time as a large integer */\r
89                         Counter.HighPart &= 0x7FL; /* Clear high bits to prevent overflow */\r
90                         Offset.LowPart = CurrentTime.dwLowDateTime;\r
91                         Offset.HighPart = (LONG) CurrentTime.dwHighDateTime;\r
92                         Offset.QuadPart -= Counter.QuadPart * 10000000 / Frequency.QuadPart;\r
93                 }\r
94         \r
95                 /* Convert counter to a 100 nanoseconds resolution timer value. */\r
96         \r
97                 Counter.HighPart &= 0x7FL; /* Clear high bits to prevent overflows */\r
98                 Counter.QuadPart *= 10000000; /* need time stamp in 100 ns units */\r
99                 Counter.QuadPart /= Frequency.QuadPart;/* counter of 0.1 microseconds */\r
100         \r
101                 if(LastCounter.QuadPart > Counter.QuadPart)\r
102                 { /* Counter value wrapped */\r
103                         Offset.QuadPart += (0x7F00000000*10000000) / Frequency.QuadPart;\r
104                 }\r
105                 LastCounter = Counter;\r
106         \r
107                 /* Add the in previous call calculated offset */\r
108                 Counter.QuadPart += Offset.QuadPart;\r
109         \r
110                 /* get time as a large integer */\r
111                 Time.LowPart = CurrentTime.dwLowDateTime;\r
112                 Time.HighPart = (LONG) CurrentTime.dwHighDateTime;\r
113         \r
114                 /* keep time difference within an interval of +- 0.1 seconds\r
115                 relative to the time function by adjusting the counters offset */\r
116         \r
117                 if( ((Time.QuadPart + 1000000) < Counter.QuadPart) ||\r
118                                 ((Time.QuadPart - 1000000) > Counter.QuadPart) )\r
119                 { /* Adjust the offset */\r
120                         Offset.QuadPart += Time.QuadPart - Counter.QuadPart;\r
121                         Counter.QuadPart = Time.QuadPart;\r
122                 }\r
123         \r
124                 /* use the adjusted performance counter time for the time stamp */\r
125                 CurrentTime.dwLowDateTime = Counter.LowPart;\r
126                 CurrentTime.dwHighDateTime = Counter.HighPart;\r
127         }\r
128         else\r
129         {\r
130                 GetSystemTimeAsFileTime(&CurrentTime);\r
131         }\r
132 \r
133         FileTimeToTimeval(&CurrentTime,ptv);\r
134 \r
135         return(0);\r
136 }\r
137 \r
138 #endif /* _GTOD_C_ */\r