Browse Source

Improve reliability of memory stats

The allocation count is managed atomically and where it actually should
change (for instance, not counting an allocation before its success has
been checked).

Bonus: Improve readability of the pre-pad checks.
Pedro J. Estébanez 8 years ago
parent
commit
490a2ff0b9
2 changed files with 27 additions and 51 deletions
  1. 26 49
      core/os/memory.cpp
  2. 1 2
      core/os/memory.h

+ 26 - 49
core/os/memory.cpp

@@ -29,6 +29,7 @@
 /*************************************************************************/
 /*************************************************************************/
 #include "memory.h"
 #include "memory.h"
 #include "copymem.h"
 #include "copymem.h"
+#include "core/safe_refcount.h"
 #include "error_macros.h"
 #include "error_macros.h"
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
@@ -43,41 +44,36 @@ void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)) {
 	return p_allocfunc(p_size);
 	return p_allocfunc(p_size);
 }
 }
 
 
-#include <stdio.h>
-
 #ifdef DEBUG_ENABLED
 #ifdef DEBUG_ENABLED
 size_t Memory::mem_usage = 0;
 size_t Memory::mem_usage = 0;
 size_t Memory::max_usage = 0;
 size_t Memory::max_usage = 0;
+#define PREPAD true
+#else
+#define PREPAD p_pad_align
 #endif
 #endif
 
 
-size_t Memory::alloc_count = 0;
+uint64_t Memory::alloc_count = 0;
 
 
 void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
 void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
 
 
-#ifdef DEBUG_ENABLED
-	bool prepad = true;
-#else
-	bool prepad = p_pad_align;
-#endif
-
-	void *mem = malloc(p_bytes + (prepad ? PAD_ALIGN : 0));
-
-	alloc_count++;
+	void *mem = malloc(p_bytes + (PREPAD ? PAD_ALIGN : 0));
 
 
 	ERR_FAIL_COND_V(!mem, NULL);
 	ERR_FAIL_COND_V(!mem, NULL);
 
 
-	if (prepad) {
-		uint64_t *s = (uint64_t *)mem;
-		*s = p_bytes;
-
-		uint8_t *s8 = (uint8_t *)mem;
+	atomic_increment(&alloc_count);
 
 
+	if (PREPAD) {
 #ifdef DEBUG_ENABLED
 #ifdef DEBUG_ENABLED
 		mem_usage += p_bytes;
 		mem_usage += p_bytes;
 		if (mem_usage > max_usage) {
 		if (mem_usage > max_usage) {
 			max_usage = mem_usage;
 			max_usage = mem_usage;
 		}
 		}
 #endif
 #endif
+
+		uint64_t *s = (uint64_t *)mem;
+		*s = p_bytes;
+
+		uint8_t *s8 = (uint8_t *)mem;
 		return s8 + PAD_ALIGN;
 		return s8 + PAD_ALIGN;
 	} else {
 	} else {
 		return mem;
 		return mem;
@@ -92,38 +88,30 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) {
 
 
 	uint8_t *mem = (uint8_t *)p_memory;
 	uint8_t *mem = (uint8_t *)p_memory;
 
 
-#ifdef DEBUG_ENABLED
-	bool prepad = true;
-#else
-	bool prepad = p_pad_align;
-#endif
-
-	if (prepad) {
+	if (PREPAD) {
 		mem -= PAD_ALIGN;
 		mem -= PAD_ALIGN;
 		uint64_t *s = (uint64_t *)mem;
 		uint64_t *s = (uint64_t *)mem;
 
 
+		if (p_bytes == 0) {
 #ifdef DEBUG_ENABLED
 #ifdef DEBUG_ENABLED
-		mem_usage -= *s;
-		mem_usage += p_bytes;
+			mem_usage -= *s;
 #endif
 #endif
-
-		if (p_bytes == 0) {
 			free(mem);
 			free(mem);
 			return NULL;
 			return NULL;
 		} else {
 		} else {
-			*s = p_bytes;
-
 			mem = (uint8_t *)realloc(mem, p_bytes + PAD_ALIGN);
 			mem = (uint8_t *)realloc(mem, p_bytes + PAD_ALIGN);
 			ERR_FAIL_COND_V(!mem, NULL);
 			ERR_FAIL_COND_V(!mem, NULL);
 
 
 			s = (uint64_t *)mem;
 			s = (uint64_t *)mem;
-
+#ifdef DEBUG_ENABLED
+			mem_usage -= *s;
+			mem_usage += p_bytes;
+#endif
 			*s = p_bytes;
 			*s = p_bytes;
 
 
 			return mem + PAD_ALIGN;
 			return mem + PAD_ALIGN;
 		}
 		}
 	} else {
 	} else {
-
 		mem = (uint8_t *)realloc(mem, p_bytes);
 		mem = (uint8_t *)realloc(mem, p_bytes);
 
 
 		ERR_FAIL_COND_V(mem == NULL && p_bytes > 0, NULL);
 		ERR_FAIL_COND_V(mem == NULL && p_bytes > 0, NULL);
@@ -138,27 +126,16 @@ void Memory::free_static(void *p_ptr, bool p_pad_align) {
 
 
 	uint8_t *mem = (uint8_t *)p_ptr;
 	uint8_t *mem = (uint8_t *)p_ptr;
 
 
-#ifdef DEBUG_ENABLED
-	bool prepad = true;
-#else
-	bool prepad = p_pad_align;
-#endif
-
-	alloc_count--;
-
-	if (prepad) {
+	if (PREPAD) {
 		mem -= PAD_ALIGN;
 		mem -= PAD_ALIGN;
-		uint64_t *s = (uint64_t *)mem;
-
 #ifdef DEBUG_ENABLED
 #ifdef DEBUG_ENABLED
-		mem_usage -= *s;
+		const uint64_t s = *((uint64_t *)mem);
+		mem_usage -= s;
 #endif
 #endif
-
-		free(mem);
-	} else {
-
-		free(mem);
 	}
 	}
+	atomic_decrement(&alloc_count);
+
+	free(mem);
 }
 }
 
 
 size_t Memory::get_mem_available() {
 size_t Memory::get_mem_available() {

+ 1 - 2
core/os/memory.h

@@ -48,8 +48,7 @@ class Memory {
 	static size_t mem_usage;
 	static size_t mem_usage;
 	static size_t max_usage;
 	static size_t max_usage;
 #endif
 #endif
-
-	static size_t alloc_count;
+	static uint64_t alloc_count;
 
 
 public:
 public:
 	static void *alloc_static(size_t p_bytes, bool p_pad_align = false);
 	static void *alloc_static(size_t p_bytes, bool p_pad_align = false);