summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2011-08-10 08:40:45 -0700
committerdormando <dormando@rydia.net>2011-08-10 08:44:52 -0700
commit569decdbb140b989fbd517a0dd6082363a21f854 (patch)
treee6d79cda4e0c1ee9b4f0dbf41f699af0c04be9f3
parent51b68daa195ba37af1c87ba324eea504bd4cacdd (diff)
downloadmemcached-569decdbb140b989fbd517a0dd6082363a21f854.tar.gz
Do the monotonic clock ourselves1.4.7-rc11.4.7
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.
-rw-r--r--configure.ac1
-rw-r--r--memcached.c27
2 files changed, 26 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac
index 066d06c..1e3893e 100644
--- a/configure.ac
+++ b/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,
diff --git a/memcached.c b/memcached.c
index 21ee227..f52c32d 100644
--- a/memcached.c
+++ b/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) {