0030959: OSD_Parallel_TBB: number of execution threads is strictly limited by the...
[occt.git] / src / OSD / OSD_Timer.cxx
1 // Created on: 1992-12-04
2 // Created by: Didier PIFFAULT , Mireille MERCIEN
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <OSD_Timer.hxx>
18
19 #ifndef _WIN32
20
21 #include <sys/time.h>
22
23 //=======================================================================
24 //function : GetWallClockTime
25 //purpose  : Get current time in seconds with system-defined precision
26 //=======================================================================
27
28 static inline Standard_Real GetWallClockTime ()
29 {
30   struct timeval tv;
31   // use time of first call as base for computing total time,
32   // to avoid loss of precision due to big values of tv_sec (counted since 1970)
33   static time_t startSec = (gettimeofday (&tv, NULL) ? 0 : tv.tv_sec);
34   return gettimeofday (&tv, NULL) ? 0. : (tv.tv_sec - startSec) + 0.000001 * tv.tv_usec;
35 }
36
37 #else
38
39 #include <windows.h>
40
41 //=======================================================================
42 //function : GetWallClockTime
43 //purpose  : Get current time in seconds with system-defined precision
44 //=======================================================================
45
46 static inline Standard_Real GetWallClockTime ()
47 {
48   // compute clock frequence on first call
49   static LARGE_INTEGER freq;
50   static BOOL isOk = QueryPerformanceFrequency (&freq);
51
52   LARGE_INTEGER time;
53   return isOk && QueryPerformanceCounter (&time) ? 
54          (Standard_Real)time.QuadPart / (Standard_Real)freq.QuadPart :
55 #ifndef OCCT_UWP
56          0.001 * GetTickCount();
57 #else
58          0.001 * GetTickCount64();
59 #endif
60 }
61
62 #endif /* _WIN32 */
63
64 namespace
65 {
66   //! Auxiliary function splits elapsed time in seconds into Hours, Minutes and Seconds.
67   //! @param theTimeSec [in]  elapsed time in seconds
68   //! @param theHours   [out] clamped elapsed hours
69   //! @param theMinutes [out] clamped elapsed minutes within range [0, 59]
70   //! @param theSeconds [out] clamped elapsed seconds within range [0, 60)
71   static void timeToHoursMinutesSeconds (Standard_Real     theTimeSec,
72                                          Standard_Integer& theHours,
73                                          Standard_Integer& theMinutes,
74                                          Standard_Real&    theSeconds)
75   {
76     Standard_Integer aSec = (Standard_Integer)theTimeSec;
77     theHours   = aSec / 3600;
78     theMinutes = (aSec - theHours * 3600) / 60;
79     theSeconds = theTimeSec - theHours * 3600 - theMinutes * 60;
80   }
81 }
82
83 //=======================================================================
84 //function : OSD_Timer
85 //purpose  : 
86 //=======================================================================
87
88 OSD_Timer::OSD_Timer (Standard_Boolean theThisThreadOnly)
89 : OSD_Chronometer (theThisThreadOnly),
90   myTimeStart (0.0),
91   myTimeCumul (0.0)
92 {
93   //
94 }
95
96 //=======================================================================
97 //function : Reset
98 //purpose  :
99 //=======================================================================
100
101 void OSD_Timer::Reset (const Standard_Real theTimeElapsedSec)
102 {
103   myTimeStart = 0.0;
104   myTimeCumul = theTimeElapsedSec;
105   OSD_Chronometer::Reset();
106 }
107
108 //=======================================================================
109 //function : Reset
110 //purpose  : 
111 //=======================================================================
112
113 void OSD_Timer::Reset ()
114 {
115   myTimeStart = myTimeCumul = 0.0;
116   OSD_Chronometer::Reset();
117 }
118
119 //=======================================================================
120 //function : Restart
121 //purpose  :
122 //=======================================================================
123
124 void OSD_Timer::Restart ()
125 {
126   myTimeStart = GetWallClockTime();
127   myTimeCumul = 0.0;
128   OSD_Chronometer::Restart();
129 }
130
131 //=======================================================================
132 //function : Show
133 //purpose  : 
134 //=======================================================================
135
136 void OSD_Timer::Show() const
137 {
138   Show (std::cout);
139 }
140
141 //=======================================================================
142 //function : ElapsedTime
143 //purpose  :
144 //=======================================================================
145
146 Standard_Real OSD_Timer::ElapsedTime() const
147 {
148   if (myIsStopped)
149   {
150     return myTimeCumul;
151   }
152
153   return myTimeCumul + GetWallClockTime() - myTimeStart;
154 }
155
156 //=======================================================================
157 //function : Show
158 //purpose  : 
159 //=======================================================================
160
161 void OSD_Timer::Show (Standard_Real&    theSeconds,
162                       Standard_Integer& theMinutes,
163                       Standard_Integer& theHours,
164                       Standard_Real&    theCPUtime) const
165 {
166   const Standard_Real aTimeCumul = myIsStopped
167                                  ? myTimeCumul
168                                  : myTimeCumul + GetWallClockTime() - myTimeStart;
169   timeToHoursMinutesSeconds (aTimeCumul, theHours, theMinutes, theSeconds);
170   OSD_Chronometer::Show (theCPUtime);
171 }
172
173 //=======================================================================
174 //function : Show
175 //purpose  : 
176 //=======================================================================
177
178 void OSD_Timer::Show (Standard_OStream& theOStream) const
179 {
180   const Standard_Real aTimeCumul = ElapsedTime();
181
182   Standard_Integer anHours, aMinutes;
183   Standard_Real    aSeconds;
184   timeToHoursMinutesSeconds (aTimeCumul, anHours, aMinutes, aSeconds);
185
186   std::streamsize prec = theOStream.precision (12);
187   theOStream << "Elapsed time: " << anHours  << " Hours "   <<
188                                     aMinutes << " Minutes " <<
189                                     aSeconds << " Seconds\n";
190   OSD_Chronometer::Show (theOStream);
191   theOStream.precision (prec);
192 }
193
194 //=======================================================================
195 //function : Stop
196 //purpose  : 
197 //=======================================================================
198
199 void OSD_Timer::Stop ()
200 {
201   if (!myIsStopped)
202   {
203     myTimeCumul += GetWallClockTime() - myTimeStart;
204     OSD_Chronometer::Stop();
205   }
206 }
207
208 //=======================================================================
209 //function : Start
210 //purpose  : 
211 //=======================================================================
212
213 void OSD_Timer::Start()
214 {
215   if (myIsStopped)
216   {
217     myTimeStart = GetWallClockTime();
218     OSD_Chronometer::Start();
219   }
220 }