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