diff options
author | John Högberg <[email protected]> | 2018-12-07 12:31:33 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2018-12-07 12:31:33 +0100 |
commit | 689f9d5cf041ed9c16b4b31a66c50eac57b2f6f0 (patch) | |
tree | ece2f373bfd5d4a5a1d070e6224c06b08848f769 /erts/emulator/sys | |
parent | ea7d6c39f2179b2240d55df4a1ddd515b6d32832 (diff) | |
parent | 1d549eddbeeccf7d108310466de5f63af04b004c (diff) | |
download | otp-689f9d5cf041ed9c16b4b31a66c50eac57b2f6f0.tar.gz otp-689f9d5cf041ed9c16b4b31a66c50eac57b2f6f0.tar.bz2 otp-689f9d5cf041ed9c16b4b31a66c50eac57b2f6f0.zip |
Merge pull request #2046 from jhogberg/john/erts/mark-pooled-free-blocks-unused/OTP-15075
Mark free blocks in pooled carriers as unused
Diffstat (limited to 'erts/emulator/sys')
-rw-r--r-- | erts/emulator/sys/common/erl_mmap.h | 57 | ||||
-rw-r--r-- | erts/emulator/sys/win32/sys.c | 4 |
2 files changed, 60 insertions, 1 deletions
diff --git a/erts/emulator/sys/common/erl_mmap.h b/erts/emulator/sys/common/erl_mmap.h index 539daea419..e1ff0fe80a 100644 --- a/erts/emulator/sys/common/erl_mmap.h +++ b/erts/emulator/sys/common/erl_mmap.h @@ -176,4 +176,61 @@ void hard_dbg_remove_mseg(void* seg, UWord sz); #endif /* HAVE_ERTS_MMAP */ +/* Marks the given memory region as unused without freeing it, letting the OS + * reclaim its physical memory with the promise that we'll get it back (without + * its contents) the next time it's accessed. */ +ERTS_GLB_INLINE void erts_mem_discard(void *p, UWord size); + +#if ERTS_GLB_INLINE_INCL_FUNC_DEF + +#ifdef VALGRIND + #include <valgrind/memcheck.h> + + ERTS_GLB_INLINE void erts_mem_discard(void *ptr, UWord size) { + VALGRIND_MAKE_MEM_UNDEFINED(ptr, size); + } +#elif defined(DEBUG) + /* Try to provoke crashes by filling the discard region with garbage. It's + * extremely hard to find bugs where we've discarded too much, as the + * region often retains its old contents if it's accessed before the OS + * reclaims it. */ + ERTS_GLB_INLINE void erts_mem_discard(void *ptr, UWord size) { + static const char pattern[] = "DISCARDED"; + char *data; + int i; + + for(i = 0, data = ptr; i < size; i++) { + data[i] = pattern[i % sizeof(pattern)]; + } + } +#elif defined(HAVE_SYS_MMAN_H) + #include <sys/mman.h> + + ERTS_GLB_INLINE void erts_mem_discard(void *ptr, UWord size) { + #ifdef MADV_FREE + /* This is preferred as it doesn't necessarily free the pages right + * away, which is a bit faster than MADV_DONTNEED. */ + madvise(ptr, size, MADV_FREE); + #else + madvise(ptr, size, MADV_DONTNEED); + #endif + } +#elif defined(_WIN32) + #include <winbase.h> + + /* MEM_RESET is defined on all supported versions of Windows, and has the + * same semantics as MADV_FREE. */ + ERTS_GLB_INLINE void erts_mem_discard(void *ptr, UWord size) { + VirtualAlloc(ptr, size, MEM_RESET, PAGE_READWRITE); + } +#else + /* Dummy implementation. */ + ERTS_GLB_INLINE void erts_mem_discard(void *ptr, UWord size) { + (void)ptr; + (void)size; + } +#endif + +#endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */ + #endif /* ERL_MMAP_H__ */ diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c index a1c630d68a..b95aadc9b2 100644 --- a/erts/emulator/sys/win32/sys.c +++ b/erts/emulator/sys/win32/sys.c @@ -186,7 +186,9 @@ void sys_primitive_init(HMODULE beam) UWord erts_sys_get_page_size(void) { - return (UWord) 4*1024; /* Guess 4 KB */ + SYSTEM_INFO info; + GetSystemInfo(&info); + return (UWord)info.dwPageSize; } Uint |