Rev 83446 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
/** R : A Computer Language for Statistical Data Analysis* Copyright (C) 2000-2016 The R Core Team.** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.** This program 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 General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, a copy is available at* https://www.R-project.org/Licenses/*** Interfaces to time functions.*//*Notes on various time functions:===============================The current (2008/13) POSIX recommendation to find the calendartime is to call clock_gettime(), defined in <time.h>. This mayalso be used to find the time since some unspecified startingpoint (e.g. machine reboot), but is not currently so used in R.It returns in second and nanoseconds, although not necessarily tomore than clock-tick accuracy.C11 adds 'struct timespec' to <time.h>. And timespec_get() whichcan get the current time or interval after a base time.The previous POSIX recommendation was gettimeofday(), defined in<sys/time.h>. This returns in seconds and microseconds (withunspecified granularity).Many systems (including AIX, FreeBSD, Linux, Solaris) haveclock_gettime(): it appeared in macOS 10.12. macOS and Cygwinhave gettimeofday().Function time() is C99 and defined in <time.h>. C99 does notmandate the units, but POSIX does (as the number of seconds sincethe epoch: although not mandated, time_t seems always to be aninteger type).Function clock() is C99 and defined in <time.h>. It measures CPUtime at CLOCKS_PER_SEC: there is a small danger of integeroverflow.Function times() is POSIX and defined in <sys/times.h>. Itreturns the elapsed time in clock ticks, plus CPU times in astruct tms* argument (also in clock ticks).More precise information on CPU times may be available from thePOSIX function getrusage() defined in <sys/resource.h>. Thisreturns the same time structure as gettimeofday() and on somesystems offers millisecond resolution.It is available on Cygwin, FreeBSD, macOS, Linux and Solaris.currentTime() (in this file) usesclock_gettime(): AIX, FreeBSD, Linux, Solaris, macOS >= 10.12gettimeofday(): macOS <= 10.11, Windows, Cygwintime() (as ultimate fallback, AFAIK unused).proc.time() uses currentTime() for elapsed time,and getrusage, then times for CPU times on a Unix-alike,GetProcessTimes on Windows.devPS.c uses time() and localtime() for timestamps.do_date (platform.c) uses ctime.*/#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <Defn.h>#include <Internal.h>#include <time.h>/* clock_gettime, timespec_get time are in <time.h> */#ifdef HAVE_SYS_TIME_H/* gettimeoday, including on Windows */# include <sys/time.h>#endifdouble currentTime(void){double ans = NA_REAL;#ifdef HAVE_TIMESPEC_GETstruct timespec tp;int res = timespec_get(&tp, TIME_UTC);if(res != 0)ans = (double) tp.tv_sec + 1e-9 * (double) tp.tv_nsec;#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)/* Has 2038 issue if time_t: tv.tv_sec is 32-bit. */struct timespec tp;int res = clock_gettime(CLOCK_REALTIME, &tp);if(res == 0)ans = (double) tp.tv_sec + 1e-9 * (double) tp.tv_nsec;#elif defined(HAVE_GETTIMEOFDAY)/* macOS , mingw.org, used on mingw-w64.Has 2038 issue if time_t: tv.tv_sec is 32-bit.*/struct timeval tv;int res = gettimeofday(&tv, NULL);if(res == 0)ans = (double) tv.tv_sec + 1e-6 * (double) tv.tv_usec;#else/* No known current OSes */time_t res = time(NULL);if(res != (time_t)(-1)) /* -1 must be an error as the real value -1was ca 1969 */ans = (double) res;#endif#ifndef HAVE_POSIX_LEAPSECONDS/* No known current OSes *//* Disallowed by POSIX (1988-):http://www.mail-archive.com/leapsecs@rom.usno.navy.mil/msg00109.htmlhttps://en.wikipedia.org/wiki/Unix_time*/if (!ISNAN(ans)) {ans -= n_leapseconds;}#endifreturn ans;}attribute_hidden SEXP do_systime(SEXP call, SEXP op, SEXP args, SEXP env){checkArity(op, args);return ScalarReal(currentTime());}#ifdef HAVE_UNISTD_H#include <unistd.h> /* for getpid */#endif/* For RNG.c, main.c, mkdtemp.c */attribute_hidden unsigned int TimeToSeed(void){unsigned int seed, pid = getpid();#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME){struct timespec tp;clock_gettime(CLOCK_REALTIME, &tp);seed = (unsigned int)(((uint_least64_t) tp.tv_nsec << 16) ^ tp.tv_sec);}#elif defined(HAVE_GETTIMEOFDAY){struct timeval tv;gettimeofday (&tv, NULL);seed = (unsigned int)(((uint_least64_t) tv.tv_usec << 16) ^ tv.tv_sec);}#else/* C89, so must work */seed = (Int32) time(NULL);#endifseed ^= (pid <<16);return seed;}