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
#include "cs_config.h"
30
* Standard C library headers
35
#if defined (HAVE_GETTIMEOFDAY)
39
#if defined (HAVE_GETRUSAGE)
41
#include <sys/resource.h>
43
#elif defined(_POSIX_SOURCE)
44
#include <sys/times.h>
49
* Optional library and ECS headers
53
#include "ecs_timer.h"
55
/*-----------------------------------------------------------------------------*/
60
} /* Fake brace to force back Emacs auto-indentation back to column 0 */
62
#endif /* __cplusplus */
64
/*-----------------------------------------------------------------------------*/
66
/*-----------------------------------------------------------------------------
67
* Local type definitions
68
*-----------------------------------------------------------------------------*/
70
/*-----------------------------------------------------------------------------
71
* Local function prototypes
72
*-----------------------------------------------------------------------------*/
74
/*-----------------------------------------------------------------------------
75
* Local static variable definitions
76
*-----------------------------------------------------------------------------*/
78
static _Bool _ecs_timer_initialized = false;
82
#if defined (HAVE_GETTIMEOFDAY)
83
static struct timeval _ecs_timer_wtime_tv_start;
85
static time_t _ecs_timer_wtime_start;
90
#if defined (HAVE_GETRUSAGE)
91
#elif defined(_POSIX_SOURCE)
92
static time_t _ecs_timer_unit = 0;
94
static clock_t _ecs_timer_clock_start;
97
/*-----------------------------------------------------------------------------
98
* Local function definitions
99
*-----------------------------------------------------------------------------*/
102
_ecs_timer_initialize(void)
104
#if defined (HAVE_GETTIMEOFDAY)
105
(void)gettimeofday(&_ecs_timer_wtime_tv_start, NULL);
107
(void)time(&_ecs_timer_wtime_start);
110
#if defined (HAVE_GETRUSAGE)
111
#elif defined(_POSIX_SOURCE)
112
_ecs_timer_unit = (double)sysconf(_SC_CLK_TCK);
114
_ecs_timer_clock_start = clock();
117
_ecs_timer_initialized = true;
120
/*============================================================================
121
* Public function definitions
122
*============================================================================*/
125
* \brief Return Wall clock time
127
* \return elapsed time from first call of a function of the ecs_timer_...()
128
* series, or -1 if unable to compute.
132
ecs_timer_wtime(void)
134
double this_wtime = -1.;
136
/* Ensure initialization */
138
if (_ecs_timer_initialized == false)
139
_ecs_timer_initialize();
141
/* Compute elapsed time */
143
#if defined (HAVE_GETTIMEOFDAY)
146
struct timeval wtime_tv_current;
148
if (gettimeofday(&wtime_tv_current, NULL) == 0) {
150
/* Perform carry for later subtraction */
151
if (_ecs_timer_wtime_tv_start.tv_usec > wtime_tv_current.tv_usec) {
152
int nsec = (_ecs_timer_wtime_tv_start.tv_usec - wtime_tv_current.tv_usec)
154
wtime_tv_current.tv_usec += 1000000 * nsec;
155
wtime_tv_current.tv_sec -= nsec;
157
if ( wtime_tv_current.tv_usec - _ecs_timer_wtime_tv_start.tv_usec
159
int nsec = (wtime_tv_current.tv_usec - _ecs_timer_wtime_tv_start.tv_usec)
161
wtime_tv_current.tv_usec -= 1000000 * nsec;
162
wtime_tv_current.tv_sec += nsec;
165
this_wtime = ( wtime_tv_current.tv_sec
166
- _ecs_timer_wtime_tv_start.tv_sec)
167
+ ( wtime_tv_current.tv_usec
168
- _ecs_timer_wtime_tv_start.tv_usec) * 1.e-6 ;
177
time_t wtime_current;
179
if (time(&wtime_current) != (time_t)-1)
180
this_wtime = difftime(wtime_current, _ecs_timer_wtime_start);
189
* \brief Return CPU time.
191
* Note that in the rare case that only the minimal C library clock()
192
* method is available (see ecs_timer_cpu_time_method()), at least one of
193
* the ecs_timer_...() functions (possibly this one) must be called
194
* upon program start for this function to be used. In addition,
195
* in this case, time may "loop" back to 0 every multiple of
196
* 2^size_t / CLOCKS_PER_SEC seconds.
198
* \return current CPU time usage, or -1 if unable to compute.
202
ecs_timer_cpu_time(void)
204
double cpu_time = -1.;
206
/* Ensure initialization */
208
if (_ecs_timer_initialized == 0)
209
_ecs_timer_initialize();
211
/* Compute CPU time */
213
#if defined (HAVE_GETRUSAGE)
218
if (getrusage(RUSAGE_SELF, &usage) == 0) {
219
cpu_time = usage.ru_utime.tv_sec + usage.ru_stime.tv_sec
220
+ (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) * 1.e-6;
224
#elif defined(_POSIX_SOURCE)
227
static struct tms ptimer;
229
if (_ecs_timer_unit != -1 && times(&ptimer) != -1) {
230
cpu_time = ((double)(ptimer.tms_utime + ptimer.tms_stime))
236
#else /* Use minimal C library function */
238
if (_ecs_timer_clock_start != -1) {
240
static clock_t clock_current;
242
clock_current = clock();
243
if (clock_current != (clock_t)-1)
245
= ((double)(clock_current - _ecs_timer_clock_start)) / CLOCKS_PER_SEC;
255
* \brief Return separate user and system CPU times.
257
* Note that in the rare case that only the minimal C library clock()
258
* method is available, this function will return -1 values.
260
* \param [out] user_time current user CPU usage.
261
* \param [out] system_time current system CPU usage.
265
ecs_timer_cpu_times(double *user_time,
268
/* Ensure initialization */
270
if (_ecs_timer_initialized == 0)
271
_ecs_timer_initialize();
276
/* Compute CPU time */
278
#if defined (HAVE_GETRUSAGE)
283
if (getrusage(RUSAGE_SELF, &usage) == 0) {
284
*user_time = usage.ru_utime.tv_sec + usage.ru_utime.tv_usec * 1.e-6;
285
*system_time = usage.ru_stime.tv_sec + usage.ru_stime.tv_usec * 1.e-6;
289
#elif defined(_POSIX_SOURCE)
292
static struct tms ptimer;
294
if (_ecs_timer_unit != -1 && times(&ptimer) != -1) {
295
*user_time = ((double)ptimer.tms_utime) / _ecs_timer_unit;
296
*system_time = ((double)ptimer.tms_stime) / _ecs_timer_unit;
304
/*-----------------------------------------------------------------------------*/
308
#endif /* __cplusplus */