summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.in5
-rw-r--r--include/jemalloc/internal/jemalloc_internal.h.in4
-rw-r--r--include/jemalloc/internal/jemalloc_internal_decls.h8
-rw-r--r--include/jemalloc/internal/private_symbols.txt1
-rw-r--r--include/jemalloc/internal/time.h22
-rw-r--r--src/time.c36
-rw-r--r--test/unit/time.c23
7 files changed, 97 insertions, 2 deletions
diff --git a/Makefile.in b/Makefile.in
index 1ac6f29..c4f8cf9 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -85,8 +85,8 @@ C_SRCS := $(srcroot)src/jemalloc.c $(srcroot)src/arena.c \
$(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 @@ TESTS_UNIT := $(srcroot)test/unit/atomic.c \
$(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 @@ typedef unsigned szind_t;
# 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 @@ typedef unsigned szind_t;
/******************************************************************************/
#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_prefork(void);
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 @@ void jemalloc_postfork_child(void);
/******************************************************************************/
#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 @@ isblank(int c)
#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 @@ tcaches_get
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));
+}