2000-04-27 22:03:57 +02:00
|
|
|
/**********
|
|
|
|
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
|
|
|
|
**********/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Date and time utility functions
|
|
|
|
|
*/
|
|
|
|
|
|
2011-12-11 19:05:00 +01:00
|
|
|
#include "ngspice/ngspice.h"
|
2000-07-03 17:32:29 +02:00
|
|
|
#include <string.h>
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2024-10-18 17:50:30 +02:00
|
|
|
#if defined(HAS_WINGUI) || defined(__MINGW32__) || defined(_MSC_VER)
|
|
|
|
|
#ifdef HAVE_QUERYPERFORMANCECOUNTER
|
|
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
|
|
|
/*
|
|
|
|
|
* The ngspice.h file included above defines BOOLEAN (via bool.h) and this
|
|
|
|
|
* clashes with the definition obtained from windows.h (via winnt.h).
|
|
|
|
|
* However, BOOLEAN is not used by this file so we can work round this problem
|
|
|
|
|
* by undefining BOOLEAN before including windows.h
|
|
|
|
|
* SJB - April 2005
|
|
|
|
|
*/
|
|
|
|
|
#undef BOOLEAN
|
|
|
|
|
#include <windows.h>
|
2000-04-27 22:03:57 +02:00
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
2024-10-18 17:50:30 +02:00
|
|
|
#include "misc_time.h"
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2024-10-18 17:50:30 +02:00
|
|
|
#ifdef USE_OMP
|
|
|
|
|
#include <omp.h>
|
|
|
|
|
#endif
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
/* Return the date. Return value is static data. */
|
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
|
datestring(void)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_LOCALTIME
|
|
|
|
|
static char tbuf[45];
|
|
|
|
|
struct tm *tp;
|
|
|
|
|
char *ap;
|
2010-11-02 18:20:05 +01:00
|
|
|
size_t i;
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
time_t tloc;
|
|
|
|
|
time(&tloc);
|
|
|
|
|
tp = localtime(&tloc);
|
|
|
|
|
ap = asctime(tp);
|
|
|
|
|
(void) sprintf(tbuf, "%.20s", ap);
|
|
|
|
|
(void) strcat(tbuf, ap + 19);
|
|
|
|
|
i = strlen(tbuf);
|
|
|
|
|
tbuf[i - 1] = '\0';
|
|
|
|
|
return (tbuf);
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
return ("today");
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* return time interval in seconds and milliseconds */
|
|
|
|
|
|
2024-10-18 17:50:30 +02:00
|
|
|
PerfTime timebegin;
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2024-10-18 17:50:30 +02:00
|
|
|
void timediff(PerfTime *now, PerfTime *begin, int *sec, int *msec)
|
2000-04-27 22:03:57 +02:00
|
|
|
{
|
|
|
|
|
|
2024-10-18 17:50:30 +02:00
|
|
|
*msec = (int) now->milliseconds - (int) begin->milliseconds;
|
|
|
|
|
*sec = (int) now->seconds - (int) begin->seconds;
|
2000-04-27 22:03:57 +02:00
|
|
|
if (*msec < 0) {
|
|
|
|
|
*msec += 1000;
|
|
|
|
|
(*sec)--;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2003-08-11 22:53:33 +02:00
|
|
|
/*
|
|
|
|
|
* How many seconds have elapsed in running time.
|
|
|
|
|
* This is the routine called in IFseconds
|
|
|
|
|
*/
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
double
|
|
|
|
|
seconds(void)
|
|
|
|
|
{
|
2024-10-18 17:50:30 +02:00
|
|
|
#ifdef USE_OMP
|
|
|
|
|
// Usage of OpenMP time function
|
|
|
|
|
return omp_get_wtime();
|
|
|
|
|
#elif defined(HAVE_QUERYPERFORMANCECOUNTER)
|
|
|
|
|
// Windows (MSC and mingw) specific implementation
|
|
|
|
|
LARGE_INTEGER frequency, counter;
|
|
|
|
|
QueryPerformanceFrequency(&frequency);
|
|
|
|
|
QueryPerformanceCounter(&counter);
|
|
|
|
|
return (double)counter.QuadPart / frequency.QuadPart;
|
|
|
|
|
#elif defined(HAVE_CLOCK_GETTIME)
|
|
|
|
|
struct timespec ts;
|
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
|
|
|
return ts.tv_sec + ts.tv_nsec / 1e9;
|
|
|
|
|
#elif defined(HAVE_GETTIMEOFDAY)
|
|
|
|
|
// Usage of gettimeofday
|
|
|
|
|
struct timeval tv;
|
|
|
|
|
gettimeofday(&tv, NULL);
|
|
|
|
|
return tv.tv_sec + tv.tv_usec / 1e6;
|
|
|
|
|
#elif defined(HAVE_TIMES)
|
|
|
|
|
// Usage of times
|
|
|
|
|
struct tms t;
|
|
|
|
|
clock_t ticks = times(&t);
|
|
|
|
|
return (double)ticks / sysconf(_SC_CLK_TCK);
|
|
|
|
|
#elif defined(HAVE_GETRUSAGE)
|
|
|
|
|
// Usage of getrusage
|
|
|
|
|
struct rusage usage;
|
|
|
|
|
getrusage(RUSAGE_SELF, &usage);
|
|
|
|
|
return usage.ru_utime.tv_sec + usage.ru_utime.tv_usec / 1e6;
|
|
|
|
|
#elif defined(HAVE_FTIME)
|
|
|
|
|
// Usage of ftime
|
|
|
|
|
struct timeb tb;
|
|
|
|
|
ftime(&tb);
|
|
|
|
|
return tb.time + tb.millitm / 1000.0;
|
2000-04-27 22:03:57 +02:00
|
|
|
#else
|
2024-10-18 17:50:30 +02:00
|
|
|
#error "No timer function available."
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2024-10-18 17:50:30 +02:00
|
|
|
void perf_timer_start(PerfTimer *timer)
|
|
|
|
|
{
|
|
|
|
|
timer->start = seconds();
|
|
|
|
|
}
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2024-10-18 17:50:30 +02:00
|
|
|
void perf_timer_stop(PerfTimer *timer)
|
|
|
|
|
{
|
|
|
|
|
timer->end = seconds();
|
|
|
|
|
}
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2024-10-18 17:50:30 +02:00
|
|
|
void perf_timer_elapsed_sec_ms(const PerfTimer *timer, int *seconds, int *milliseconds)
|
|
|
|
|
{
|
|
|
|
|
double elapsed = timer->end - timer->start;
|
|
|
|
|
*seconds = (int)elapsed;
|
|
|
|
|
*milliseconds = (int)((elapsed - *seconds) * 1000.0);
|
|
|
|
|
}
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2024-10-18 17:50:30 +02:00
|
|
|
void perf_timer_get_time(PerfTime *time)
|
|
|
|
|
{
|
|
|
|
|
double secs = seconds();
|
|
|
|
|
time->seconds = (int)secs;
|
|
|
|
|
time->milliseconds = (int)((secs - time->seconds) * 1000.0);
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
}
|