Page MenuHome
Paste P2856

Realloc usable size (experement)
ActivePublic

Authored by Campbell Barton (campbellbarton) on Mar 28 2022, 9:02 AM.
diff --git a/intern/guardedalloc/CMakeLists.txt b/intern/guardedalloc/CMakeLists.txt
index 3329e4bf10e..c28dc03e029 100644
--- a/intern/guardedalloc/CMakeLists.txt
+++ b/intern/guardedalloc/CMakeLists.txt
@@ -46,6 +46,24 @@ if(WITH_MEM_JEMALLOC AND NOT ("${JEMALLOC_VERSION}" VERSION_LESS "5.0.0"))
add_definitions(-DWITH_JEMALLOC_CONF)
endif()
+# Check for `malloc_usable_size`.
+if(NOT DEFINED HAS_MALLOC_USABLE_SIZE)
+ # result cached
+ check_c_source_runs("
+ #include <malloc.h>
+ int main(void) {
+ int *v = malloc(sizeof(int));
+ int i = malloc_usable_size(v);
+ free(v);
+ return i != 0;
+ }"
+ HAS_MALLOC_USABLE_SIZE)
+endif()
+
+if(HAS_MALLOC_USABLE_SIZE)
+ add_definitions(-DHAS_MALLOC_USABLE_SIZE)
+endif()
+
blender_add_lib(bf_intern_guardedalloc "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
# Override C++ alloc, optional.
diff --git a/intern/guardedalloc/intern/mallocn_lockfree_impl.c b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
index 73912ad07b1..ed0290f83fa 100644
--- a/intern/guardedalloc/intern/mallocn_lockfree_impl.c
+++ b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
@@ -20,6 +20,9 @@
#include "atomic_ops.h"
#include "mallocn_intern.h"
+/* FIXME: use value from CMake. */
+#define HAS_MALLOC_USABLE_SIZE 1
+
typedef struct MemHead {
/* Length of allocated memory block. */
size_t len;
@@ -145,10 +148,28 @@ void *MEM_lockfree_reallocN_id(void *vmemh, size_t len, const char *str)
size_t old_len = MEM_lockfree_allocN_len(vmemh);
if (LIKELY(!MEMHEAD_IS_ALIGNED(memh))) {
+#ifdef HAS_MALLOC_USABLE_SIZE
+ printf("realloc: %d %d %d\n", (int)old_len, (int)len, (int)malloc_usable_size(memh));
+ if ((old_len <= len) && (sizeof(MemHead) + len <= malloc_usable_size(memh))) {
+ atomic_add_and_fetch_z(&mem_in_use, len - old_len);
+ update_maximum(&peak_mem, mem_in_use);
+ memh->len = len;
+ return memh + 1;
+ }
+#endif
newp = MEM_lockfree_mallocN(len, "realloc");
}
else {
MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
+#ifdef HAS_MALLOC_USABLE_SIZE
+ printf("realloc: %d %d %d\n", (int)old_len, (int)len, (int)malloc_usable_size(memh_aligned));
+ if ((old_len <= len) && (sizeof(MemHeadAligned) + len <= malloc_usable_size(memh_aligned))) {
+ atomic_add_and_fetch_z(&mem_in_use, len - old_len);
+ update_maximum(&peak_mem, mem_in_use);
+ memh_aligned->len = len | (size_t)MEMHEAD_ALIGN_FLAG;
+ return memh_aligned + 1;
+ }
+#endif
newp = MEM_lockfree_mallocN_aligned(len, (size_t)memh_aligned->alignment, "realloc");
}
@@ -181,10 +202,33 @@ void *MEM_lockfree_recallocN_id(void *vmemh, size_t len, const char *str)
size_t old_len = MEM_lockfree_allocN_len(vmemh);
if (LIKELY(!MEMHEAD_IS_ALIGNED(memh))) {
+#ifdef HAS_MALLOC_USABLE_SIZE
+ printf("recalloc: %d %d %d\n", (int)old_len, (int)len, (int)malloc_usable_size(memh));
+ if ((old_len <= len) && (sizeof(MemHead) + len <= malloc_usable_size(memh))) {
+ atomic_add_and_fetch_z(&mem_in_use, len - old_len);
+ update_maximum(&peak_mem, mem_in_use);
+ memh->len = len;
+ newp = memh + 1;
+ memset(((char *)newp) + old_len, 0, len - old_len);
+ return newp;
+ }
+#endif
newp = MEM_lockfree_mallocN(len, "recalloc");
}
else {
MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
+#ifdef HAS_MALLOC_USABLE_SIZE
+ printf(
+ "recalloc: %d %d %d\n", (int)old_len, (int)len, (int)malloc_usable_size(memh_aligned));
+ if ((old_len <= len) && (sizeof(MemHeadAligned) + len <= malloc_usable_size(memh_aligned))) {
+ atomic_add_and_fetch_z(&mem_in_use, len - old_len);
+ update_maximum(&peak_mem, mem_in_use);
+ memh_aligned->len = len | (size_t)MEMHEAD_ALIGN_FLAG;
+ newp = memh_aligned + 1;
+ memset(((char *)newp) + old_len, 0, len - old_len);
+ return newp;
+ }
+#endif
newp = MEM_lockfree_mallocN_aligned(len, (size_t)memh_aligned->alignment, "recalloc");
}

Event Timeline

Campbell Barton (campbellbarton) changed the title of this paste from Realloc usable size to Realloc usable size (experement).
Campbell Barton (campbellbarton) updated the paste's language from autodetect to diff.