Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Do the monotonic clock ourselves

I've still removed the "set the time now" stuff that the flush_all commands
do. They push to one second in the past, and with some startup fudge the tests
all pass.

Relying on libevent's firing of clock_handler was drifting ~5ms per tick.
Fudging it further wouldn't be a great idea.
  • Loading branch information...
commit 569decdbb140b989fbd517a0dd6082363a21f854 1 parent 51b68da
@dormando dormando authored
Showing with 26 additions and 2 deletions.
  1. +1 −0  configure.ac
  2. +25 −2 memcached.c
View
1  configure.ac
@@ -418,6 +418,7 @@ AC_CHECK_FUNCS(mlockall)
AC_CHECK_FUNCS(getpagesizes)
AC_CHECK_FUNCS(memcntl)
AC_CHECK_FUNCS(sigignore)
+AC_CHECK_FUNCS(clock_gettime)
AC_DEFUN([AC_C_ALIGNMENT],
[AC_CACHE_CHECK(for alignment, ac_cv_c_alignment,
View
27 memcached.c
@@ -4106,6 +4106,10 @@ static struct event clockevent;
static void clock_handler(const int fd, const short which, void *arg) {
struct timeval t = {.tv_sec = 1, .tv_usec = 0};
static bool initialized = false;
+#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
+ static bool monotonic = false;
+ static time_t monotonic_start;
+#endif
if (initialized) {
/* only delete the event if it's actually there. */
@@ -4114,14 +4118,33 @@ static void clock_handler(const int fd, const short which, void *arg) {
initialized = true;
/* process_started is initialized to time() - 2. We initialize to 1 so
* flush_all won't underflow during tests. */
- current_time = 1;
+#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
+ monotonic = true;
+ monotonic_start = ts.tv_sec - 2;
+ }
+#endif
}
evtimer_set(&clockevent, clock_handler, 0);
event_base_set(main_base, &clockevent);
evtimer_add(&clockevent, &t);
- current_time++;
+#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
+ if (monotonic) {
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
+ return;
+ current_time = (rel_time_t) (ts.tv_sec - monotonic_start);
+ return;
+ }
+#endif
+ {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ current_time = (rel_time_t) (tv.tv_sec - process_started);
+ }
}
static void usage(void) {
Please sign in to comment.
Something went wrong with that request. Please try again.