Fix pages_purge_forced() to discard pages on non-Linux systems.

madvise(..., MADV_DONTNEED) only causes demand-zeroing on Linux, so fall
back to overlaying a new mapping.
This commit is contained in:
Jason Evans 2017-03-09 18:20:02 -08:00
parent 21a68e2d22
commit 7cbcd2e2b7
4 changed files with 21 additions and 5 deletions

View File

@ -547,6 +547,7 @@ case "${host}" in
dnl syscall(2) and secure_getenv(3) are exposed by _GNU_SOURCE. dnl syscall(2) and secure_getenv(3) are exposed by _GNU_SOURCE.
JE_APPEND_VS(CPPFLAGS, -D_GNU_SOURCE) JE_APPEND_VS(CPPFLAGS, -D_GNU_SOURCE)
abi="elf" abi="elf"
AC_DEFINE([JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS])
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_THREADED_INIT], [ ]) AC_DEFINE([JEMALLOC_THREADED_INIT], [ ])
@ -558,6 +559,7 @@ case "${host}" in
dnl syscall(2) and secure_getenv(3) are exposed by _GNU_SOURCE. dnl syscall(2) and secure_getenv(3) are exposed by _GNU_SOURCE.
JE_APPEND_VS(CPPFLAGS, -D_GNU_SOURCE) JE_APPEND_VS(CPPFLAGS, -D_GNU_SOURCE)
abi="elf" abi="elf"
AC_DEFINE([JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS])
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_THREADED_INIT], [ ]) AC_DEFINE([JEMALLOC_THREADED_INIT], [ ])

View File

@ -265,12 +265,17 @@
* *
* madvise(..., MADV_FREE) : This marks pages as being unused, such that they * madvise(..., MADV_FREE) : This marks pages as being unused, such that they
* will be discarded rather than swapped out. * will be discarded rather than swapped out.
* madvise(..., MADV_DONTNEED) : This immediately discards pages, such that * madvise(..., MADV_DONTNEED) : If JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS is
* new pages will be demand-zeroed if the * defined, this immediately discards pages,
* address region is later touched. * such that new pages will be demand-zeroed if
* the address region is later touched;
* otherwise this behaves similarly to
* MADV_FREE, though typically with higher
* system overhead.
*/ */
#undef JEMALLOC_PURGE_MADVISE_FREE #undef JEMALLOC_PURGE_MADVISE_FREE
#undef JEMALLOC_PURGE_MADVISE_DONTNEED #undef JEMALLOC_PURGE_MADVISE_DONTNEED
#undef JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS
/* /*
* Defined if transparent huge pages are supported via the MADV_[NO]HUGEPAGE * Defined if transparent huge pages are supported via the MADV_[NO]HUGEPAGE

View File

@ -37,7 +37,9 @@
* next step after purging on Windows anyway, there's no point in adding such * next step after purging on Windows anyway, there's no point in adding such
* complexity. * complexity.
*/ */
#if !defined(_WIN32) && defined(JEMALLOC_PURGE_MADVISE_DONTNEED) #if !defined(_WIN32) && ((defined(JEMALLOC_PURGE_MADVISE_DONTNEED) && \
defined(JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS)) || \
defined(JEMALLOC_MAPS_COALESCE))
# define PAGES_CAN_PURGE_FORCED # define PAGES_CAN_PURGE_FORCED
#endif #endif

View File

@ -170,6 +170,9 @@ pages_purge_lazy(void *addr, size_t size) {
VirtualAlloc(addr, size, MEM_RESET, PAGE_READWRITE); VirtualAlloc(addr, size, MEM_RESET, PAGE_READWRITE);
#elif defined(JEMALLOC_PURGE_MADVISE_FREE) #elif defined(JEMALLOC_PURGE_MADVISE_FREE)
madvise(addr, size, MADV_FREE); madvise(addr, size, MADV_FREE);
#elif defined(JEMALLOC_PURGE_MADVISE_DONTNEED) && \
!defined(JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS)
madvise(addr, size, MADV_DONTNEED);
#else #else
not_reached(); not_reached();
#endif #endif
@ -182,8 +185,12 @@ pages_purge_forced(void *addr, size_t size) {
return true; return true;
} }
#if defined(JEMALLOC_PURGE_MADVISE_DONTNEED) #if defined(JEMALLOC_PURGE_MADVISE_DONTNEED) && \
defined(JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS)
return (madvise(addr, size, MADV_DONTNEED) != 0); return (madvise(addr, size, MADV_DONTNEED) != 0);
#elif defined(JEMALLOC_MAPS_COALESCE)
/* Try to overlay a new demand-zeroed mapping. */
return pages_commit(addr, size);
#else #else
not_reached(); not_reached();
#endif #endif