aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/sys
diff options
context:
space:
mode:
authorJohn Högberg <[email protected]>2018-12-07 12:31:33 +0100
committerGitHub <[email protected]>2018-12-07 12:31:33 +0100
commit689f9d5cf041ed9c16b4b31a66c50eac57b2f6f0 (patch)
treeece2f373bfd5d4a5a1d070e6224c06b08848f769 /erts/emulator/sys
parentea7d6c39f2179b2240d55df4a1ddd515b6d32832 (diff)
parent1d549eddbeeccf7d108310466de5f63af04b004c (diff)
downloadotp-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.h57
-rw-r--r--erts/emulator/sys/win32/sys.c4
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