* Updated source file copyright headers to remove "Copyright by the Board of Trustees of the University of Illinois", which is kept in the top-level COPYING file.
657 lines
21 KiB
C
657 lines
21 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* Copyright by The HDF Group. *
|
|
* All rights reserved. *
|
|
* *
|
|
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
|
* terms governing use, modification, and redistribution, is contained in *
|
|
* the COPYING file, which can be found at the root of the source code *
|
|
* distribution tree, or in https://www.hdfgroup.org/licenses. *
|
|
* If you do not have access to either file, you may request a copy from *
|
|
* help@hdfgroup.org. *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Created: H5timer.c
|
|
* Aug 21 2006
|
|
* Quincey Koziol
|
|
*
|
|
* Purpose: Internal, platform-independent 'timer' support routines.
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
|
|
/****************/
|
|
/* Module Setup */
|
|
/****************/
|
|
#include "H5module.h" /* This source code file is part of the H5 module */
|
|
|
|
/***********/
|
|
/* Headers */
|
|
/***********/
|
|
#include "H5private.h" /* Generic Functions */
|
|
|
|
/****************/
|
|
/* Local Macros */
|
|
/****************/
|
|
|
|
/* Size of a generated time string.
|
|
* Most time strings should be < 20 or so characters (max!) so this should be a
|
|
* safe size. Dynamically allocating the correct size would be painful.
|
|
*/
|
|
#define H5TIMER_TIME_STRING_LEN 1536
|
|
|
|
/* Conversion factors */
|
|
#define H5_SEC_PER_DAY (24.0 * 60.0 * 60.0)
|
|
#define H5_SEC_PER_HOUR (60.0 * 60.0)
|
|
#define H5_SEC_PER_MIN (60.0)
|
|
|
|
/******************/
|
|
/* Local Typedefs */
|
|
/******************/
|
|
|
|
/********************/
|
|
/* Package Typedefs */
|
|
/********************/
|
|
|
|
/********************/
|
|
/* Local Prototypes */
|
|
/********************/
|
|
|
|
/*********************/
|
|
/* Package Variables */
|
|
/*********************/
|
|
|
|
/*****************************/
|
|
/* Library Private Variables */
|
|
/*****************************/
|
|
|
|
/*******************/
|
|
/* Local Variables */
|
|
/*******************/
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5_bandwidth
|
|
*
|
|
* Purpose: Prints the bandwidth (bytes per second) in a field 10
|
|
* characters wide widh four digits of precision like this:
|
|
*
|
|
* NaN If <=0 seconds
|
|
* 1234. TB/s
|
|
* 123.4 TB/s
|
|
* 12.34 GB/s
|
|
* 1.234 MB/s
|
|
* 4.000 kB/s
|
|
* 1.000 B/s
|
|
* 0.000 B/s If NBYTES==0
|
|
* 1.2345e-10 For bandwidth less than 1
|
|
* 6.7893e+94 For exceptionally large values
|
|
* 6.678e+106 For really big values
|
|
*
|
|
* Return: void
|
|
*
|
|
* Programmer: Robb Matzke
|
|
* Wednesday, August 5, 1998
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
void
|
|
H5_bandwidth(char *buf /*out*/, size_t bufsize, double nbytes, double nseconds)
|
|
{
|
|
double bw;
|
|
|
|
if (nseconds <= 0.0)
|
|
HDstrcpy(buf, " NaN");
|
|
else {
|
|
bw = nbytes / nseconds;
|
|
if (H5_DBL_ABS_EQUAL(bw, 0.0))
|
|
HDstrcpy(buf, "0.000 B/s");
|
|
else if (bw < 1.0)
|
|
HDsnprintf(buf, bufsize, "%10.4e", bw);
|
|
else if (bw < (double)H5_KB) {
|
|
HDsnprintf(buf, bufsize, "%05.4f", bw);
|
|
HDstrcpy(buf + 5, " B/s");
|
|
}
|
|
else if (bw < (double)H5_MB) {
|
|
HDsnprintf(buf, bufsize, "%05.4f", bw / (double)H5_KB);
|
|
HDstrcpy(buf + 5, " kB/s");
|
|
}
|
|
else if (bw < (double)H5_GB) {
|
|
HDsnprintf(buf, bufsize, "%05.4f", bw / (double)H5_MB);
|
|
HDstrcpy(buf + 5, " MB/s");
|
|
}
|
|
else if (bw < (double)H5_TB) {
|
|
HDsnprintf(buf, bufsize, "%05.4f", bw / (double)H5_GB);
|
|
HDstrcpy(buf + 5, " GB/s");
|
|
}
|
|
else if (bw < (double)H5_PB) {
|
|
HDsnprintf(buf, bufsize, "%05.4f", bw / (double)H5_TB);
|
|
HDstrcpy(buf + 5, " TB/s");
|
|
}
|
|
else if (bw < (double)H5_EB) {
|
|
HDsnprintf(buf, bufsize, "%05.4f", bw / (double)H5_PB);
|
|
HDstrcpy(buf + 5, " PB/s");
|
|
}
|
|
else {
|
|
HDsnprintf(buf, bufsize, "%10.4e", bw);
|
|
if (HDstrlen(buf) > 10)
|
|
HDsnprintf(buf, bufsize, "%10.3e", bw);
|
|
} /* end else-if */
|
|
} /* end else */
|
|
} /* end H5_bandwidth() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5_now
|
|
*
|
|
* Purpose: Retrieves the current time, as seconds after the UNIX epoch.
|
|
*
|
|
* Return: # of seconds from the epoch (can't fail)
|
|
*
|
|
* Programmer: Quincey Koziol
|
|
* Tuesday, November 28, 2006
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
time_t
|
|
H5_now(void)
|
|
{
|
|
time_t now; /* Current time */
|
|
|
|
#ifdef H5_HAVE_GETTIMEOFDAY
|
|
{
|
|
struct timeval now_tv;
|
|
|
|
HDgettimeofday(&now_tv, NULL);
|
|
now = now_tv.tv_sec;
|
|
}
|
|
#else /* H5_HAVE_GETTIMEOFDAY */
|
|
now = HDtime(NULL);
|
|
#endif /* H5_HAVE_GETTIMEOFDAY */
|
|
|
|
return (now);
|
|
} /* end H5_now() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5_now_usec
|
|
*
|
|
* Purpose: Retrieves the current time, as microseconds after the UNIX epoch.
|
|
*
|
|
* Return: # of microseconds from the epoch (can't fail)
|
|
*
|
|
* Programmer: Quincey Koziol
|
|
* Tuesday, November 28, 2006
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
uint64_t
|
|
H5_now_usec(void)
|
|
{
|
|
uint64_t now; /* Current time, in microseconds */
|
|
|
|
#if defined(H5_HAVE_CLOCK_GETTIME)
|
|
{
|
|
struct timespec ts;
|
|
|
|
HDclock_gettime(CLOCK_MONOTONIC, &ts);
|
|
|
|
/* Cast all values in this expression to uint64_t to ensure that all intermediate
|
|
* calculations are done in 64 bit, to prevent overflow */
|
|
now = ((uint64_t)ts.tv_sec * ((uint64_t)1000 * (uint64_t)1000)) +
|
|
((uint64_t)ts.tv_nsec / (uint64_t)1000);
|
|
}
|
|
#elif defined(H5_HAVE_GETTIMEOFDAY)
|
|
{
|
|
struct timeval now_tv;
|
|
|
|
HDgettimeofday(&now_tv, NULL);
|
|
|
|
/* Cast all values in this expression to uint64_t to ensure that all intermediate
|
|
* calculations are done in 64 bit, to prevent overflow */
|
|
now = ((uint64_t)now_tv.tv_sec * ((uint64_t)1000 * (uint64_t)1000)) + (uint64_t)now_tv.tv_usec;
|
|
}
|
|
#else /* H5_HAVE_GETTIMEOFDAY */
|
|
/* Cast all values in this expression to uint64_t to ensure that all intermediate calculations
|
|
* are done in 64 bit, to prevent overflow */
|
|
now = ((uint64_t)HDtime(NULL) * ((uint64_t)1000 * (uint64_t)1000));
|
|
#endif /* H5_HAVE_GETTIMEOFDAY */
|
|
|
|
return (now);
|
|
} /* end H5_now_usec() */
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* Function: H5_get_time
|
|
*
|
|
* Purpose: Get the current time, as the time of seconds after the UNIX epoch
|
|
*
|
|
* Return: Success: A non-negative time value
|
|
* Failure: -1.0 (in theory, can't currently fail)
|
|
*
|
|
* Programmer: Quincey Koziol
|
|
* October 05, 2016
|
|
*--------------------------------------------------------------------------
|
|
*/
|
|
double
|
|
H5_get_time(void)
|
|
{
|
|
double ret_value = 0.0;
|
|
|
|
FUNC_ENTER_NOAPI_NOINIT_NOERR
|
|
|
|
#if defined(H5_HAVE_CLOCK_GETTIME)
|
|
{
|
|
struct timespec ts;
|
|
|
|
HDclock_gettime(CLOCK_MONOTONIC, &ts);
|
|
ret_value = (double)ts.tv_sec + ((double)ts.tv_nsec / 1000000000.0);
|
|
}
|
|
#elif defined(H5_HAVE_GETTIMEOFDAY)
|
|
{
|
|
struct timeval now_tv;
|
|
|
|
HDgettimeofday(&now_tv, NULL);
|
|
ret_value = (double)now_tv.tv_sec + ((double)now_tv.tv_usec / 1000000.0);
|
|
}
|
|
#else
|
|
ret_value = (double)HDtime(NULL);
|
|
#endif
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5_get_time() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5__timer_get_timevals
|
|
*
|
|
* Purpose: Internal platform-specific function to get time system,
|
|
* user and elapsed time values.
|
|
*
|
|
* Return: Success: 0
|
|
* Failure: -1
|
|
*
|
|
* Programmer: Dana Robinson
|
|
* May 2011
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static herr_t
|
|
H5__timer_get_timevals(H5_timevals_t *times /*in,out*/)
|
|
{
|
|
/* Sanity check */
|
|
HDassert(times);
|
|
|
|
/* Windows call handles both system/user and elapsed times */
|
|
#ifdef H5_HAVE_WIN32_API
|
|
if (H5_get_win32_times(times) < 0) {
|
|
times->elapsed = -1.0;
|
|
times->system = -1.0;
|
|
times->user = -1.0;
|
|
|
|
return -1;
|
|
} /* end if */
|
|
#else /* H5_HAVE_WIN32_API */
|
|
|
|
/*************************
|
|
* System and user times *
|
|
*************************/
|
|
#if defined(H5_HAVE_GETRUSAGE)
|
|
{
|
|
struct rusage res;
|
|
|
|
if (HDgetrusage(RUSAGE_SELF, &res) < 0)
|
|
return -1;
|
|
times->system = (double)res.ru_stime.tv_sec + ((double)res.ru_stime.tv_usec / 1.0E6);
|
|
times->user = (double)res.ru_utime.tv_sec + ((double)res.ru_utime.tv_usec / 1.0E6);
|
|
}
|
|
#else
|
|
/* No suitable way to get system/user times */
|
|
/* This is not an error condition, they just won't be available */
|
|
times->system = -1.0;
|
|
times->user = -1.0;
|
|
#endif
|
|
|
|
/****************
|
|
* Elapsed time *
|
|
****************/
|
|
|
|
times->elapsed = H5_get_time();
|
|
|
|
#endif /* H5_HAVE_WIN32_API */
|
|
|
|
return 0;
|
|
} /* end H5__timer_get_timevals() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5_timer_init
|
|
*
|
|
* Purpose: Initialize a platform-independent timer.
|
|
*
|
|
* Timer usage is as follows:
|
|
*
|
|
* 1) Call H5_timer_init(), passing in a timer struct, to set
|
|
* up the timer.
|
|
*
|
|
* 2) Wrap any code you'd like to time with calls to
|
|
* H5_timer_start/stop(). For accurate timing, place these
|
|
* calls as close to the code of interest as possible. You
|
|
* can call start/stop multiple times on the same timer -
|
|
* when you do this, H5_timer_get_times() will return time
|
|
* values for the current/last session and
|
|
* H5_timer_get_total_times() will return the summed times
|
|
* of all sessions (see #3 and #4, below).
|
|
*
|
|
* 3) Use H5_timer_get_times() to get the current system, user
|
|
* and elapsed times from a running timer. If called on a
|
|
* stopped timer, this will return the time recorded at the
|
|
* stop point.
|
|
*
|
|
* 4) Call H5_timer_get_total_times() to get the total system,
|
|
* user and elapsed times recorded across multiple start/stop
|
|
* sessions. If called on a running timer, it will return the
|
|
* time recorded up to that point. On a stopped timer, it
|
|
* will return the time recorded at the stop point.
|
|
*
|
|
* NOTE: Obtaining a time point is not free! Keep in mind that
|
|
* the time functions make system calls and can have
|
|
* non-trivial overhead. If you call one of the get_time
|
|
* functions on a running timer, that overhead will be
|
|
* added to the reported times.
|
|
*
|
|
* 5) All times recorded will be in seconds. These can be
|
|
* converted into human-readable strings with the
|
|
* H5_timer_get_time_string() function.
|
|
*
|
|
* 6) A timer can be reset using by calling H5_timer_init() on
|
|
* it. This will set its state to 'stopped' and reset all
|
|
* accumulated times to zero.
|
|
*
|
|
*
|
|
* Return: Success: 0
|
|
* Failure: -1
|
|
*
|
|
* Programmer: Dana Robinson
|
|
* May 2011
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5_timer_init(H5_timer_t *timer /*in,out*/)
|
|
{
|
|
/* Sanity check */
|
|
HDassert(timer);
|
|
|
|
/* Initialize everything */
|
|
HDmemset(timer, 0, sizeof(H5_timer_t));
|
|
|
|
return 0;
|
|
} /* end H5_timer_init() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5_timer_start
|
|
*
|
|
* Purpose: Start tracking time in a platform-independent timer.
|
|
*
|
|
* Return: Success: 0
|
|
* Failure: -1
|
|
*
|
|
* Programmer: Dana Robinson
|
|
* May 2011
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5_timer_start(H5_timer_t *timer /*in,out*/)
|
|
{
|
|
/* Sanity check */
|
|
HDassert(timer);
|
|
|
|
/* Start the timer
|
|
* This sets the "initial" times to the system-defined start times.
|
|
*/
|
|
if (H5__timer_get_timevals(&(timer->initial)) < 0)
|
|
return -1;
|
|
|
|
timer->is_running = TRUE;
|
|
|
|
return 0;
|
|
} /* end H5_timer_start() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5_timer_stop
|
|
*
|
|
* Purpose: Stop tracking time in a platform-independent timer.
|
|
*
|
|
* Return: Success: 0
|
|
* Failure: -1
|
|
*
|
|
* Programmer: Dana Robinson
|
|
* May 2011
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5_timer_stop(H5_timer_t *timer /*in,out*/)
|
|
{
|
|
/* Sanity check */
|
|
HDassert(timer);
|
|
|
|
/* Stop the timer */
|
|
if (H5__timer_get_timevals(&(timer->final_interval)) < 0)
|
|
return -1;
|
|
|
|
/* The "final" times are stored as intervals (final - initial)
|
|
* for more useful reporting to the user.
|
|
*/
|
|
timer->final_interval.elapsed = timer->final_interval.elapsed - timer->initial.elapsed;
|
|
timer->final_interval.system = timer->final_interval.system - timer->initial.system;
|
|
timer->final_interval.user = timer->final_interval.user - timer->initial.user;
|
|
|
|
/* Add the intervals to the elapsed time */
|
|
timer->total.elapsed += timer->final_interval.elapsed;
|
|
timer->total.system += timer->final_interval.system;
|
|
timer->total.user += timer->final_interval.user;
|
|
|
|
timer->is_running = FALSE;
|
|
|
|
return 0;
|
|
} /* end H5_timer_stop() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5_timer_get_times
|
|
*
|
|
* Purpose: Get the system, user and elapsed times from a timer. These
|
|
* are the times since the timer was last started and will be
|
|
* 0.0 in a timer that has not been started since it was
|
|
* initialized.
|
|
*
|
|
* This function can be called either before or after
|
|
* H5_timer_stop() has been called. If it is called before the
|
|
* stop function, the timer will continue to run.
|
|
*
|
|
* The system and user times will be -1.0 if those times cannot
|
|
* be computed on a particular platform. The elapsed time will
|
|
* always be present.
|
|
*
|
|
* Return: Success: 0
|
|
* Failure: -1
|
|
*
|
|
* Programmer: Dana Robinson
|
|
* May 2011
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5_timer_get_times(H5_timer_t timer, H5_timevals_t *times /*in,out*/)
|
|
{
|
|
/* Sanity check */
|
|
HDassert(times);
|
|
|
|
if (timer.is_running) {
|
|
H5_timevals_t now;
|
|
|
|
/* Get the current times and report the current intervals without
|
|
* stopping the timer.
|
|
*/
|
|
if (H5__timer_get_timevals(&now) < 0)
|
|
return -1;
|
|
|
|
times->elapsed = now.elapsed - timer.initial.elapsed;
|
|
times->system = now.system - timer.initial.system;
|
|
times->user = now.user - timer.initial.user;
|
|
} /* end if */
|
|
else {
|
|
times->elapsed = timer.final_interval.elapsed;
|
|
times->system = timer.final_interval.system;
|
|
times->user = timer.final_interval.user;
|
|
} /* end else */
|
|
|
|
return 0;
|
|
} /* end H5_timer_get_times() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5_timer_get_total_times
|
|
*
|
|
* Purpose: Get the TOTAL system, user and elapsed times recorded by
|
|
* the timer since its initialization. This is the sum of all
|
|
* times recorded while the timer was running.
|
|
*
|
|
* These will be 0.0 in a timer that has not been started
|
|
* since it was initialized. Calling H5_timer_init() on a
|
|
* timer will reset these values to 0.0.
|
|
*
|
|
* This function can be called either before or after
|
|
* H5_timer_stop() has been called. If it is called before the
|
|
* stop function, the timer will continue to run.
|
|
*
|
|
* The system and user times will be -1.0 if those times cannot
|
|
* be computed on a particular platform. The elapsed time will
|
|
* always be present.
|
|
*
|
|
* Return: Success: 0
|
|
* Failure: -1
|
|
*
|
|
* Programmer: Dana Robinson
|
|
* May 2011
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5_timer_get_total_times(H5_timer_t timer, H5_timevals_t *times /*in,out*/)
|
|
{
|
|
/* Sanity check */
|
|
HDassert(times);
|
|
|
|
if (timer.is_running) {
|
|
H5_timevals_t now;
|
|
|
|
/* Get the current times and report the current totals without
|
|
* stopping the timer.
|
|
*/
|
|
if (H5__timer_get_timevals(&now) < 0)
|
|
return -1;
|
|
|
|
times->elapsed = timer.total.elapsed + (now.elapsed - timer.initial.elapsed);
|
|
times->system = timer.total.system + (now.system - timer.initial.system);
|
|
times->user = timer.total.user + (now.user - timer.initial.user);
|
|
} /* end if */
|
|
else {
|
|
times->elapsed = timer.total.elapsed;
|
|
times->system = timer.total.system;
|
|
times->user = timer.total.user;
|
|
} /* end else */
|
|
|
|
return 0;
|
|
} /* end H5_timer_get_total_times() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5_timer_get_time_string
|
|
*
|
|
* Purpose: Converts a time (in seconds) into a human-readable string
|
|
* suitable for log messages.
|
|
*
|
|
* Return: Success: The time string.
|
|
*
|
|
* The general format of the time string is:
|
|
*
|
|
* "N/A" time < 0 (invalid time)
|
|
* "%.f ns" time < 1 microsecond
|
|
* "%.1f us" time < 1 millisecond
|
|
* "%.1f ms" time < 1 second
|
|
* "%.2f s" time < 1 minute
|
|
* "%.f m %.f s" time < 1 hour
|
|
* "%.f h %.f m %.f s" longer times
|
|
*
|
|
* Failure: NULL
|
|
*
|
|
* Programmer: Dana Robinson
|
|
* May 2011
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
char *
|
|
H5_timer_get_time_string(double seconds)
|
|
{
|
|
char *s; /* output string */
|
|
|
|
/* Used when the time is greater than 59 seconds */
|
|
double days = 0.0;
|
|
double hours = 0.0;
|
|
double minutes = 0.0;
|
|
double remainder_sec = 0.0;
|
|
|
|
/* Extract larger time units from count of seconds */
|
|
if (seconds > 60.0) {
|
|
/* Set initial # of seconds */
|
|
remainder_sec = seconds;
|
|
|
|
/* Extract days */
|
|
days = HDfloor(remainder_sec / H5_SEC_PER_DAY);
|
|
remainder_sec -= (days * H5_SEC_PER_DAY);
|
|
|
|
/* Extract hours */
|
|
hours = HDfloor(remainder_sec / H5_SEC_PER_HOUR);
|
|
remainder_sec -= (hours * H5_SEC_PER_HOUR);
|
|
|
|
/* Extract minutes */
|
|
minutes = HDfloor(remainder_sec / H5_SEC_PER_MIN);
|
|
remainder_sec -= (minutes * H5_SEC_PER_MIN);
|
|
|
|
/* The # of seconds left is in remainder_sec */
|
|
} /* end if */
|
|
|
|
/* Allocate */
|
|
if (NULL == (s = (char *)HDcalloc(H5TIMER_TIME_STRING_LEN, sizeof(char))))
|
|
return NULL;
|
|
|
|
/* Do we need a format string? Some people might like a certain
|
|
* number of milliseconds or s before spilling to the next highest
|
|
* time unit. Perhaps this could be passed as an integer.
|
|
* (name? round_up_size? ?)
|
|
*/
|
|
if (seconds < 0.0)
|
|
HDsnprintf(s, H5TIMER_TIME_STRING_LEN, "N/A");
|
|
else if (H5_DBL_ABS_EQUAL(0.0, seconds))
|
|
HDsnprintf(s, H5TIMER_TIME_STRING_LEN, "0.0 s");
|
|
else if (seconds < 1.0E-6)
|
|
/* t < 1 us, Print time in ns */
|
|
HDsnprintf(s, H5TIMER_TIME_STRING_LEN, "%.f ns", seconds * 1.0E9);
|
|
else if (seconds < 1.0E-3)
|
|
/* t < 1 ms, Print time in us */
|
|
HDsnprintf(s, H5TIMER_TIME_STRING_LEN, "%.1f us", seconds * 1.0E6);
|
|
else if (seconds < 1.0)
|
|
/* t < 1 s, Print time in ms */
|
|
HDsnprintf(s, H5TIMER_TIME_STRING_LEN, "%.1f ms", seconds * 1.0E3);
|
|
else if (seconds < H5_SEC_PER_MIN)
|
|
/* t < 1 m, Print time in s */
|
|
HDsnprintf(s, H5TIMER_TIME_STRING_LEN, "%.2f s", seconds);
|
|
else if (seconds < H5_SEC_PER_HOUR)
|
|
/* t < 1 h, Print time in m and s */
|
|
HDsnprintf(s, H5TIMER_TIME_STRING_LEN, "%.f m %.f s", minutes, remainder_sec);
|
|
else if (seconds < H5_SEC_PER_DAY)
|
|
/* t < 1 d, Print time in h, m and s */
|
|
HDsnprintf(s, H5TIMER_TIME_STRING_LEN, "%.f h %.f m %.f s", hours, minutes, remainder_sec);
|
|
else
|
|
/* Print time in d, h, m and s */
|
|
HDsnprintf(s, H5TIMER_TIME_STRING_LEN, "%.f d %.f h %.f m %.f s", days, hours, minutes,
|
|
remainder_sec);
|
|
|
|
return s;
|
|
} /* end H5_timer_get_time_string() */
|