1 /*! \file elapsed_time.cpp
2 \brief time esurment functions
3 \author Atsushi Suzuki, Laboratoire Jacques-Louis Lions
4 \date Jun. 4th 2013
5 \date Jul. 12th 2015
6 \date Nov. 30th 2016
7 */
8
9 // This file is part of Dissection
10 //
11 // Dissection is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // Linking Dissection statically or dynamically with other modules is making
17 // a combined work based on Disssection. Thus, the terms and conditions of
18 // the GNU General Public License cover the whole combination.
19 //
20 // As a special exception, the copyright holders of Dissection give you
21 // permission to combine Dissection program with free software programs or
22 // libraries that are released under the GNU LGPL and with independent modules
23 // that communicate with Dissection solely through the Dissection-fortran
24 // interface. You may copy and distribute such a system following the terms of
25 // the GNU GPL for Dissection and the licenses of the other code concerned,
26 // provided that you include the source code of that other code when and as
27 // the GNU GPL requires distribution of source code and provided that you do
28 // not modify the Dissection-fortran interface.
29 //
30 // Note that people who make modified versions of Dissection are not obligated
31 // to grant this special exception for their modified versions; it is their
32 // choice whether to do so. The GNU General Public License gives permission to
33 // release a modified version without this exception; this exception also makes
34 // it possible to release a modified version which carries forward this
35 // exception. If you modify the Dissection-fortran interface, this exception
36 // does not apply to your modified version of Dissection, and you must remove
37 // this exception when you distribute your modified version.
38 //
39 // This exception is an additional permission under section 7 of the GNU
40 // General Public License, version 3 ("GPLv3")
41 //
42 // Dissection is distributed in the hope that it will be useful,
43 // but WITHOUT ANY WARRANTY; without even the implied warranty of
44 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45 // GNU General Public License for more details.
46 //
47 // You should have received a copy of the GNU General Public License
48 // along with Dissection. If not, see <http://www.gnu.org/licenses/>.
49 //
50
51 #include "elapsed_time.hpp"
52 #ifdef CLOCK_GETTIME
53 #ifdef _MSC_VER // added by Yann Collette
54
55 // From http://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows
56
getFILETIMEoffset()57 LARGE_INTEGER getFILETIMEoffset()
58 {
59 SYSTEMTIME s;
60 FILETIME f;
61 LARGE_INTEGER t;
62
63 s.wYear = 1970;
64 s.wMonth = 1;
65 s.wDay = 1;
66 s.wHour = 0;
67 s.wMinute = 0;
68 s.wSecond = 0;
69 s.wMilliseconds = 0;
70 SystemTimeToFileTime(&s, &f);
71 t.QuadPart = f.dwHighDateTime;
72 t.QuadPart <<= 32;
73 t.QuadPart |= f.dwLowDateTime;
74 return (t);
75 }
76
clock_gettime(int X,struct timeval * tv)77 int clock_gettime(int X, struct timeval *tv)
78 {
79 LARGE_INTEGER t;
80 FILETIME f;
81 double microseconds;
82 static LARGE_INTEGER offset;
83 static double frequencyToMicroseconds;
84 static int initialized = 0;
85 static BOOL usePerformanceCounter = 0;
86
87 if (!initialized) {
88 LARGE_INTEGER performanceFrequency;
89 initialized = 1;
90 usePerformanceCounter = QueryPerformanceFrequency(&performanceFrequency);
91 if (usePerformanceCounter) {
92 QueryPerformanceCounter(&offset);
93 frequencyToMicroseconds = (double)performanceFrequency.QuadPart / 1000000.;
94 } else {
95 offset = getFILETIMEoffset();
96 frequencyToMicroseconds = 10.;
97 }
98 }
99 if (usePerformanceCounter) QueryPerformanceCounter(&t);
100 else {
101 GetSystemTimeAsFileTime(&f);
102 t.QuadPart = f.dwHighDateTime;
103 t.QuadPart <<= 32;
104 t.QuadPart |= f.dwLowDateTime;
105 }
106
107 t.QuadPart -= offset.QuadPart;
108 microseconds = (double)t.QuadPart / frequencyToMicroseconds;
109 t.QuadPart = microseconds;
110 tv->tv_sec = t.QuadPart / 1000000;
111 tv->tv_usec = t.QuadPart % 1000000;
112 return (0);
113 }
114
get_realtime(elapsed_t * tm)115 void get_realtime(elapsed_t *tm)
116 {
117 clock_gettime(0, (timeval *)tm);
118 }
119
convert_time(elapsed_t time1,elapsed_t time0)120 double convert_time(elapsed_t time1, elapsed_t time0)
121 {
122 return ((double)time1.tv_sec - (double)time0.tv_sec +
123 ((double)time1.tv_usec - (double)time0.tv_usec) / 1.0e+6);
124 }
125
convert_sec(elapsed_t t)126 int convert_sec(elapsed_t t)
127 {
128 return (int)t.tv_sec;
129 }
130
convert_microsec(elapsed_t t)131 int convert_microsec(elapsed_t t)
132 {
133 return (int)(t.tv_usec);
134 }
135 #else // _MSC_VER
get_realtime(elapsed_t * tm)136 void get_realtime(elapsed_t *tm)
137 {
138 //clock_gettime(CLOCK_REALTIME, tm);
139 clock_gettime(CLOCK_MONOTONIC, tm);
140 }
141
convert_time(elapsed_t time1,elapsed_t time0)142 double convert_time(elapsed_t time1, elapsed_t time0)
143 {
144 double t;
145 t = ((double)time1.tv_sec -
146 (double)time0.tv_sec +
147 ((double)time1.tv_nsec -
148 (double)time0.tv_nsec) / 1.0e+9);
149 return t;
150 }
151
convert_sec(elapsed_t t)152 int convert_sec(elapsed_t t)
153 {
154 return (int)t.tv_sec;
155 }
156
convert_microsec(elapsed_t t)157 int convert_microsec(elapsed_t t)
158 {
159 return (int)(t.tv_nsec / 1.0e+3);
160 }
161 #endif // _MSC_VER
162 #else /* #ifdef CLOCK_GETTIME */
163 #ifdef GETRUSAGE
get_realtime(elapsed_t * tm)164 void get_realtime(elapsed_t *tm)
165 {
166 getrusage(RUSAGE_SELF, tm);
167 }
168
convert_time(elapsed_t time1,elapsed_t time0)169 double convert_time(elapsed_t time1, elapsed_t time0)
170 {
171 double t;
172 t = ((double)time1.ru_utime.tv_sec -
173 (double)time0.ru_utime.tv_sec +
174 (double)time1.ru_stime.tv_sec -
175 (double)time0.ru_stime.tv_sec +
176 ((double)time1.ru_utime.tv_usec -
177 (double)time0.ru_utime.tv_usec +
178 (double)time1.ru_stime.tv_usec -
179 (double)time0.ru_stime.tv_usec) / 1.0e+6);
180 return t;
181 }
182
convert_sec(elapsed_t t)183 int convert_sec(elapsed_t t)
184 {
185 int t0 = (int)(t.ru_utime.tv_sec + t.ru_stime.tv_sec);
186 int t1 = (int)(t.ru_utime.tv_usec + t.ru_stime.tv_usec);
187 return (int)(t0 + t1 / 1000000);
188 }
189
convert_microsec(elapsed_t t)190 int convert_microsec(elapsed_t t)
191 {
192 int t1 = (int)(t.ru_utime.tv_usec + t.ru_stime.tv_usec);
193 return (int)(t1 % 1000000);
194 }
195
196 #else
197 #ifdef CLOCK
198
get_realtime(elapsed_t * tm)199 void get_realtime(elapsed_t *tm)
200 {
201 *tm = clock();
202 }
203
convert_time(elapsed_t time1,elapsed_t time0)204 double convert_time(elapsed_t time1, elapsed_t time0)
205 {
206 double t;
207 t = (time1 - time0) / CLOCKS_PER_SEC;
208 return t;
209 }
210
convert_sec(elapsed_t t)211 int convert_sec(elapsed_t t)
212 {
213 return (int)(t / CLOCKS_PER_SEC);
214 }
215
convert_microsec(elapsed_t t)216 int convert_microsec(elapsed_t t)
217 {
218 return (int)((t * 1.0e+3) / CLOCKS_PER_SEC);
219 }
220
221 #else
get_realtime(elapsed_t * tm)222 void get_realtime(elapsed_t *tm)
223 {
224 gettimeofday(tm, (struct timezone *)0);
225 }
226
convert_time(elapsed_t time1,elapsed_t time0)227 double convert_time(elapsed_t time1, elapsed_t time0)
228 {
229 double t;
230 t = ((double)time1.tv_sec -
231 (double)time0.tv_sec +
232 ((double)time1.tv_usec -
233 (double)time0.tv_usec) / 1.0e+6);
234 return t;
235 }
236
237
convert_sec(elapsed_t t)238 int convert_sec(elapsed_t t)
239 {
240 return (int)t.tv_sec;
241 }
242
convert_microsec(elapsed_t t)243 int convert_microsec(elapsed_t t)
244 {
245 return (int)t.tv_usec;
246 }
247 #endif /* #ifdef CLOCK */
248 #endif /* #ifdef GETRUSAGE */
249 #endif /* #ifdef CLOCK_GETTIME */
250