8aa7b1e802474e0df49143b7a67f0f3295327679
[swift-upb.git] / compat / hirestimeofday.cpp
1 /*
2  * Inspired by
3  * - http://msdn.microsoft.com/en-us/library/ms644904%28VS.85%29.aspx
4  * - Python-2.6.3/Modules/timemodule.c
5  */
6
7 #include <iostream>
8 #include "hirestimeofday.h"
9
10 #ifndef _WIN32
11 #include <sys/time.h>
12 #endif
13
14 namespace swift {
15
16 HiResTimeOfDay* HiResTimeOfDay::_instance = 0;
17
18 HiResTimeOfDay* HiResTimeOfDay::Instance()
19 {
20         if (_instance == 0)
21                 _instance = new HiResTimeOfDay();
22         return _instance;
23 }
24
25
26 #ifdef _WIN32
27 #include <windows.h>
28 #include <sys/timeb.h>
29
30
31 HiResTimeOfDay::HiResTimeOfDay(void)
32 {
33         frequency = getFrequency();
34         epochstart = getFTime();
35         epochcounter = getCounter();
36 }
37
38
39 tint HiResTimeOfDay::getTimeUSec(void)
40 {
41         LARGE_INTEGER currentcounter;
42         tint      currentstart;
43
44         currentstart = getFTime();
45     currentcounter = getCounter();
46
47     if (currentcounter.QuadPart < epochcounter.QuadPart)
48     {
49
50         // Wrap around detected, reestablish baseline
51         epochstart = currentstart;
52         epochcounter = currentcounter;
53     }
54     return epochstart + (1000000*(currentcounter.QuadPart-epochcounter.QuadPart))/frequency.QuadPart;
55 }
56
57
58 // Private
59 tint HiResTimeOfDay::getFTime()
60 {
61         struct timeb t;
62         ftime(&t);
63         tint usec;
64         usec =  t.time * 1000000;
65         usec += t.millitm * 1000;
66         return usec;
67 }
68
69
70
71 LARGE_INTEGER HiResTimeOfDay::getFrequency(void)
72 {
73     LARGE_INTEGER proc_freq;
74
75     if (!::QueryPerformanceFrequency(&proc_freq))
76         std::cerr << "HiResTimeOfDay: QueryPerformanceFrequency() failed";
77
78     return proc_freq;
79 }
80
81 LARGE_INTEGER HiResTimeOfDay::getCounter()
82 {
83     LARGE_INTEGER counter;
84
85     DWORD_PTR oldmask = ::SetThreadAffinityMask(::GetCurrentThread(), 0);
86     if (!::QueryPerformanceCounter(&counter))
87         std::cerr << "HiResTimeOfDay: QueryPerformanceCounter() failed";
88     ::SetThreadAffinityMask(::GetCurrentThread(), oldmask);
89
90     return counter;
91 }
92
93 #else
94
95 HiResTimeOfDay::HiResTimeOfDay(void)
96 {
97 }
98
99
100 tint HiResTimeOfDay::getTimeUSec(void)
101 {
102         struct timeval t;
103         gettimeofday(&t,NULL);
104         tint ret;
105         ret = t.tv_sec;
106         ret *= 1000000;
107         ret += t.tv_usec;
108         return ret;
109 }
110 #endif
111
112   
113   
114   
115 // ARNOTODO: move to swift.cpp
116
117 #ifdef _WIN32
118 static WSADATA _WSAData;
119 #endif
120   
121 void LibraryInit(void)
122 {
123 #ifdef _WIN32
124         // win32 requires you to initialize the Winsock DLL with the desired
125         // specification version
126         WORD wVersionRequested;
127     wVersionRequested = MAKEWORD(2, 2);
128         WSAStartup(wVersionRequested, &_WSAData);
129 #endif
130 }
131   
132   
133 } // end of namespace
134
135
136
137
138 #ifdef TEST
139 #include <iostream>
140
141 using namespace swift;
142
143 int main()
144 {
145         HiResTimeOfDay *t = HiResTimeOfDay::Instance();
146         for (int i=0; i<100; i++)
147         {
148                 tint st = t->getTimeUSec();
149                 Sleep(1000);
150                 tint et = t->getTimeUSec();
151                 tint diff = et - st;
152                 std::cout << "diffxTime is " << diff << "\n";
153         }
154         return 0;
155 }
156 #endif
157