Refactor madvise(2) configuration.

Add feature tests for the MADV_FREE and MADV_DONTNEED flags to
madvise(2), so that MADV_FREE is detected and used for Linux kernel
versions 4.5 and newer.  Refactor pages_purge() so that on systems which
support both flags, MADV_FREE is preferred over MADV_DONTNEED.

This resolves #387.
This commit is contained in:
Jason Evans 2016-11-17 10:24:51 -08:00
parent e7ca53bac2
commit 62f2d84e7a
3 changed files with 39 additions and 30 deletions

View File

@ -354,7 +354,6 @@ maps_coalesce="1"
case "${host}" in case "${host}" in
*-*-darwin* | *-*-ios*) *-*-darwin* | *-*-ios*)
abi="macho" abi="macho"
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
RPATH="" RPATH=""
LD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES" LD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES"
so="dylib" so="dylib"
@ -367,21 +366,17 @@ case "${host}" in
*-*-freebsd*) *-*-freebsd*)
abi="elf" abi="elf"
AC_DEFINE([JEMALLOC_SYSCTL_VM_OVERCOMMIT], [ ]) AC_DEFINE([JEMALLOC_SYSCTL_VM_OVERCOMMIT], [ ])
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
force_lazy_lock="1" force_lazy_lock="1"
;; ;;
*-*-dragonfly*) *-*-dragonfly*)
abi="elf" abi="elf"
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
;; ;;
*-*-openbsd*) *-*-openbsd*)
abi="elf" abi="elf"
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
force_tls="0" force_tls="0"
;; ;;
*-*-bitrig*) *-*-bitrig*)
abi="elf" abi="elf"
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
;; ;;
*-*-linux-android) *-*-linux-android)
dnl syscall(2) and secure_getenv(3) are exposed by _GNU_SOURCE. dnl syscall(2) and secure_getenv(3) are exposed by _GNU_SOURCE.
@ -389,7 +384,6 @@ case "${host}" in
abi="elf" abi="elf"
AC_DEFINE([JEMALLOC_HAS_ALLOCA_H]) AC_DEFINE([JEMALLOC_HAS_ALLOCA_H])
AC_DEFINE([JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY], [ ]) AC_DEFINE([JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY], [ ])
AC_DEFINE([JEMALLOC_PURGE_MADVISE_DONTNEED], [ ])
AC_DEFINE([JEMALLOC_THREADED_INIT], [ ]) AC_DEFINE([JEMALLOC_THREADED_INIT], [ ])
AC_DEFINE([JEMALLOC_C11ATOMICS]) AC_DEFINE([JEMALLOC_C11ATOMICS])
force_tls="0" force_tls="0"
@ -401,7 +395,6 @@ case "${host}" in
abi="elf" abi="elf"
AC_DEFINE([JEMALLOC_HAS_ALLOCA_H]) AC_DEFINE([JEMALLOC_HAS_ALLOCA_H])
AC_DEFINE([JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY], [ ]) AC_DEFINE([JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY], [ ])
AC_DEFINE([JEMALLOC_PURGE_MADVISE_DONTNEED], [ ])
AC_DEFINE([JEMALLOC_THREADED_INIT], [ ]) AC_DEFINE([JEMALLOC_THREADED_INIT], [ ])
AC_DEFINE([JEMALLOC_USE_CXX_THROW], [ ]) AC_DEFINE([JEMALLOC_USE_CXX_THROW], [ ])
default_munmap="0" default_munmap="0"
@ -418,11 +411,9 @@ case "${host}" in
[abi="elf"], [abi="elf"],
[abi="aout"]) [abi="aout"])
AC_MSG_RESULT([$abi]) AC_MSG_RESULT([$abi])
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
;; ;;
*-*-solaris2*) *-*-solaris2*)
abi="elf" abi="elf"
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
RPATH='-Wl,-R,$(1)' RPATH='-Wl,-R,$(1)'
dnl Solaris needs this for sigwait(). dnl Solaris needs this for sigwait().
CPPFLAGS="$CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS" CPPFLAGS="$CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS"
@ -1610,13 +1601,34 @@ dnl Check for madvise(2).
JE_COMPILABLE([madvise(2)], [ JE_COMPILABLE([madvise(2)], [
#include <sys/mman.h> #include <sys/mman.h>
], [ ], [
{
madvise((void *)0, 0, 0); madvise((void *)0, 0, 0);
}
], [je_cv_madvise]) ], [je_cv_madvise])
if test "x${je_cv_madvise}" = "xyes" ; then if test "x${je_cv_madvise}" = "xyes" ; then
dnl Check for madvise(..., MADV_FREE).
JE_COMPILABLE([madvise(..., MADV_FREE)], [
#include <sys/mman.h>
], [
madvise((void *)0, 0, MADV_FREE);
], [je_cv_madv_free])
if test "x${je_cv_madv_free}" = "xyes" ; then
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
fi
dnl Check for madvise(..., MADV_DONTNEED).
JE_COMPILABLE([madvise(..., MADV_DONTNEED)], [
#include <sys/mman.h>
], [
madvise((void *)0, 0, MADV_DONTNEED);
], [je_cv_madv_dontneed])
if test "x${je_cv_madv_dontneed}" = "xyes" ; then
AC_DEFINE([JEMALLOC_PURGE_MADVISE_DONTNEED], [ ])
fi
if test "x${je_cv_madv_free}" = "xyes" \
-o "x${je_cv_madv_dontneed}" = "xyes" ; then
AC_DEFINE([JEMALLOC_HAVE_MADVISE], [ ]) AC_DEFINE([JEMALLOC_HAVE_MADVISE], [ ])
fi fi
fi
dnl ============================================================================ dnl ============================================================================
dnl Check whether __sync_{add,sub}_and_fetch() are available despite dnl Check whether __sync_{add,sub}_and_fetch() are available despite

View File

@ -55,11 +55,6 @@
*/ */
#undef JEMALLOC_HAVE_BUILTIN_CLZ #undef JEMALLOC_HAVE_BUILTIN_CLZ
/*
* Defined if madvise(2) is available.
*/
#undef JEMALLOC_HAVE_MADVISE
/* /*
* Defined if os_unfair_lock_*() functions are available, as provided by Darwin. * Defined if os_unfair_lock_*() functions are available, as provided by Darwin.
*/ */
@ -252,18 +247,20 @@
#undef JEMALLOC_SYSCTL_VM_OVERCOMMIT #undef JEMALLOC_SYSCTL_VM_OVERCOMMIT
#undef JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY #undef JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY
/* Defined if madvise(2) is available. */
#undef JEMALLOC_HAVE_MADVISE
/* /*
* Methods for purging unused pages differ between operating systems. * Methods for purging unused pages differ between operating systems.
* *
* madvise(..., MADV_DONTNEED) : On Linux, this immediately discards pages, * madvise(..., MADV_FREE) : This marks pages as being unused, such that they
* such that new pages will be demand-zeroed if * will be discarded rather than swapped out.
* the address region is later touched. * madvise(..., MADV_DONTNEED) : This immediately discards pages, such that
* madvise(..., MADV_FREE) : On FreeBSD and Darwin, this marks pages as being * new pages will be demand-zeroed if the
* unused, such that they will be discarded rather * address region is later touched.
* than swapped out.
*/ */
#undef JEMALLOC_PURGE_MADVISE_DONTNEED
#undef JEMALLOC_PURGE_MADVISE_FREE #undef JEMALLOC_PURGE_MADVISE_FREE
#undef JEMALLOC_PURGE_MADVISE_DONTNEED
/* Define if operating system has alloca.h header. */ /* Define if operating system has alloca.h header. */
#undef JEMALLOC_HAS_ALLOCA_H #undef JEMALLOC_HAS_ALLOCA_H

View File

@ -171,14 +171,14 @@ pages_purge(void *addr, size_t size)
VirtualAlloc(addr, size, MEM_RESET, PAGE_READWRITE); VirtualAlloc(addr, size, MEM_RESET, PAGE_READWRITE);
unzeroed = true; unzeroed = true;
#elif defined(JEMALLOC_HAVE_MADVISE) #elif defined(JEMALLOC_HAVE_MADVISE)
# ifdef JEMALLOC_PURGE_MADVISE_DONTNEED # if defined(JEMALLOC_PURGE_MADVISE_FREE)
# define JEMALLOC_MADV_PURGE MADV_DONTNEED
# define JEMALLOC_MADV_ZEROS true
# elif defined(JEMALLOC_PURGE_MADVISE_FREE)
# define JEMALLOC_MADV_PURGE MADV_FREE # define JEMALLOC_MADV_PURGE MADV_FREE
# define JEMALLOC_MADV_ZEROS false # define JEMALLOC_MADV_ZEROS false
# elif defined(JEMALLOC_PURGE_MADVISE_DONTNEED)
# define JEMALLOC_MADV_PURGE MADV_DONTNEED
# define JEMALLOC_MADV_ZEROS true
# else # else
# error "No madvise(2) flag defined for purging unused dirty pages." # error No madvise(2) flag defined for purging unused dirty pages
# endif # endif
int err = madvise(addr, size, JEMALLOC_MADV_PURGE); int err = madvise(addr, size, JEMALLOC_MADV_PURGE);
unzeroed = (!JEMALLOC_MADV_ZEROS || err != 0); unzeroed = (!JEMALLOC_MADV_ZEROS || err != 0);