aboutsummaryrefslogtreecommitdiff
path: root/src/common_memory.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2023-04-21 13:29:38 +0100
committergingerBill <bill@gingerbill.org>2023-04-21 13:29:38 +0100
commita95b064d6d0a2e3dfa8c414be60ae966a099adfd (patch)
tree6f41ef1d5b4794173204e129c616a93a3259776c /src/common_memory.cpp
parentc503a758733b921cfd8dc9f63bddd6ecdc3fe2e1 (diff)
Fix memory leak caused by awful realloc usage on Linux
Diffstat (limited to 'src/common_memory.cpp')
-rw-r--r--src/common_memory.cpp37
1 files changed, 26 insertions, 11 deletions
diff --git a/src/common_memory.cpp b/src/common_memory.cpp
index f33fb0dff..d6a87529f 100644
--- a/src/common_memory.cpp
+++ b/src/common_memory.cpp
@@ -1,3 +1,4 @@
+#include <malloc.h>
gb_internal gb_inline void zero_size(void *ptr, isize len) {
memset(ptr, 0, len);
@@ -121,7 +122,6 @@ struct PlatformMemoryBlock {
PlatformMemoryBlock *prev, *next;
};
-
gb_global std::atomic<isize> global_platform_memory_total_usage;
gb_global PlatformMemoryBlock global_platform_memory_block_sentinel;
@@ -177,12 +177,12 @@ gb_internal void platform_virtual_memory_protect(void *memory, isize size);
gb_printf_err("Total Usage: %lld bytes\n", cast(long long)global_platform_memory_total_usage);
GB_ASSERT_MSG(pmblock != nullptr, "Out of Virtual Memory, oh no...");
}
- global_platform_memory_total_usage += total_size;
+ global_platform_memory_total_usage.fetch_add(total_size);
return pmblock;
}
gb_internal void platform_virtual_memory_free(PlatformMemoryBlock *block) {
isize size = block->total_size;
- global_platform_memory_total_usage -= size;
+ global_platform_memory_total_usage.fetch_sub(size);
munmap(block, size);
}
gb_internal void platform_virtual_memory_protect(void *memory, isize size) {
@@ -396,6 +396,8 @@ gb_internal gbAllocator heap_allocator(void) {
return a;
}
+gb_internal std::atomic<isize> total_heap_memory_allocated;
+
gb_internal GB_ALLOCATOR_PROC(heap_allocator_proc) {
void *ptr = nullptr;
@@ -403,7 +405,6 @@ gb_internal GB_ALLOCATOR_PROC(heap_allocator_proc) {
gb_unused(old_size);
-
// TODO(bill): Throughly test!
switch (type) {
#if defined(GB_COMPILER_MSVC)
@@ -436,28 +437,34 @@ gb_internal GB_ALLOCATOR_PROC(heap_allocator_proc) {
#elif defined(GB_SYSTEM_LINUX)
// TODO(bill): *nix version that's decent
case gbAllocation_Alloc: {
- ptr = aligned_alloc(alignment, (size + alignment - 1) & ~(alignment - 1));
+ isize total_size = (size + alignment - 1) & ~(alignment - 1);
+ total_heap_memory_allocated.fetch_add(total_size);
+ ptr = aligned_alloc(alignment, total_size);
gb_zero_size(ptr, size);
} break;
case gbAllocation_Free:
if (old_memory != nullptr) {
+ total_heap_memory_allocated.fetch_sub(malloc_usable_size(old_memory));
free(old_memory);
}
break;
- case gbAllocation_Resize:
+ case gbAllocation_Resize: {
if (size == 0) {
if (old_memory != nullptr) {
+ total_heap_memory_allocated.fetch_sub(malloc_usable_size(old_memory));
free(old_memory);
}
break;
}
-
+
alignment = gb_max(alignment, gb_align_of(max_align_t));
-
+
if (old_memory == nullptr) {
- ptr = aligned_alloc(alignment, (size + alignment - 1) & ~(alignment - 1));
+ isize total_size = (size + alignment - 1) & ~(alignment - 1);
+ total_heap_memory_allocated.fetch_add(total_size);
+ ptr = aligned_alloc(alignment, total_size);
gb_zero_size(ptr, size);
break;
}
@@ -466,11 +473,19 @@ gb_internal GB_ALLOCATOR_PROC(heap_allocator_proc) {
break;
}
- ptr = aligned_alloc(alignment, (size + alignment - 1) & ~(alignment - 1));
+ size_t actual_old_size = malloc_usable_size(old_memory);
+ if (size <= actual_old_size) {
+ ptr = old_memory;
+ break;
+ }
+
+ isize total_size = (size + alignment - 1) & ~(alignment - 1);
+ total_heap_memory_allocated.fetch_add(total_size);
+ ptr = aligned_alloc(alignment, total_size);
gb_memmove(ptr, old_memory, old_size);
free(old_memory);
gb_zero_size(cast(u8 *)ptr + old_size, gb_max(size-old_size, 0));
- break;
+ } break;
#else
// TODO(bill): *nix version that's decent
case gbAllocation_Alloc: {