1 | /* |
2 | * Copyright 2016-present Facebook, Inc. |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | |
17 | #include <folly/portability/SysTime.h> |
18 | |
19 | #ifdef _WIN32 |
20 | |
21 | #include <cstdint> |
22 | |
23 | extern "C" { |
24 | int gettimeofday(timeval* tv, struct timezone*) { |
25 | constexpr auto posixWinFtOffset = 116444736000000000ULL; |
26 | |
27 | if (tv) { |
28 | FILETIME ft; |
29 | ULARGE_INTEGER lft; |
30 | GetSystemTimeAsFileTime(&ft); |
31 | // As per the docs of FILETIME, don't just do an indirect |
32 | // pointer cast, to avoid alignment faults. |
33 | lft.HighPart = ft.dwHighDateTime; |
34 | lft.LowPart = ft.dwLowDateTime; |
35 | uint64_t ns = lft.QuadPart; |
36 | tv->tv_usec = (long)((ns / 10ULL) % 1000000ULL); |
37 | tv->tv_sec = (long)((ns - posixWinFtOffset) / 10000000ULL); |
38 | } |
39 | |
40 | return 0; |
41 | } |
42 | |
43 | void timeradd(timeval* a, timeval* b, timeval* res) { |
44 | res->tv_sec = a->tv_sec + b->tv_sec; |
45 | res->tv_usec = a->tv_usec + b->tv_usec; |
46 | if (res->tv_usec >= 1000000) { |
47 | res->tv_sec++; |
48 | res->tv_usec -= 1000000; |
49 | } |
50 | } |
51 | |
52 | void timersub(timeval* a, timeval* b, timeval* res) { |
53 | res->tv_sec = a->tv_sec - b->tv_sec; |
54 | res->tv_usec = a->tv_usec - b->tv_usec; |
55 | if (res->tv_usec < 0) { |
56 | res->tv_sec--; |
57 | res->tv_usec += 1000000; |
58 | } |
59 | } |
60 | } |
61 | |
62 | #endif |
63 | |