354c3c4b47f08e9f074698996bdb045689f6d992
[scilab.git] / scilab / modules / core / includes / timer.hxx
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2008-2008 - DIGITEO - Bruno JOFRET
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  * === LICENSE_END ===
14  *
15  */
16
17 #ifndef __TIMER_HXX__
18 #define __TIMER_HXX__
19
20 #ifndef _MSC_VER
21 #include <sys/time.h>
22 #else
23 #define NOMINMAX
24 #include <windows.h>
25 #undef NOMINMAX
26 #endif
27 #include <iostream>
28 #include <iomanip>
29
30 class Timer
31 {
32
33 private:
34 #ifndef _MSC_VER
35     int start_hour;
36     int start_min;
37     int start_sec;
38     int start_usec;
39 #else
40     LARGE_INTEGER iStart;
41     LARGE_INTEGER iEnd;
42     LARGE_INTEGER iFreq;
43 #endif
44
45 public:
46
47     //===========================================================================
48     // Return the total time that the timer has been in the "running"
49     // state since it was first "started" or last "restarted".  For
50     // "short" time periods (less than an hour), the actual cpu time
51     // used is reported instead of the elapsed time.
52
53     inline double elapsed_time(bool _bRestart = false)
54     {
55         // FIXME : Tonio
56 #ifndef _MSC_VER
57         struct timeval tv;
58         struct timezone tz;
59         struct tm *tm;
60         gettimeofday(&tv, &tz);
61         tm = localtime(&tv.tv_sec);
62         double dblTime = ( 3600000.0 * (tm->tm_hour - start_hour) +
63                            60000.0 * (tm->tm_min - start_min) +
64                            1000.0 * (tm->tm_sec - start_sec) +
65                            (1.0 * (tv.tv_usec - start_usec)) / 1000.0
66                          );
67 #else
68         QueryPerformanceCounter(&iEnd);
69         double dblTime  = ((iEnd.QuadPart - iStart.QuadPart) * 1000.0) / iFreq.QuadPart;
70 #endif
71
72         if (_bRestart == true)
73         {
74             start();
75         }
76         return dblTime;
77     } // timer::elapsed_time
78 public:
79     Timer()
80     {
81 #ifndef _MSC_VER
82         start_hour      = 0;
83         start_min               = 0;
84         start_sec               = 0;
85         start_usec      = 0;
86 #else
87         iStart.QuadPart = 0;
88         iEnd.QuadPart           = 0;
89         QueryPerformanceFrequency(&iFreq);
90 #endif
91     }
92
93     //===========================================================================
94     // Start a timer.  If it is already running, let it continue running.
95     // Print an optional message.
96
97     inline void start(const std::wstring _msg = std::wstring(L""))
98     {
99         // Print an optional message, something like "Starting timer t";
100         if (_msg.empty() == false)
101         {
102             std::wcerr << _msg << std::endl;
103         }
104 #ifndef _MSC_VER
105         // FIXME : Tonio
106
107         // Set the start time
108         struct timeval tv;
109         struct timezone tz;
110         struct tm *tm;
111         gettimeofday(&tv, &tz);
112         tm = localtime(&tv.tv_sec);
113         start_hour = tm->tm_hour;
114         start_min = tm->tm_min;
115         start_sec = tm->tm_sec;
116         start_usec = tv.tv_usec;
117 #else
118         QueryPerformanceCounter(&iStart);
119 #endif
120     } // timer::start
121
122     //===========================================================================
123     // Stop the timer and print an optional message.
124
125     //===========================================================================
126     // Print out an optional message followed by the current timer timing.
127
128     inline double check(const std::wstring& _msg, bool _bRestart = false)
129     {
130         // Print an optional message, something like "Checking timer t";
131         double t = elapsed_time();
132         if (_msg.empty() == false)
133         {
134             std::wcerr << L"[" << _msg << L"]" << L" : ";
135         }
136         std::wcerr << L"Elapsed time ["
137                    << std::setiosflags(std::ios::fixed)
138                    << std::setprecision(3)
139                    << t << L"] milliseconds"
140                    << std::endl;
141
142         if (_bRestart == true)
143         {
144             start();
145         }
146         return t;
147     } // timer::check
148
149 };
150
151 //===========================================================================
152 // Allow timers to be printed to ostreams using the syntax 'os << t'
153 // for an ostream 'os' and a timer 't'.  For example, "cout << t" will
154 // print out the total amount of time 't' has been "running".
155
156 inline std::wostream& operator<<(std::wostream& os, Timer& t)
157 {
158     os << std::setprecision(3)
159        << std::setiosflags(std::ios::fixed)
160        << t.elapsed_time() ;
161     return os;
162 }
163
164 //===========================================================================
165 #endif /* !__TIMER_HXX__ */