summaryrefslogtreecommitdiffhomepage
path: root/dbutil.c
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2014-03-13 23:50:09 +0800
committerMatt Johnston <matt@ucc.asn.au>2014-03-13 23:50:09 +0800
commite767bbb41f277ebb8f477e5cda5b97a3a52b08a7 (patch)
tree79e85d770254e5a929aa6d3e09974cbf1fdd6d2e /dbutil.c
parent2b599df57abf70963706b62604ecc2c421b549da (diff)
Add new monotonic_now() wrapper so that timeouts are unaffected by
system clock changes
Diffstat (limited to 'dbutil.c')
-rw-r--r--dbutil.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/dbutil.c b/dbutil.c
index 52bf87c..07ba512 100644
--- a/dbutil.c
+++ b/dbutil.c
@@ -48,6 +48,19 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+#include "config.h"
+
+#ifdef __linux__
+#define _GNU_SOURCE
+/* To call clock_gettime() directly */
+#include <sys/syscall.h>
+#endif /* __linux */
+
+#ifdef HAVE_MACH_MACH_TIME_H
+#include <mach/mach_time.h>
+#include <mach/mach.h>
+#endif
+
#include "includes.h"
#include "dbutil.h"
#include "buffer.h"
@@ -932,3 +945,33 @@ int constant_time_memcmp(const void* a, const void *b, size_t n)
return c;
}
+time_t monotonic_now() {
+
+#if defined(__linux__) && defined(SYS_clock_gettime)
+ /* CLOCK_MONOTONIC_COARSE was added in Linux 2.6.32. Probably cheaper. */
+#ifndef CLOCK_MONOTONIC_COARSE
+#define CLOCK_MONOTONIC_COARSE 6
+#endif
+ static clockid_t clock_source = CLOCK_MONOTONIC_COARSE;
+ struct timespec ts;
+
+ if (syscall(SYS_clock_gettime, clock_source, &ts) == EINVAL) {
+ clock_source = CLOCK_MONOTONIC;
+ syscall(SYS_clock_gettime, CLOCK_MONOTONIC, &ts);
+ }
+ return ts.tv_sec;
+#elif defined(HAVE_MACH_ABSOLUTE_TIME)
+ /* OS X, see https://developer.apple.com/library/mac/qa/qa1398/_index.html */
+ mach_timebase_info_data_t timebase_info;
+ if (timebase_info.denom == 0) {
+ mach_timebase_info(&timebase_info);
+ }
+ return mach_absolute_time() * timebase_info.numer / timebase_info.denom
+ / 1e9;
+#else
+ /* Fallback for everything else - this will sometimes go backwards */
+ return time(NULL);
+#endif
+
+}
+