WSL/SLF GitLab Repository

Timer.cc 4.87 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/***********************************************************************************/
/*                   Copyright GridGroup, EIA-FR 2010                              */
/*  Copyright 2010 WSL Institute for Snow and Avalanche Research    SLF-DAVOS      */
/***********************************************************************************/
/* This file is part of MeteoIO.
    MeteoIO is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    MeteoIO is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with MeteoIO.  If not, see <http://www.gnu.org/licenses/>.
*/
//AUTHORS: Tuan Anh Nguyen (original implementation in popc)
//         Mathias Bavay (port and rewrite for Alpine3D, then MeteoIO)

#include <stdio.h>
23
#ifdef WIN32
24
25
26
27
28
29
30
31
	#include <windows.h>
	#undef max
	#undef min
#else
	#include <sys/time.h>
#endif

#include "Timer.h"
32
33
34
35

namespace mio {

/**
36
* @brief Default constructor.
37
38
* Initialize internal variables. It does NOT start timing.
*/
39
40
Timer::Timer()
     : start_point(0.), elapsed(0.), isRunning(false) {}
41
42

/**
43
* @brief Start the timer.
44
45
46
*/
void Timer::start() {
	if (!isRunning) {
47
48
		isRunning = true;
		start_point = getCurrentTime();
49
50
51
52
	}
}

/**
53
54
55
56
* @brief Reset and start the timer.
*/
void Timer::restart() {
	reset();
57
	isRunning = true;
58
59
60
61
}

/**
* @brief Stop the timer.
62
* It can be restarted afterward, adding time to what was already timed.
63
64
65
*/
void Timer::stop() {
	if (isRunning) {
66
		elapsed += static_cast<double>( getCurrentTime()-start_point );
67
		isRunning = false;
68
69
70
71
72
73
74
	}
}

/**
* @brief Reset the timer to zero.
*/
void Timer::reset() {
75
	elapsed = 0.;
76
	start_point = getCurrentTime();
77
78
79
}

/**
80
* @brief Get total elapsed time.
81
* It returns the sum of all the elapsed time between all the start/stop sessions since
82
* the timer was created or the last call to reset. Time is in seconds with microsecond resolution.
83
*/
84
double Timer::getElapsed() const {
85
	if (isRunning) {
86
		return elapsed + static_cast<double>(getCurrentTime()-start_point);
87
88
89
90
	}
	return elapsed;
}

91
#ifdef WIN32
92
long double Timer::getCurrentTime() const {
93
94
95
96
97
98
99
100
101
102
	SYSTEMTIME systemTime;
	GetSystemTime( &systemTime );

	FILETIME fileTime;
	SystemTimeToFileTime( &systemTime, &fileTime );

	ULARGE_INTEGER uli;
	uli.LowPart = fileTime.dwLowDateTime;
	uli.HighPart = fileTime.dwHighDateTime;

103
	const ULONGLONG units_convert = 10000*1000ULL; //it gives the time since 1 January 1601 (UTC) in units of 100ns
104
	const ULONGLONG offset_to_epoch = 11644473600ULL; //offset in seconds to Unix epoch, 134774 days * 24*3600
105
	return static_cast<long double>(uli.QuadPart - offset_to_epoch*units_convert) / units_convert;
106
107
}
#else
108
long double Timer::getCurrentTime() const {
109
110
	timeval tp;
	gettimeofday(&tp,NULL);
111
	const long double t = static_cast<long double>(tp.tv_sec) + static_cast<long double>(tp.tv_usec)*1.0e-6;
112
113
	return t;
}
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192

	
#endif

#ifndef WIN32
const int UsageTimer::who = RUSAGE_SELF;

UsageTimer::UsageTimer() : start_usage(), current_usage(), is_running(false), user_time(0.), sys_time(0.), elapsed(0.) {}

void	UsageTimer::start()
{
	if (!is_running) {
		is_running = true;
		getrusage(UsageTimer::who, &start_usage);
	}
}

void UsageTimer::stop() 
{
	if (is_running) {
		getElapsedTimes();
		is_running = false;
	}
}

void UsageTimer::restart() 
{
	reset();
	is_running = true;
}

void UsageTimer::reset() {
	user_time = sys_time = elapsed= 0.;
}

double UsageTimer::getElapsed()
{
	if (is_running) {
		getElapsedTimes();
	}

	return elapsed;
}

double UsageTimer::getElapsedUserTime()
{
	if (is_running) {
		getElapsedTimes();
	}

	return user_time;
}

double UsageTimer::getElapsedSystemTime()
{
	if (is_running) {
		getElapsedTimes();
	}

	return sys_time;
}

void UsageTimer::getElapsedTimes()
{
	getrusage(UsageTimer::who, &current_usage);
	
	//calculate start point
	double start_user_time = static_cast<double>(start_usage.ru_utime.tv_sec) + static_cast<double>(start_usage.ru_utime.tv_usec) / 1000000.;
	double start_sys_time  = static_cast<double>(start_usage.ru_stime.tv_sec) + static_cast<double>(start_usage.ru_stime.tv_usec) / 1000000.;
	
	//calculate end point
	double end_user_time = static_cast<double>(current_usage.ru_utime.tv_sec) + static_cast<double>(current_usage.ru_utime.tv_usec) / 1000000;
	double end_sys_time  = static_cast<double>(current_usage.ru_stime.tv_sec) + static_cast<double>(current_usage.ru_stime.tv_usec) / 1000000;

	//calculate different elapsed times
	user_time = end_user_time - start_user_time;
	sys_time = end_sys_time - start_sys_time;
	elapsed = sys_time + user_time;
}
193
#endif
194
195
196

} //namespace