Add time_update().
diff --git a/Makefile.in b/Makefile.in
index 1ac6f29..c4f8cf9 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -85,8 +85,8 @@
 	$(srcroot)src/extent.c $(srcroot)src/hash.c $(srcroot)src/huge.c \
 	$(srcroot)src/mb.c $(srcroot)src/mutex.c $(srcroot)src/pages.c \
 	$(srcroot)src/prof.c $(srcroot)src/quarantine.c $(srcroot)src/rtree.c \
-	$(srcroot)src/stats.c $(srcroot)src/tcache.c $(srcroot)src/util.c \
-	$(srcroot)src/tsd.c
+	$(srcroot)src/stats.c $(srcroot)src/tcache.c $(srcroot)src/time.c \
+	$(srcroot)src/tsd.c $(srcroot)src/util.c
 ifeq ($(enable_valgrind), 1)
 C_SRCS += $(srcroot)src/valgrind.c
 endif
@@ -143,6 +143,7 @@
 	$(srcroot)test/unit/SFMT.c \
 	$(srcroot)test/unit/size_classes.c \
 	$(srcroot)test/unit/stats.c \
+	$(srcroot)test/unit/time.c \
 	$(srcroot)test/unit/tsd.c \
 	$(srcroot)test/unit/util.c \
 	$(srcroot)test/unit/zero.c
diff --git a/include/jemalloc/internal/jemalloc_internal.h.in b/include/jemalloc/internal/jemalloc_internal.h.in
index 8c507f7..e7bc4c8 100644
--- a/include/jemalloc/internal/jemalloc_internal.h.in
+++ b/include/jemalloc/internal/jemalloc_internal.h.in
@@ -356,6 +356,7 @@
 #  define VARIABLE_ARRAY(type, name, count) type name[(count)]
 #endif
 
+#include "jemalloc/internal/time.h"
 #include "jemalloc/internal/valgrind.h"
 #include "jemalloc/internal/util.h"
 #include "jemalloc/internal/atomic.h"
@@ -384,6 +385,7 @@
 /******************************************************************************/
 #define	JEMALLOC_H_STRUCTS
 
+#include "jemalloc/internal/time.h"
 #include "jemalloc/internal/valgrind.h"
 #include "jemalloc/internal/util.h"
 #include "jemalloc/internal/atomic.h"
@@ -469,6 +471,7 @@
 void	jemalloc_postfork_parent(void);
 void	jemalloc_postfork_child(void);
 
+#include "jemalloc/internal/time.h"
 #include "jemalloc/internal/valgrind.h"
 #include "jemalloc/internal/util.h"
 #include "jemalloc/internal/atomic.h"
@@ -497,6 +500,7 @@
 /******************************************************************************/
 #define	JEMALLOC_H_INLINES
 
+#include "jemalloc/internal/time.h"
 #include "jemalloc/internal/valgrind.h"
 #include "jemalloc/internal/util.h"
 #include "jemalloc/internal/atomic.h"
diff --git a/include/jemalloc/internal/jemalloc_internal_decls.h b/include/jemalloc/internal/jemalloc_internal_decls.h
index a601d6e..0f29e67 100644
--- a/include/jemalloc/internal/jemalloc_internal_decls.h
+++ b/include/jemalloc/internal/jemalloc_internal_decls.h
@@ -61,4 +61,12 @@
 #endif
 #include <fcntl.h>
 
+#include <sys/time.h>
+#ifdef _WIN32
+struct timespec {
+	time_t	tv_sec;
+	long	tv_nsec;
+};
+#endif
+
 #endif /* JEMALLOC_INTERNAL_H */
diff --git a/include/jemalloc/internal/private_symbols.txt b/include/jemalloc/internal/private_symbols.txt
index a90021a..8b1fd45 100644
--- a/include/jemalloc/internal/private_symbols.txt
+++ b/include/jemalloc/internal/private_symbols.txt
@@ -460,6 +460,7 @@
 tcache_stats_merge
 thread_allocated_cleanup
 thread_deallocated_cleanup
+time_update
 tsd_arena_get
 tsd_arena_set
 tsd_boot
diff --git a/include/jemalloc/internal/time.h b/include/jemalloc/internal/time.h
new file mode 100644
index 0000000..e3e6c5f
--- /dev/null
+++ b/include/jemalloc/internal/time.h
@@ -0,0 +1,22 @@
+#define JEMALLOC_CLOCK_GETTIME defined(_POSIX_MONOTONIC_CLOCK) \
+    && _POSIX_MONOTONIC_CLOCK >= 0
+
+/******************************************************************************/
+#ifdef JEMALLOC_H_TYPES
+
+#endif /* JEMALLOC_H_TYPES */
+/******************************************************************************/
+#ifdef JEMALLOC_H_STRUCTS
+
+#endif /* JEMALLOC_H_STRUCTS */
+/******************************************************************************/
+#ifdef JEMALLOC_H_EXTERNS
+
+bool	time_update(struct timespec *time);
+
+#endif /* JEMALLOC_H_EXTERNS */
+/******************************************************************************/
+#ifdef JEMALLOC_H_INLINES
+
+#endif /* JEMALLOC_H_INLINES */
+/******************************************************************************/
diff --git a/src/time.c b/src/time.c
new file mode 100644
index 0000000..2147c52
--- /dev/null
+++ b/src/time.c
@@ -0,0 +1,36 @@
+#include "jemalloc/internal/jemalloc_internal.h"
+
+bool
+time_update(struct timespec *time)
+{
+	struct timespec old_time;
+
+	memcpy(&old_time, time, sizeof(struct timespec));
+
+#ifdef _WIN32
+	FILETIME ft;
+	uint64_t ticks;
+	GetSystemTimeAsFileTime(&ft);
+	ticks = (ft.dwHighDateTime << 32) | ft.dWLowDateTime;
+	time->tv_sec = ticks / 10000;
+	time->tv_nsec = ((ticks % 10000) * 100);
+#elif JEMALLOC_CLOCK_GETTIME
+	if (sysconf(_SC_MONOTONIC_CLOCK) > 0)
+		clock_gettime(CLOCK_MONOTONIC, time);
+	else
+		clock_gettime(CLOCK_REALTIME, time);
+#else
+	struct timeval tv;
+	gettimeofday(&tv, NULL);
+	time->tv_sec = tv.tv_sec;
+	time->tv_nsec = tv.tv_usec * 1000;
+#endif
+
+	/* Handle non-monotonic clocks. */
+	if (unlikely(old_time.tv_sec > time->tv_sec))
+		return (true);
+	if (unlikely(old_time.tv_sec == time->tv_sec))
+		return old_time.tv_nsec > time->tv_nsec;
+
+	return (false);
+}
diff --git a/test/unit/time.c b/test/unit/time.c
new file mode 100644
index 0000000..80460f9
--- /dev/null
+++ b/test/unit/time.c
@@ -0,0 +1,23 @@
+#include "test/jemalloc_test.h"
+
+TEST_BEGIN(test_time_update)
+{
+	struct timespec ts;
+
+	memset(&ts, 0, sizeof(struct timespec));
+
+	assert_false(time_update(&ts), "Basic time update failed.");
+
+	/* Only Rip Van Winkle sleeps this long. */
+	ts.tv_sec += 631152000;
+	assert_true(time_update(&ts), "Update should detect time roll-back.");
+}
+TEST_END
+
+int
+main(void)
+{
+
+	return (test(
+	    test_time_update));
+}