changeset: 91950:944dba586dfa tag: tip user: Victor Stinner date: Thu Jul 31 13:06:52 2014 +0200 files: Doc/library/time.rst Include/pytime.h Lib/queue.py Lib/sched.py Lib/socketserver.py Lib/subprocess.py Lib/telnetlib.py Lib/test/test_selectors.py Lib/threading.py Lib/trace.py Modules/_threadmodule.c Modules/gcmodule.c Modules/socketmodule.c Modules/timemodule.c Python/pytime.c configure configure.ac description: implement monotonic diff -r b0aa2448b3ad -r 944dba586dfa Doc/library/time.rst --- a/Doc/library/time.rst Thu Jul 31 13:03:12 2014 +0200 +++ b/Doc/library/time.rst Thu Jul 31 13:06:52 2014 +0200 @@ -315,9 +315,9 @@ The module defines the following functio processes running for more than 49 days. On more recent versions of Windows and on other operating systems, :func:`monotonic` is system-wide. - Availability: Windows, Mac OS X, Linux, FreeBSD, OpenBSD, Solaris. - .. versionadded:: 3.3 + .. versionchanged:: 3.5 + The function is now always available. .. function:: perf_counter() diff -r b0aa2448b3ad -r 944dba586dfa Include/pytime.h --- a/Include/pytime.h Thu Jul 31 13:03:12 2014 +0200 +++ b/Include/pytime.h Thu Jul 31 13:06:52 2014 +0200 @@ -109,6 +109,22 @@ PyAPI_FUNC(int) _PyTime_ObjectToTimespec long *nsec, _PyTime_round_t); +/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards. + The clock is not affected by system clock updates. The reference point of + the returned value is undefined, so that only the difference between the + results of consecutive calls is valid. + + The function never fails. _PyTimeSpec_Init() ensures that a monotonic clock + is available and works. */ +PyAPI_FUNC(void) _PyTimeSpec_monotonic( + _PyTimeSpec *ts); + +/* Similar to _PyTime_monotonic(), fill also info (if set) with information of + the function used to get the time. */ +PyAPI_FUNC(int) _PyTimeSpec_monotonic_info( + _PyTimeSpec *ts, + _Py_clock_info_t *info); + #endif /* Dummy to force linking. */ diff -r b0aa2448b3ad -r 944dba586dfa Lib/queue.py --- a/Lib/queue.py Thu Jul 31 13:03:12 2014 +0200 +++ b/Lib/queue.py Thu Jul 31 13:06:52 2014 +0200 @@ -6,10 +6,7 @@ except ImportError: import dummy_threading as threading from collections import deque from heapq import heappush, heappop -try: - from time import monotonic as time -except ImportError: - from time import time +from time import monotonic as time __all__ = ['Empty', 'Full', 'Queue', 'PriorityQueue', 'LifoQueue'] diff -r b0aa2448b3ad -r 944dba586dfa Lib/sched.py --- a/Lib/sched.py Thu Jul 31 13:03:12 2014 +0200 +++ b/Lib/sched.py Thu Jul 31 13:06:52 2014 +0200 @@ -35,10 +35,7 @@ try: import threading except ImportError: import dummy_threading as threading -try: - from time import monotonic as _time -except ImportError: - from time import time as _time +from time import monotonic as _time __all__ = ["scheduler"] diff -r b0aa2448b3ad -r 944dba586dfa Lib/socketserver.py --- a/Lib/socketserver.py Thu Jul 31 13:03:12 2014 +0200 +++ b/Lib/socketserver.py Thu Jul 31 13:06:52 2014 +0200 @@ -136,10 +136,7 @@ try: import threading except ImportError: import dummy_threading as threading -try: - from time import monotonic as time -except ImportError: - from time import time as time +from time import monotonic as time __all__ = ["TCPServer","UDPServer","ForkingUDPServer","ForkingTCPServer", "ThreadingUDPServer","ThreadingTCPServer","BaseRequestHandler", diff -r b0aa2448b3ad -r 944dba586dfa Lib/subprocess.py --- a/Lib/subprocess.py Thu Jul 31 13:03:12 2014 +0200 +++ b/Lib/subprocess.py Thu Jul 31 13:06:52 2014 +0200 @@ -365,10 +365,7 @@ import signal import builtins import warnings import errno -try: - from time import monotonic as _time -except ImportError: - from time import time as _time +from time import monotonic as _time # Exception classes used by this module. class SubprocessError(Exception): pass diff -r b0aa2448b3ad -r 944dba586dfa Lib/telnetlib.py --- a/Lib/telnetlib.py Thu Jul 31 13:03:12 2014 +0200 +++ b/Lib/telnetlib.py Thu Jul 31 13:06:52 2014 +0200 @@ -36,10 +36,7 @@ To do: import sys import socket import selectors -try: - from time import monotonic as _time -except ImportError: - from time import time as _time +from time import monotonic as _time __all__ = ["Telnet"] diff -r b0aa2448b3ad -r 944dba586dfa Lib/test/test_selectors.py --- a/Lib/test/test_selectors.py Thu Jul 31 13:03:12 2014 +0200 +++ b/Lib/test/test_selectors.py Thu Jul 31 13:06:52 2014 +0200 @@ -8,10 +8,7 @@ from test import support from time import sleep import unittest import unittest.mock -try: - from time import monotonic as time -except ImportError: - from time import time as time +from time import monotonic as time try: import resource except ImportError: diff -r b0aa2448b3ad -r 944dba586dfa Lib/threading.py --- a/Lib/threading.py Thu Jul 31 13:03:12 2014 +0200 +++ b/Lib/threading.py Thu Jul 31 13:06:52 2014 +0200 @@ -3,10 +3,7 @@ import sys as _sys import _thread -try: - from time import monotonic as _time -except ImportError: - from time import time as _time +from time import monotonic as _time from traceback import format_exc as _format_exc from _weakrefset import WeakSet from itertools import islice as _islice diff -r b0aa2448b3ad -r 944dba586dfa Lib/trace.py --- a/Lib/trace.py Thu Jul 31 13:03:12 2014 +0200 +++ b/Lib/trace.py Thu Jul 31 13:06:52 2014 +0200 @@ -59,10 +59,7 @@ import gc import dis import pickle from warnings import warn as _warn -try: - from time import monotonic as _time -except ImportError: - from time import time as _time +from time import monotonic as _time try: import threading diff -r b0aa2448b3ad -r 944dba586dfa Modules/_threadmodule.c --- a/Modules/_threadmodule.c Thu Jul 31 13:03:12 2014 +0200 +++ b/Modules/_threadmodule.c Thu Jul 31 13:06:52 2014 +0200 @@ -57,7 +57,7 @@ acquire_timed(PyThread_type_lock lock, P if (microseconds > 0) { - _PyTimeSpec_get_time(&endtime); + _PyTimeSpec_monotonic(&endtime); _PyTimeSpec_add_us(&endtime, microseconds); } @@ -82,7 +82,7 @@ acquire_timed(PyThread_type_lock lock, P /* If we're using a timeout, recompute the timeout after processing * signals, since those can take time. */ if (microseconds > 0) { - _PyTimeSpec_get_time(&curtime); + _PyTimeSpec_monotonic(&curtime); microseconds = _PyTimeSpec_interval_us(&curtime, &endtime); /* Check for negative values, since those mean block forever. diff -r b0aa2448b3ad -r 944dba586dfa Modules/gcmodule.c --- a/Modules/gcmodule.c Thu Jul 31 13:03:12 2014 +0200 +++ b/Modules/gcmodule.c Thu Jul 31 13:06:52 2014 +0200 @@ -919,7 +919,7 @@ collect(int generation, Py_ssize_t *n_co for (i = 0; i < NUM_GENERATIONS; i++) PySys_FormatStderr(" %zd", gc_list_size(GEN_HEAD(i))); - _PyTimeSpec_get_time(&t1); + _PyTimeSpec_monotonic(&t1); PySys_WriteStderr("\n"); } @@ -1025,7 +1025,7 @@ collect(int generation, Py_ssize_t *n_co } if (debug & DEBUG_STATS) { _PyTimeSpec t2; - _PyTimeSpec_get_time(&t2); + _PyTimeSpec_monotonic(&t2); if (m == 0 && n == 0) PySys_WriteStderr("gc: done"); diff -r b0aa2448b3ad -r 944dba586dfa Modules/socketmodule.c --- a/Modules/socketmodule.c Thu Jul 31 13:03:12 2014 +0200 +++ b/Modules/socketmodule.c Thu Jul 31 13:06:52 2014 +0200 @@ -680,7 +680,7 @@ internal_select(PySocketSockObject *s, i double interval = s->sock_timeout; \ int has_timeout = s->sock_timeout > 0.0; \ if (has_timeout) { \ - _PyTimeSpec_get_time(&now); \ + _PyTimeSpec_monotonic(&now); \ deadline = now; \ _PyTimeSpec_add_sec(&deadline, s->sock_timeout); \ } \ @@ -691,7 +691,7 @@ internal_select(PySocketSockObject *s, i if (!has_timeout || \ (!CHECK_ERRNO(EWOULDBLOCK) && !CHECK_ERRNO(EAGAIN))) \ break; \ - _PyTimeSpec_get_time(&now); \ + _PyTimeSpec_monotonic(&now); \ interval = _PyTimeSpec_interval_sec(&now, &deadline); \ } \ } \ diff -r b0aa2448b3ad -r 944dba586dfa Modules/timemodule.c --- a/Modules/timemodule.c Thu Jul 31 13:03:12 2014 +0200 +++ b/Modules/timemodule.c Thu Jul 31 13:06:52 2014 +0200 @@ -903,122 +903,15 @@ the local timezone used by methods such should not be relied on."); #endif /* HAVE_WORKING_TZSET */ -#if defined(MS_WINDOWS) || defined(__APPLE__) \ - || (defined(HAVE_CLOCK_GETTIME) \ - && (defined(CLOCK_HIGHRES) || defined(CLOCK_MONOTONIC))) -#define PYMONOTONIC -#endif - -#ifdef PYMONOTONIC static PyObject* pymonotonic(_Py_clock_info_t *info) { -#if defined(MS_WINDOWS) - static ULONGLONG (*GetTickCount64) (void) = NULL; - static ULONGLONG (CALLBACK *Py_GetTickCount64)(void); - static int has_getickcount64 = -1; - double result; + _PyTimeSpec ts; - if (has_getickcount64 == -1) { - /* GetTickCount64() was added to Windows Vista */ - if (winver.dwMajorVersion >= 6) { - HINSTANCE hKernel32; - hKernel32 = GetModuleHandleW(L"KERNEL32"); - *(FARPROC*)&Py_GetTickCount64 = GetProcAddress(hKernel32, - "GetTickCount64"); - has_getickcount64 = (Py_GetTickCount64 != NULL); - } - else - has_getickcount64 = 0; - } + if (_PyTimeSpec_monotonic_info(&ts, info) < 0) + return NULL; - if (has_getickcount64) { - ULONGLONG ticks; - ticks = Py_GetTickCount64(); - result = (double)ticks * 1e-3; - } - else { - static DWORD last_ticks = 0; - static DWORD n_overflow = 0; - DWORD ticks; - - ticks = GetTickCount(); - if (ticks < last_ticks) - n_overflow++; - last_ticks = ticks; - - result = ldexp(n_overflow, 32); - result += ticks; - result *= 1e-3; - } - - if (info) { - DWORD timeAdjustment, timeIncrement; - BOOL isTimeAdjustmentDisabled, ok; - if (has_getickcount64) - info->implementation = "GetTickCount64()"; - else - info->implementation = "GetTickCount()"; - info->monotonic = 1; - ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, - &isTimeAdjustmentDisabled); - if (!ok) { - PyErr_SetFromWindowsErr(0); - return NULL; - } - info->resolution = timeIncrement * 1e-7; - info->adjustable = 0; - } - return PyFloat_FromDouble(result); - -#elif defined(__APPLE__) - static mach_timebase_info_data_t timebase; - uint64_t time; - double secs; - - if (timebase.denom == 0) { - /* According to the Technical Q&A QA1398, mach_timebase_info() cannot - fail: https://developer.apple.com/library/mac/#qa/qa1398/ */ - (void)mach_timebase_info(&timebase); - } - - time = mach_absolute_time(); - secs = (double)time * timebase.numer / timebase.denom * 1e-9; - if (info) { - info->implementation = "mach_absolute_time()"; - info->resolution = (double)timebase.numer / timebase.denom * 1e-9; - info->monotonic = 1; - info->adjustable = 0; - } - return PyFloat_FromDouble(secs); - -#elif defined(HAVE_CLOCK_GETTIME) && (defined(CLOCK_HIGHRES) || defined(CLOCK_MONOTONIC)) - struct timespec tp; -#ifdef CLOCK_HIGHRES - const clockid_t clk_id = CLOCK_HIGHRES; - const char *function = "clock_gettime(CLOCK_HIGHRES)"; -#else - const clockid_t clk_id = CLOCK_MONOTONIC; - const char *function = "clock_gettime(CLOCK_MONOTONIC)"; -#endif - - if (clock_gettime(clk_id, &tp) != 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - if (info) { - struct timespec res; - info->monotonic = 1; - info->implementation = function; - info->adjustable = 0; - if (clock_getres(clk_id, &res) == 0) - info->resolution = res.tv_sec + res.tv_nsec * 1e-9; - else - info->resolution = 1e-9; - } - return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); -#endif + return PyFloat_FromDouble(ts.tv_sec + ts.tv_nsec * 1e-9); } static PyObject * @@ -1031,20 +924,15 @@ PyDoc_STRVAR(monotonic_doc, "monotonic() -> float\n\ \n\ Monotonic clock, cannot go backward."); -#endif /* PYMONOTONIC */ static PyObject* perf_counter(_Py_clock_info_t *info) { -#if defined(WIN32_PERF_COUNTER) || defined(PYMONOTONIC) PyObject *res; -#endif -#if defined(WIN32_PERF_COUNTER) +#ifdef WIN32_PERF_COUNTER static int use_perf_counter = 1; #endif -#ifdef PYMONOTONIC static int use_monotonic = 1; -#endif #ifdef WIN32_PERF_COUNTER if (use_perf_counter) { @@ -1054,7 +942,6 @@ perf_counter(_Py_clock_info_t *info) } #endif -#ifdef PYMONOTONIC if (use_monotonic) { res = pymonotonic(info); if (res != NULL) @@ -1062,7 +949,6 @@ perf_counter(_Py_clock_info_t *info) use_monotonic = 0; PyErr_Clear(); } -#endif return floattime(info); } @@ -1231,10 +1117,8 @@ time_get_clock_info(PyObject *self, PyOb else if (strcmp(name, "clock") == 0) obj = pyclock(&info); #endif -#ifdef PYMONOTONIC else if (strcmp(name, "monotonic") == 0) obj = pymonotonic(&info); -#endif else if (strcmp(name, "perf_counter") == 0) obj = perf_counter(&info); else if (strcmp(name, "process_time") == 0) @@ -1426,9 +1310,7 @@ static PyMethodDef time_methods[] = { #ifdef HAVE_WORKING_TZSET {"tzset", time_tzset, METH_NOARGS, tzset_doc}, #endif -#ifdef PYMONOTONIC {"monotonic", time_monotonic, METH_NOARGS, monotonic_doc}, -#endif {"process_time", time_process_time, METH_NOARGS, process_time_doc}, {"perf_counter", time_perf_counter, METH_NOARGS, perf_counter_doc}, {"get_clock_info", time_get_clock_info, METH_VARARGS, get_clock_info_doc}, @@ -1535,30 +1417,8 @@ static PyObject* floattime(_Py_clock_info_t *info) { _PyTimeSpec ts; -#ifdef HAVE_CLOCK_GETTIME - struct timespec tp; - int ret; - - /* _PyTime_gettimeofday() does not use clock_gettime() - because it would require to link Python to the rt (real-time) - library, at least on Linux */ - ret = clock_gettime(CLOCK_REALTIME, &tp); - if (ret == 0) { - if (info) { - struct timespec res; - info->implementation = "clock_gettime(CLOCK_REALTIME)"; - info->monotonic = 0; - info->adjustable = 1; - if (clock_getres(CLOCK_REALTIME, &res) == 0) - info->resolution = res.tv_sec + res.tv_nsec * 1e-9; - else - info->resolution = 1e-9; - } - return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); - } -#endif if (_PyTimeSpec_get_time_info(&ts, info) < 0) { - assert(0 && "_PyTimeSpec_get_time_info should never fail"); + assert(0 && "getting the time must never fail"); return NULL; } return PyFloat_FromDouble((double)ts.tv_sec + ts.tv_nsec * 1e-9); diff -r b0aa2448b3ad -r 944dba586dfa Python/pytime.c --- a/Python/pytime.c Thu Jul 31 13:03:12 2014 +0200 +++ b/Python/pytime.c Thu Jul 31 13:06:52 2014 +0200 @@ -208,17 +208,22 @@ pygettimeofday(_PyTimeSpec *ts, _Py_cloc return 0; #else /* There are four ways to get the time: - (1) gettimeofday() -- resolution in microseconds - (2) ftime() -- resolution in milliseconds - (3) time() -- resolution in seconds + (1) clock_gettime() -- resolution in nanoseconds + (2) gettimeofday() -- resolution in microseconds + (3) ftime() -- resolution in milliseconds + (4) time() -- resolution in seconds In all cases the return value in a timeval struct. Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may fail, so we fall back on ftime() or time(). Note: clock resolution does not imply clock accuracy! */ -#if defined(HAVE_GETTIMEOFDAY) || defined(HAVE_FTIME) +#if (defined(HAVE_CLOCK_GETTIME) || defined(HAVE_GETTIMEOFDAY) \ + || defined(HAVE_FTIME)) int err; #endif +#ifdef HAVE_CLOCK_GETTIME + struct timespec tp; +#endif #ifdef HAVE_GETTIMEOFDAY struct timeval tv; #endif @@ -226,6 +231,30 @@ pygettimeofday(_PyTimeSpec *ts, _Py_cloc struct timeb tb; #endif + /* test clock_gettime(CLOCK_REALTIME) */ +#ifdef HAVE_CLOCK_GETTIME + err = clock_gettime(CLOCK_REALTIME, &tp); + if (err && raise) { + PyErr_SetFromErrno(PyExc_OSError); + goto error; + } + if (err == 0) { + if (info) { + struct timespec res; + info->implementation = "clock_gettime(CLOCK_REALTIME)"; + info->monotonic = 0; + info->adjustable = 1; + if (clock_getres(CLOCK_REALTIME, &res) == 0) + info->resolution = res.tv_sec + res.tv_nsec * 1e-9; + else + info->resolution = 1e-9; + } + ts->tv_sec = tp.tv_sec; + ts->tv_nsec = tp.tv_nsec; + return 0; + } +#endif + /* test gettimeofday() */ #ifdef HAVE_GETTIMEOFDAY #ifdef GETTIMEOFDAY_NO_TZ @@ -402,6 +431,155 @@ int return _PyTime_ObjectToDenominator(obj, sec, usec, 1e6, round); } +static int +pymonotonic(_PyTimeSpec *ts, _Py_clock_info_t *info, int raise) +{ +#if defined(MS_WINDOWS) + static ULONGLONG (*GetTickCount64) (void) = NULL; + static ULONGLONG (CALLBACK *Py_GetTickCount64)(void); + static int has_getickcount64 = -1; + double result; + + if (has_getickcount64 == -1) { + /* GetTickCount64() was added to Windows Vista */ + if (winver.dwMajorVersion >= 6) { + HINSTANCE hKernel32; + hKernel32 = GetModuleHandleW(L"KERNEL32"); + *(FARPROC*)&Py_GetTickCount64 = GetProcAddress(hKernel32, + "GetTickCount64"); + has_getickcount64 = (Py_GetTickCount64 != NULL); + } + else + has_getickcount64 = 0; + } + + if (has_getickcount64) { + ULONGLONG ticks; + ticks = Py_GetTickCount64(); + ts->tv_sec = ticks / SEC_IN_MILLISECONDS; + ts->tv_nsec = (ticks % SEC_IN_MILLISECONDS) * MS_IN_NANOSECONDS; + } + else { + static DWORD last_ticks = 0; + DWORD ticks; + static ULONGLONG delta = 0; + ULONGLONG result; + + ticks = GetTickCount(); + if (ticks < last_ticks) + delta += (ULONGLONG)1 << 32; + last_ticks = ticks; + + result = (ULONGLONG)ticks + delta; + + ts->tv_sec = result / SEC_IN_MILLISECONDS; + ts->tv_nsec = (result % SEC_IN_MILLISECONDS) * MS_IN_NANOSECONDS; + } + + if (info) { + DWORD timeAdjustment, timeIncrement; + BOOL isTimeAdjustmentDisabled, ok; + if (has_getickcount64) + info->implementation = "GetTickCount64()"; + else + info->implementation = "GetTickCount()"; + info->monotonic = 1; + ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, + &isTimeAdjustmentDisabled); + if (!ok) { + if (raise) + PyErr_SetFromWindowsErr(0); + goto error; + } + info->resolution = timeIncrement * 1e-7; + info->adjustable = 0; + } + return 0; + +#elif defined(__APPLE__) + static mach_timebase_info_data_t timebase; + uint64_t time; + double secs; + + if (timebase.denom == 0) { + /* According to the Technical Q&A QA1398, mach_timebase_info() cannot + fail: https://developer.apple.com/library/mac/#qa/qa1398/ */ + (void)mach_timebase_info(&timebase); + } + + time = mach_absolute_time(); + secs = (double)time * timebase.numer / timebase.denom * 1e-9; + + if (_PyTime_DoubleToDenominator(secs, &ts->tv_sec, &ts->nsec, + 1e9, _PyTime_ROUND_DOWN, raise) < 0) + goto error; + + if (info) { + info->implementation = "mach_absolute_time()"; + info->resolution = (double)timebase.numer / timebase.denom * 1e-9; + info->monotonic = 1; + info->adjustable = 0; + } + return 0; + +#elif defined(HAVE_CLOCK_GETTIME) && (defined(CLOCK_HIGHRES) || defined(CLOCK_MONOTONIC)) + struct timespec tp; +#ifdef CLOCK_HIGHRES + const clockid_t clk_id = CLOCK_HIGHRES; + const char *function = "clock_gettime(CLOCK_HIGHRES)"; +#else + const clockid_t clk_id = CLOCK_MONOTONIC; + const char *function = "clock_gettime(CLOCK_MONOTONIC)"; +#endif + + if (clock_gettime(clk_id, &tp) != 0) { + if (raise) + PyErr_SetFromErrno(PyExc_OSError); + goto error; + } + ts->tv_sec = tp.tv_sec; + ts->tv_nsec = tp.tv_nsec; + + if (info) { + struct timespec res; + info->monotonic = 1; + info->implementation = function; + info->adjustable = 0; + if (clock_getres(clk_id, &res) == 0) + info->resolution = res.tv_sec + res.tv_nsec * 1e-9; + else + info->resolution = 1e-9; + } + return 0; +#else + /* you are not luky, your OS does not provide a monotonic clock, + Python 3.5 now requires a monotonic clock. */ + PyErr_SetNone(PyExc_NotImplementedError); + Py_RETURN_NOTIMPLEMENTED; + goto error; +#endif + +error: + ts->tv_sec = 0; + ts->tv_nsec = 0; + return -1; +} + +void +_PyTimeSpec_monotonic(_PyTimeSpec *ts) +{ + int res = pymonotonic(ts, NULL, 0); + /* _PyTimeSpec_Init() ensures that a monotonic clock is available and + works. */ + assert(res >= 0); +} + +int +_PyTimeSpec_monotonic_info(_PyTimeSpec *ts, _Py_clock_info_t *info) +{ + return pymonotonic(ts, info, 1); +} + int _PyTimeSpec_Init(void) { @@ -409,5 +587,8 @@ int /* ensure that the system clock works */ if (_PyTimeSpec_get_time_info(&ts, NULL) < 0) return -1; + /* ensure that the operating system provides a monotonic clock */ + if (_PyTimeSpec_monotonic_info(&ts, NULL) < 0) + return -1; return 0; } diff -r b0aa2448b3ad -r 944dba586dfa configure --- a/configure Thu Jul 31 13:03:12 2014 +0200 +++ b/configure Thu Jul 31 13:06:52 2014 +0200 @@ -11811,6 +11811,7 @@ fi $as_echo "$ac_cv_lib_rt_clock_gettime" >&6; } if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then : + LIBS="$LIBS -lrt" $as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h diff -r b0aa2448b3ad -r 944dba586dfa configure.ac --- a/configure.ac Thu Jul 31 13:03:12 2014 +0200 +++ b/configure.ac Thu Jul 31 13:06:52 2014 +0200 @@ -3269,6 +3269,7 @@ AC_CHECK_FUNCS(gettimeofday, AC_CHECK_FUNCS(clock_gettime, [], [ AC_CHECK_LIB(rt, clock_gettime, [ + LIBS="$LIBS -lrt" AC_DEFINE(HAVE_CLOCK_GETTIME, 1) AC_DEFINE(TIMEMODULE_LIB, [rt], [Library needed by timemodule.c: librt may be needed for clock_gettime()])