1
/*============================================================================
2
* Program timing information
3
*============================================================================*/
6
This file is part of Code_Saturne, a general-purpose CFD tool.
8
Copyright (C) 1998-2011 EDF S.A.
10
This program is free software; you can redistribute it and/or modify it under
11
the terms of the GNU General Public License as published by the Free Software
12
Foundation; either version 2 of the License, or (at your option) any later
15
This program is distributed in the hope that it will be useful, but WITHOUT
16
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
20
You should have received a copy of the GNU General Public License along with
21
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
22
Street, Fifth Floor, Boston, MA 02110-1301, USA.
25
/*----------------------------------------------------------------------------*/
27
#if defined(HAVE_CONFIG_H)
28
#include "cs_config.h"
31
#include "bft_config_defs.h"
34
* Standard C library headers
39
#if defined (HAVE_GETTIMEOFDAY)
43
#if defined (HAVE_GETRUSAGE)
45
#include <sys/resource.h>
47
#elif defined(_POSIX_SOURCE)
48
#include <sys/times.h>
53
* Optional library and BFT headers
56
#include "bft_timer.h"
58
/*-----------------------------------------------------------------------------*/
63
} /* Fake brace to force back Emacs auto-indentation back to column 0 */
65
#endif /* __cplusplus */
67
/*-----------------------------------------------------------------------------*/
69
/*-----------------------------------------------------------------------------
70
* Local type definitions
71
*-----------------------------------------------------------------------------*/
73
/*-----------------------------------------------------------------------------
74
* Local function prototypes
75
*-----------------------------------------------------------------------------*/
77
/*-----------------------------------------------------------------------------
78
* Local static variable definitions
79
*-----------------------------------------------------------------------------*/
81
static _Bool _bft_timer_initialized = false;
85
#if defined (HAVE_GETTIMEOFDAY)
86
static struct timeval _bft_timer_wtime_tv_start;
88
static time_t _bft_timer_wtime_start;
93
#if defined (HAVE_GETRUSAGE)
94
#elif defined(_POSIX_SOURCE)
95
static time_t _bft_timer_unit = 0;
97
static clock_t _bft_timer_clock_start;
100
/*-----------------------------------------------------------------------------
101
* Local function definitions
102
*-----------------------------------------------------------------------------*/
105
_bft_timer_initialize(void)
107
#if defined (HAVE_GETTIMEOFDAY)
108
(void)gettimeofday(&_bft_timer_wtime_tv_start, NULL);
110
(void)time(&_bft_timer_wtime_start);
113
#if defined (HAVE_GETRUSAGE)
114
#elif defined(_POSIX_SOURCE)
115
_bft_timer_unit = (double)sysconf(_SC_CLK_TCK);
117
_bft_timer_clock_start = clock();
120
_bft_timer_initialized = true;
123
/*============================================================================
124
* Public function definitions
125
*============================================================================*/
128
* \brief Return Wall clock time
130
* \return elapsed time from first call of a function of the bft_timer_...()
131
* series, or -1 if unable to compute.
135
bft_timer_wtime(void)
137
double this_wtime = -1.;
139
/* Ensure initialization */
141
if (_bft_timer_initialized == false)
142
_bft_timer_initialize();
144
/* Compute elapsed time */
146
#if defined (HAVE_GETTIMEOFDAY)
149
struct timeval wtime_tv_current;
151
if (gettimeofday(&wtime_tv_current, NULL) == 0) {
153
/* Perform carry for later subtraction */
154
if (_bft_timer_wtime_tv_start.tv_usec > wtime_tv_current.tv_usec) {
155
int nsec = (_bft_timer_wtime_tv_start.tv_usec - wtime_tv_current.tv_usec)
157
wtime_tv_current.tv_usec += 1000000 * nsec;
158
wtime_tv_current.tv_sec -= nsec;
160
if ( wtime_tv_current.tv_usec - _bft_timer_wtime_tv_start.tv_usec
162
int nsec = (wtime_tv_current.tv_usec - _bft_timer_wtime_tv_start.tv_usec)
164
wtime_tv_current.tv_usec -= 1000000 * nsec;
165
wtime_tv_current.tv_sec += nsec;
168
this_wtime = ( wtime_tv_current.tv_sec
169
- _bft_timer_wtime_tv_start.tv_sec)
170
+ ( wtime_tv_current.tv_usec
171
- _bft_timer_wtime_tv_start.tv_usec) * 1.e-6 ;
180
time_t wtime_current;
182
if (time(&wtime_current) != (time_t)-1)
183
this_wtime = difftime(wtime_current, _bft_timer_wtime_start);
192
* \brief Return CPU time.
194
* Note that in the rare case that only the minimal C library clock()
195
* method is available (see bft_timer_cpu_time_method()), at least one of
196
* the bft_timer_...() functions (possibly this one) must be called
197
* upon program start for this function to be used. In addition,
198
* in this case, time may "loop" back to 0 every multiple of
199
* 2^size_t / CLOCKS_PER_SEC seconds.
201
* \return current CPU time usage, or -1 if unable to compute.
205
bft_timer_cpu_time(void)
207
double cpu_time = -1.;
209
/* Ensure initialization */
211
if (_bft_timer_initialized == 0)
212
_bft_timer_initialize();
214
/* Compute CPU time */
216
#if defined (HAVE_GETRUSAGE)
221
if (getrusage(RUSAGE_SELF, &usage) == 0) {
222
cpu_time = usage.ru_utime.tv_sec + usage.ru_stime.tv_sec
223
+ (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) * 1.e-6;
227
#elif defined(_POSIX_SOURCE)
230
static struct tms ptimer;
232
if (_bft_timer_unit != -1 && times(&ptimer) != -1) {
233
cpu_time = ((double)(ptimer.tms_utime + ptimer.tms_stime))
239
#else /* Use minimal C library function */
241
if (_bft_timer_clock_start != -1) {
243
static clock_t clock_current;
245
clock_current = clock();
246
if (clock_current != (clock_t)-1)
248
= ((double)(clock_current - _bft_timer_clock_start)) / CLOCKS_PER_SEC;
258
* \brief Return separate user and system CPU times.
260
* Note that in the rare case that only the minimal C library clock()
261
* method is available, this function will return -1 values.
263
* \param [out] user_time current user CPU usage.
264
* \param [out] system_time current system CPU usage.
268
bft_timer_cpu_times(double *user_time,
272
/* Ensure initialization */
274
if (_bft_timer_initialized == 0)
275
_bft_timer_initialize();
280
/* Compute CPU time */
282
#if defined (HAVE_GETRUSAGE)
287
if (getrusage(RUSAGE_SELF, &usage) == 0) {
288
*user_time = usage.ru_utime.tv_sec + usage.ru_utime.tv_usec * 1.e-6;
289
*system_time = usage.ru_stime.tv_sec + usage.ru_stime.tv_usec * 1.e-6;
293
#elif defined(_POSIX_SOURCE)
296
static struct tms ptimer;
298
if (_bft_timer_unit != -1 && times(&ptimer) != -1) {
299
*user_time = ((double)ptimer.tms_utime) / _bft_timer_unit;
300
*system_time = ((double)ptimer.tms_stime) / _bft_timer_unit;
309
* \brief Return method used to return wall clock time.
311
* \return short description of method used to return wall clock time.
315
bft_timer_wtime_method(void)
317
if (_bft_timer_initialized == 0)
318
_bft_timer_initialize();
320
#if defined (HAVE_GETTIMEOFDAY)
321
return _("gettimeofday() function");
323
return _("Iso C time() function");
328
* \brief Return method used to return CPU time.
330
* \return short description of method used to return CPU time.
334
bft_timer_cpu_time_method(void)
336
if (_bft_timer_initialized == 0)
337
_bft_timer_initialize();
339
#if defined (HAVE_GETRUSAGE)
340
return _("getrusage() function");
341
#elif defined(_POSIX_SOURCE)
342
return _("Posix times() function");
344
return _("Iso C clock() function");
348
/*-----------------------------------------------------------------------------*/
352
#endif /* __cplusplus */