From 54d1c8b93adbeee5838b8dadabeb789b9fa6c511 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sat, 17 Oct 2015 20:12:15 +0300 Subject: rename malloc.c/h to memmgr. --- src/common/HPM.c | 2 +- src/common/Makefile.in | 8 +- src/common/console.c | 2 +- src/common/core.c | 2 +- src/common/db.c | 2 +- src/common/ers.c | 2 +- src/common/grfio.c | 2 +- src/common/malloc.c | 897 ------------------------------------------------- src/common/malloc.h | 89 ----- src/common/memmgr.c | 897 +++++++++++++++++++++++++++++++++++++++++++++++++ src/common/memmgr.h | 89 +++++ src/common/mutex.c | 2 +- src/common/socket.c | 2 +- src/common/sql.c | 2 +- src/common/strlib.c | 2 +- src/common/sysinfo.c | 2 +- src/common/thread.c | 2 +- src/common/timer.c | 2 +- 18 files changed, 1003 insertions(+), 1003 deletions(-) delete mode 100644 src/common/malloc.c delete mode 100644 src/common/malloc.h create mode 100644 src/common/memmgr.c create mode 100644 src/common/memmgr.h (limited to 'src/common') diff --git a/src/common/HPM.c b/src/common/HPM.c index 5373c8b6a..7d9a0b104 100644 --- a/src/common/HPM.c +++ b/src/common/HPM.c @@ -11,7 +11,7 @@ #include "common/console.h" #include "common/core.h" #include "common/db.h" -#include "common/malloc.h" +#include "common/memmgr.h" #include "common/mapindex.h" #include "common/mmo.h" #include "common/showmsg.h" diff --git a/src/common/Makefile.in b/src/common/Makefile.in index 208d3b111..88e991651 100644 --- a/src/common/Makefile.in +++ b/src/common/Makefile.in @@ -27,12 +27,12 @@ COMMON_SHARED_C = conf.c db.c des.c ers.c grfio.c HPM.c mapindex.c md5calc.c \ COMMON_C = $(COMMON_SHARED_C) COMMON_SHARED_OBJ = $(patsubst %.c,%.o,$(COMMON_SHARED_C)) COMMON_OBJ = $(addprefix obj_all/, $(COMMON_SHARED_OBJ) \ - console.o core.o malloc.o socket.o) + console.o core.o memmgr.o socket.o) COMMON_MINI_OBJ = $(addprefix obj_all/, $(COMMON_SHARED_OBJ) \ - miniconsole.o minicore.o minimalloc.o minisocket.o) -COMMON_C += console.c core.c malloc.c socket.c + miniconsole.o minicore.o minimemmgr.o minisocket.o) +COMMON_C += console.c core.c memmgr.c socket.c COMMON_H = atomic.h cbasetypes.h conf.h console.h core.h db.h des.h ers.h \ - grfio.h hercules.h HPM.h HPMi.h malloc.h mapindex.h md5calc.h \ + grfio.h hercules.h HPM.h HPMi.h memmgr.h mapindex.h md5calc.h \ mmo.h mutex.h nullpo.h random.h showmsg.h socket.h spinlock.h \ sql.h strlib.h sysinfo.h thread.h timer.h utils.h winapi.h diff --git a/src/common/console.c b/src/common/console.c index c8ca4ae87..f4f18b799 100644 --- a/src/common/console.c +++ b/src/common/console.c @@ -16,7 +16,7 @@ #ifndef MINICORE # include "common/atomic.h" # include "common/ers.h" -# include "common/malloc.h" +# include "common/memmgr.h" # include "common/mutex.h" # include "common/spinlock.h" # include "common/sql.h" diff --git a/src/common/core.c b/src/common/core.c index 8564b8acc..6f21f526b 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -10,7 +10,7 @@ #include "common/cbasetypes.h" #include "common/console.h" #include "common/db.h" -#include "common/malloc.h" +#include "common/memmgr.h" #include "common/mmo.h" #include "common/random.h" #include "common/showmsg.h" diff --git a/src/common/db.c b/src/common/db.c index 4df5c08db..0600be2e8 100644 --- a/src/common/db.c +++ b/src/common/db.c @@ -73,7 +73,7 @@ #include "db.h" #include "common/ers.h" -#include "common/malloc.h" +#include "common/memmgr.h" #include "common/mmo.h" #include "common/showmsg.h" #include "common/strlib.h" diff --git a/src/common/ers.c b/src/common/ers.c index 91fc6ccfb..bf17e087d 100644 --- a/src/common/ers.c +++ b/src/common/ers.c @@ -45,7 +45,7 @@ #include "ers.h" #include "common/cbasetypes.h" -#include "common/malloc.h" // CREATE, RECREATE, aMalloc, aFree +#include "common/memmgr.h" // CREATE, RECREATE, aMalloc, aFree #include "common/nullpo.h" #include "common/showmsg.h" // ShowMessage, ShowError, ShowFatalError, CL_BOLD, CL_NORMAL diff --git a/src/common/grfio.c b/src/common/grfio.c index b59c2b63d..46804ea08 100644 --- a/src/common/grfio.c +++ b/src/common/grfio.c @@ -8,7 +8,7 @@ #include "common/cbasetypes.h" #include "common/des.h" -#include "common/malloc.h" +#include "common/memmgr.h" #include "common/nullpo.h" #include "common/showmsg.h" #include "common/strlib.h" diff --git a/src/common/malloc.c b/src/common/malloc.c deleted file mode 100644 index 63de90cb3..000000000 --- a/src/common/malloc.c +++ /dev/null @@ -1,897 +0,0 @@ -// Copyright (c) Hercules Dev Team, licensed under GNU GPL. -// See the LICENSE file -// Portions Copyright (c) Athena Dev Teams - -#define HERCULES_CORE - -#include "malloc.h" - -#include "common/cbasetypes.h" -#include "common/core.h" -#include "common/showmsg.h" -#include "common/sysinfo.h" - -#include -#include -#include - -struct malloc_interface iMalloc_s; -struct malloc_interface *iMalloc; - -////////////// Memory Libraries ////////////////// - -#if defined(MEMWATCH) - -# include -# include -# define MALLOC(n,file,line,func) mwMalloc((n),(file),(line)) -# define CALLOC(m,n,file,line,func) mwCalloc((m),(n),(file),(line)) -# define REALLOC(p,n,file,line,func) mwRealloc((p),(n),(file),(line)) -# define STRDUP(p,file,line,func) mwStrdup((p),(file),(line)) -# define FREE(p,file,line,func) mwFree((p),(file),(line)) -# define MEMORY_USAGE() (size_t)0 -# define MEMORY_VERIFY(ptr) mwIsSafeAddr((ptr), 1) -# define MEMORY_CHECK() CHECK() - -#elif defined(DMALLOC) - -# include -# include -# include -# define MALLOC(n,file,line,func) dmalloc_malloc((file),(line),(n),DMALLOC_FUNC_MALLOC,0,0) -# define CALLOC(m,n,file,line,func) dmalloc_malloc((file),(line),(m)*(n),DMALLOC_FUNC_CALLOC,0,0) -# define REALLOC(p,n,file,line,func) dmalloc_realloc((file),(line),(p),(n),DMALLOC_FUNC_REALLOC,0) -# define STRDUP(p,file,line,func) strdup(p) -# define FREE(p,file,line,func) free(p) -# define MEMORY_USAGE() dmalloc_memory_allocated() -# define MEMORY_VERIFY(ptr) (dmalloc_verify(ptr) == DMALLOC_VERIFY_NOERROR) -# define MEMORY_CHECK() do { dmalloc_log_stats(); dmalloc_log_unfreed() } while(0) - -#elif defined(GCOLLECT) - -# include -# ifdef GC_ADD_CALLER -# define RETURN_ADDR 0, -# else -# define RETURN_ADDR -# endif -# define MALLOC(n,file,line,func) GC_debug_malloc((n), RETURN_ADDR (file),(line)) -# define CALLOC(m,n,file,line,func) GC_debug_malloc((m)*(n), RETURN_ADDR (file),(line)) -# define REALLOC(p,n,file,line,func) GC_debug_realloc((p),(n), RETURN_ADDR (file),(line)) -# define STRDUP(p,file,line,func) GC_debug_strdup((p), RETURN_ADDR (file),(line)) -# define FREE(p,file,line,func) GC_debug_free(p) -# define MEMORY_USAGE() GC_get_heap_size() -# define MEMORY_VERIFY(ptr) (GC_base(ptr) != NULL) -# define MEMORY_CHECK() GC_gcollect() - -# undef RETURN_ADDR - -#else - -# define MALLOC(n,file,line,func) malloc(n) -# define CALLOC(m,n,file,line,func) calloc((m),(n)) -# define REALLOC(p,n,file,line,func) realloc((p),(n)) -# define STRDUP(p,file,line,func) strdup(p) -# define FREE(p,file,line,func) free(p) -# define MEMORY_USAGE() (size_t)0 -# define MEMORY_VERIFY(ptr) true -# define MEMORY_CHECK() - -#endif - -void* aMalloc_(size_t size, const char *file, int line, const char *func) -{ - void *ret = MALLOC(size, file, line, func); - // ShowMessage("%s:%d: in func %s: aMalloc %d\n",file,line,func,size); - if (ret == NULL){ - ShowFatalError("%s:%d: in func %s: aMalloc error out of memory!\n",file,line,func); - exit(EXIT_FAILURE); - } - - return ret; -} -void* aCalloc_(size_t num, size_t size, const char *file, int line, const char *func) -{ - void *ret = CALLOC(num, size, file, line, func); - // ShowMessage("%s:%d: in func %s: aCalloc %d %d\n",file,line,func,num,size); - if (ret == NULL){ - ShowFatalError("%s:%d: in func %s: aCalloc error out of memory!\n", file, line, func); - exit(EXIT_FAILURE); - } - return ret; -} -void* aRealloc_(void *p, size_t size, const char *file, int line, const char *func) -{ - void *ret = REALLOC(p, size, file, line, func); - // ShowMessage("%s:%d: in func %s: aRealloc %p %d\n",file,line,func,p,size); - if (ret == NULL){ - ShowFatalError("%s:%d: in func %s: aRealloc error out of memory!\n",file,line,func); - exit(EXIT_FAILURE); - } - return ret; -} -char* aStrdup_(const char *p, const char *file, int line, const char *func) -{ - char *ret = STRDUP(p, file, line, func); - // ShowMessage("%s:%d: in func %s: aStrdup %p\n",file,line,func,p); - if (ret == NULL){ - ShowFatalError("%s:%d: in func %s: aStrdup error out of memory!\n", file, line, func); - exit(EXIT_FAILURE); - } - return ret; -} -void aFree_(void *p, const char *file, int line, const char *func) -{ - // ShowMessage("%s:%d: in func %s: aFree %p\n",file,line,func,p); - if (p) - FREE(p, file, line, func); - //p = NULL; -} - - -#ifdef USE_MEMMGR - -#if defined(DEBUG) -#define DEBUG_MEMMGR -#endif - -/* USE_MEMMGR */ - -/* -* Memory manager -* able to handle malloc and free efficiently -* Since the complex processing, I might be slightly heavier. -* -* (I'm sorry for the poor description ^ ^;) such as data structures -* Divided into "blocks" of a plurality of memory, "unit" of a plurality of blocks further -* I have to divide. Size of the unit, a plurality of distribution equal to the capacity of one block -* That's what you have. For example, if one unit of 32KB, one block 1 Yu 32Byte -* Knit, or are able to gather 1024, gathered 512 units 64Byte -* I can be or have. (Excluding padding, the unit_head) -* -* Lead-linked list (block_prev, block_next) in each other is the same size block -* Linked list (hash_prev, hash_nect) even among such one in the block with the figure -* I like to have. Thus, reuse of memory no longer needed can be performed efficiently. -*/ - -/* Alignment of the block */ -#define BLOCK_ALIGNMENT1 16 -#define BLOCK_ALIGNMENT2 64 - -/* Amount of data entering a block */ -#define BLOCK_DATA_COUNT1 128 -#define BLOCK_DATA_COUNT2 608 - -/* The size of the block: 16*128 + 64*576 = 40KB */ -#define BLOCK_DATA_SIZE1 ( BLOCK_ALIGNMENT1 * BLOCK_DATA_COUNT1 ) -#define BLOCK_DATA_SIZE2 ( BLOCK_ALIGNMENT2 * BLOCK_DATA_COUNT2 ) -#define BLOCK_DATA_SIZE ( BLOCK_DATA_SIZE1 + BLOCK_DATA_SIZE2 ) - -/* The number of blocks to be allocated at a time. */ -#define BLOCK_ALLOC 104 - -/* block */ -struct block { - struct block *block_next; ///< Then the allocated area - struct block *unfill_prev; ///< The previous area not filled - struct block *unfill_next; ///< The next area not filled - unsigned short unit_size; ///< The size of the unit - unsigned short unit_hash; ///< The hash of the unit - unsigned short unit_count; ///< The number of units - unsigned short unit_used; ///< The number of used units - unsigned short unit_unfill; ///< The number of unused units - unsigned short unit_maxused; ///< The maximum value of units used - char data[BLOCK_DATA_SIZE]; -}; - -struct unit_head { - struct block *block; - const char* file; - unsigned short line; - unsigned short size; - long checksum; -}; - -static struct block* hash_unfill[BLOCK_DATA_COUNT1 + BLOCK_DATA_COUNT2 + 1]; -static struct block* block_first, *block_last, block_head; - -/* Data for areas that do not use the memory be turned */ -struct unit_head_large { - size_t size; - struct unit_head_large* prev; - struct unit_head_large* next; - struct unit_head unit_head; -}; - -static struct unit_head_large *unit_head_large_first = NULL; - -static struct block* block_malloc(unsigned short hash); -static void block_free(struct block* p); -static size_t memmgr_usage_bytes; -static size_t memmgr_usage_bytes_t; - - -#define block2unit(p, n) ((struct unit_head*)(&(p)->data[ p->unit_size * (n) ])) -#define memmgr_assert(v) do { if(!(v)) { ShowError("Memory manager: assertion '" #v "' failed!\n"); } } while(0) - -static unsigned short size2hash( size_t size ) -{ - if( size <= BLOCK_DATA_SIZE1 ) { - return (unsigned short)(size + BLOCK_ALIGNMENT1 - 1) / BLOCK_ALIGNMENT1; - } else if( size <= BLOCK_DATA_SIZE ){ - return (unsigned short)(size - BLOCK_DATA_SIZE1 + BLOCK_ALIGNMENT2 - 1) / BLOCK_ALIGNMENT2 - + BLOCK_DATA_COUNT1; - } else { - return 0xffff; // If it exceeds the block length hash I do not - } -} - -static size_t hash2size( unsigned short hash ) -{ - if( hash <= BLOCK_DATA_COUNT1) { - return hash * BLOCK_ALIGNMENT1; - } else { - return (hash - BLOCK_DATA_COUNT1) * BLOCK_ALIGNMENT2 + BLOCK_DATA_SIZE1; - } -} - -void *mmalloc_(size_t size, const char *file, int line, const char *func) { - struct block *block; - short size_hash = size2hash( size ); - struct unit_head *head; - - if (((long) size) < 0) { - ShowError("mmalloc_: %"PRIdS"\n", size); - return NULL; - } - - if(size == 0) { - return NULL; - } - memmgr_usage_bytes += size; - - /* To ensure the area that exceeds the length of the block, using malloc () to */ - /* At that time, the distinction by assigning NULL to unit_head.block */ - if(hash2size(size_hash) > BLOCK_DATA_SIZE - sizeof(struct unit_head)) { - struct unit_head_large* p = (struct unit_head_large*)MALLOC(sizeof(struct unit_head_large)+size,file,line,func); - memmgr_usage_bytes_t += size+sizeof(struct unit_head_large); - if(p != NULL) { - p->size = size; - p->unit_head.block = NULL; - p->unit_head.size = 0; - p->unit_head.file = file; - p->unit_head.line = (unsigned short)line; - p->prev = NULL; - if (unit_head_large_first == NULL) - p->next = NULL; - else { - unit_head_large_first->prev = p; - p->next = unit_head_large_first; - } - unit_head_large_first = p; - *(long*)((char*)p + sizeof(struct unit_head_large) - sizeof(long) + size) = 0xdeadbeaf; - return (char *)p + sizeof(struct unit_head_large) - sizeof(long); - } else { - ShowFatalError("Memory manager::memmgr_alloc failed (allocating %"PRIuS"+%"PRIuS" bytes at %s:%d).\n", - sizeof(struct unit_head_large), size, file, line); - exit(EXIT_FAILURE); - } - } - - /* When a block of the same size is not ensured, to ensure a new */ - if(hash_unfill[size_hash]) { - block = hash_unfill[size_hash]; - } else { - block = block_malloc(size_hash); - } - - if( block->unit_unfill == 0xFFFF ) { - // there are no more free space that - memmgr_assert(block->unit_used < block->unit_count); - memmgr_assert(block->unit_used == block->unit_maxused); - head = block2unit(block, block->unit_maxused); - block->unit_used++; - block->unit_maxused++; - } else { - head = block2unit(block, block->unit_unfill); - block->unit_unfill = head->size; - block->unit_used++; - } - - if( block->unit_unfill == 0xFFFF && block->unit_maxused >= block->unit_count) { - // Since I ran out of the unit, removed from the list unfill - if( block->unfill_prev == &block_head) { - hash_unfill[ size_hash ] = block->unfill_next; - } else { - block->unfill_prev->unfill_next = block->unfill_next; - } - if( block->unfill_next ) { - block->unfill_next->unfill_prev = block->unfill_prev; - } - block->unfill_prev = NULL; - } - -#ifdef DEBUG_MEMMGR - { - size_t i, sz = hash2size( size_hash ); - for( i=0; iline != 0xfdfd ) - { - ShowError("Memory manager: freed-data is changed. (freed in %s line %d)\n", head->file,head->line); - } - else - { - ShowError("Memory manager: not-allocated-data is changed.\n"); - } - break; - } - } - memset( (char *)head + sizeof(struct unit_head) - sizeof(long), 0xcd, sz ); - } -#endif - - head->block = block; - head->file = file; - head->line = (unsigned short)line; - head->size = (unsigned short)size; - *(long*)((char*)head + sizeof(struct unit_head) - sizeof(long) + size) = 0xdeadbeaf; - return (char *)head + sizeof(struct unit_head) - sizeof(long); -} - -void *mcalloc_(size_t num, size_t size, const char *file, int line, const char *func) { - void *p = iMalloc->malloc(num * size,file,line,func); - if (p) - memset(p, 0, num * size); - return p; -} - -void *mrealloc_(void *memblock, size_t size, const char *file, int line, const char *func) { - size_t old_size; - if(memblock == NULL) { - return iMalloc->malloc(size,file,line,func); - } - - old_size = ((struct unit_head *)((char *)memblock - sizeof(struct unit_head) + sizeof(long)))->size; - if( old_size == 0 ) { - old_size = ((struct unit_head_large *)((char *)memblock - sizeof(struct unit_head_large) + sizeof(long)))->size; - } - if(old_size > size) { - // Size reduction - return> as it is (negligence) - return memblock; - } else { - // Size Large - void *p = iMalloc->malloc(size,file,line,func); - if(p != NULL) { - memcpy(p,memblock,old_size); - } - iMalloc->free(memblock,file,line,func); - return p; - } -} - -/* a mrealloc_ clone with the difference it 'z'eroes the newly created memory */ -void *mreallocz_(void *memblock, size_t size, const char *file, int line, const char *func) { - size_t old_size; - void *p = NULL; - - if(memblock == NULL) { - p = iMalloc->malloc(size,file,line,func); - memset(p,0,size); - return p; - } - - old_size = ((struct unit_head *)((char *)memblock - sizeof(struct unit_head) + sizeof(long)))->size; - if( old_size == 0 ) { - old_size = ((struct unit_head_large *)((char *)memblock - sizeof(struct unit_head_large) + sizeof(long)))->size; - } - if(old_size > size) { - // Size reduction - return> as it is (negligence) - return memblock; - } else { - // Size Large - p = iMalloc->malloc(size,file,line,func); - if(p != NULL) { - memcpy(p,memblock,old_size); - memset((char*)p+old_size,0,size-old_size); - } - iMalloc->free(memblock,file,line,func); - return p; - } -} - - -char *mstrdup_(const char *p, const char *file, int line, const char *func) { - if(p == NULL) { - return NULL; - } else { - size_t len = strlen(p); - char *string = (char *)iMalloc->malloc(len + 1,file,line,func); - memcpy(string,p,len+1); - return string; - } -} - -void mfree_(void *ptr, const char *file, int line, const char *func) { - struct unit_head *head; - - if (ptr == NULL) - return; - - head = (struct unit_head *)((char *)ptr - sizeof(struct unit_head) + sizeof(long)); - if(head->size == 0) { - /* area that is directly secured by malloc () */ - struct unit_head_large *head_large = (struct unit_head_large *)((char *)ptr - sizeof(struct unit_head_large) + sizeof(long)); - if( - *(long*)((char*)head_large + sizeof(struct unit_head_large) - sizeof(long) + head_large->size) - != 0xdeadbeaf) - { - ShowError("Memory manager: args of aFree 0x%p is overflowed pointer %s line %d\n", ptr, file, line); - } else { - head->size = 0xFFFF; - if(head_large->prev) { - head_large->prev->next = head_large->next; - } else { - unit_head_large_first = head_large->next; - } - if(head_large->next) { - head_large->next->prev = head_large->prev; - } - memmgr_usage_bytes -= head_large->size; - memmgr_usage_bytes_t -= head_large->size + sizeof(struct unit_head_large); -#ifdef DEBUG_MEMMGR - // set freed memory to 0xfd - memset(ptr, 0xfd, head_large->size); -#endif - FREE(head_large,file,line,func); - } - } else { - /* Release unit */ - struct block *block = head->block; - if( (char*)head - (char*)block > sizeof(struct block) ) { - ShowError("Memory manager: args of aFree 0x%p is invalid pointer %s line %d\n", ptr, file, line); - } else if(head->block == NULL) { - ShowError("Memory manager: args of aFree 0x%p is freed pointer %s:%d@%s\n", ptr, file, line, func); - } else if(*(long*)((char*)head + sizeof(struct unit_head) - sizeof(long) + head->size) != 0xdeadbeaf) { - ShowError("Memory manager: args of aFree 0x%p is overflowed pointer %s line %d\n", ptr, file, line); - } else { - memmgr_usage_bytes -= head->size; - head->block = NULL; -#ifdef DEBUG_MEMMGR - memset(ptr, 0xfd, block->unit_size - sizeof(struct unit_head) + sizeof(long) ); - head->file = file; - head->line = (unsigned short)line; -#endif - memmgr_assert( block->unit_used > 0 ); - if(--block->unit_used == 0) { - /* Release of the block */ - block_free(block); - } else { - if( block->unfill_prev == NULL) { - // add to unfill list - if( hash_unfill[ block->unit_hash ] ) { - hash_unfill[ block->unit_hash ]->unfill_prev = block; - } - block->unfill_prev = &block_head; - block->unfill_next = hash_unfill[ block->unit_hash ]; - hash_unfill[ block->unit_hash ] = block; - } - head->size = block->unit_unfill; - block->unit_unfill = (unsigned short)(((uintptr_t)head - (uintptr_t)block->data) / block->unit_size); - } - } - } -} - -/* Allocating blocks */ -static struct block* block_malloc(unsigned short hash) -{ - struct block *p; - if(hash_unfill[0] != NULL) { - /* Space for the block has already been secured */ - p = hash_unfill[0]; - hash_unfill[0] = hash_unfill[0]->unfill_next; - } else { - int i; - /* Newly allocated space for the block */ - p = (struct block*)MALLOC(sizeof(struct block) * (BLOCK_ALLOC), __FILE__, __LINE__, __func__ ); - memmgr_usage_bytes_t += sizeof(struct block) * (BLOCK_ALLOC); - if(p == NULL) { - ShowFatalError("Memory manager::block_alloc failed.\n"); - exit(EXIT_FAILURE); - } - - if(block_first == NULL) { - /* First ensure */ - block_first = p; - } else { - block_last->block_next = p; - } - block_last = &p[BLOCK_ALLOC - 1]; - block_last->block_next = NULL; - /* Linking the block */ - for(i=0;iunfill_prev = &block_head; - p->unfill_next = NULL; - p->unit_size = (unsigned short)(hash2size( hash ) + sizeof(struct unit_head)); - p->unit_hash = hash; - p->unit_count = BLOCK_DATA_SIZE / p->unit_size; - p->unit_used = 0; - p->unit_unfill = 0xFFFF; - p->unit_maxused = 0; -#ifdef DEBUG_MEMMGR - memset( p->data, 0xfd, sizeof(p->data) ); -#endif - return p; -} - -static void block_free(struct block* p) -{ - if( p->unfill_prev ) { - if( p->unfill_prev == &block_head) { - hash_unfill[ p->unit_hash ] = p->unfill_next; - } else { - p->unfill_prev->unfill_next = p->unfill_next; - } - if( p->unfill_next ) { - p->unfill_next->unfill_prev = p->unfill_prev; - } - p->unfill_prev = NULL; - } - - p->unfill_next = hash_unfill[0]; - hash_unfill[0] = p; -} - -size_t memmgr_usage (void) -{ - return memmgr_usage_bytes / 1024; -} - -#ifdef LOG_MEMMGR -static char memmer_logfile[128]; -static FILE *log_fp; - -static void memmgr_log(char *buf, char *vcsinfo) { - if( !log_fp ) { - time_t raw; - struct tm* t; - - log_fp = fopen(memmer_logfile,"at"); - if (!log_fp) log_fp = stdout; - - time(&raw); - t = localtime(&raw); - fprintf(log_fp, "\nMemory manager: Memory leaks found at %d/%02d/%02d %02dh%02dm%02ds (%s).\n", - (t->tm_year+1900), (t->tm_mon+1), t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, vcsinfo); - } - fprintf(log_fp, "%s", buf); - return; -} -#endif /* LOG_MEMMGR */ - -/// Returns true if the memory location is active. -/// Active means it is allocated and points to a usable part. -/// -/// @param ptr Pointer to the memory -/// @return true if the memory is active -bool memmgr_verify(void* ptr) -{ - struct block* block = block_first; - struct unit_head_large* large = unit_head_large_first; - - if( ptr == NULL ) - return false;// never valid - - // search small blocks - while( block ) - { - if( (char*)ptr >= (char*)block && (char*)ptr < ((char*)block) + sizeof(struct block) ) - {// found memory block - if( block->unit_used && (char*)ptr >= block->data ) - {// memory block is being used and ptr points to a sub-unit - size_t i = (size_t)((char*)ptr - block->data)/block->unit_size; - struct unit_head* head = block2unit(block, i); - if( i < block->unit_maxused && head->block != NULL ) - {// memory unit is allocated, check if ptr points to the usable part - return ( (char*)ptr >= ((char*)head) + sizeof(struct unit_head) - sizeof(long) - && (char*)ptr < ((char*)head) + sizeof(struct unit_head) - sizeof(long) + head->size ); - } - } - return false; - } - block = block->block_next; - } - - // search large blocks - while( large ) - { - if( (char*)ptr >= (char*)large && (char*)ptr < ((char*)large) + large->size ) - {// found memory block, check if ptr points to the usable part - return ( (char*)ptr >= ((char*)large) + sizeof(struct unit_head_large) - sizeof(long) - && (char*)ptr < ((char*)large) + sizeof(struct unit_head_large) - sizeof(long) + large->size ); - } - large = large->next; - } - return false; -} - -static void memmgr_final (void) -{ - struct block *block = block_first; - struct unit_head_large *large = unit_head_large_first; - char vcsinfo[256]; -#ifdef LOG_MEMMGR - int count = 0; -#endif /* LOG_MEMMGR */ - snprintf(vcsinfo, sizeof(vcsinfo), "%s rev '%s'", sysinfo->vcstype(), sysinfo->vcsrevision_src()); // Cache VCS info before we free() it - sysinfo->final(); - - while (block) { - if (block->unit_used) { - int i; - for (i = 0; i < block->unit_maxused; i++) { - struct unit_head *head = block2unit(block, i); - if(head->block != NULL) { - char* ptr = (char *)head + sizeof(struct unit_head) - sizeof(long); -#ifdef LOG_MEMMGR - char buf[1024]; - sprintf (buf, - "%04d : %s line %d size %lu address 0x%p\n", ++count, - head->file, head->line, (unsigned long)head->size, ptr); - memmgr_log(buf, vcsinfo); -#endif /* LOG_MEMMGR */ - // get block pointer and free it [celest] - iMalloc->free(ptr, ALC_MARK); - } - } - } - block = block->block_next; - } - - while(large) { - struct unit_head_large *large2; -#ifdef LOG_MEMMGR - char buf[1024]; - sprintf (buf, - "%04d : %s line %d size %lu address 0x%p\n", ++count, - large->unit_head.file, large->unit_head.line, (unsigned long)large->size, &large->unit_head.checksum); - memmgr_log(buf, vcsinfo); -#endif /* LOG_MEMMGR */ - large2 = large->next; - FREE(large,file,line,func); - large = large2; - } -#ifdef LOG_MEMMGR - if(count == 0) { - ShowInfo("Memory manager: No memory leaks found.\n"); - } else { - ShowWarning("Memory manager: Memory leaks found and fixed.\n"); - fclose(log_fp); - } -#endif /* LOG_MEMMGR */ -} -/* [Ind/Hercules] */ -void memmgr_report (int extra) { - struct block *block = block_first; - struct unit_head_large *large = unit_head_large_first; - unsigned int count = 0, size = 0; - int j; - unsigned short msize = 1024; - struct { - const char *file; - unsigned short line; - size_t size; - unsigned int count; - } data[100]; - memset(&data, 0, sizeof(data)); - - if( extra != 0 ) - msize = extra; - - while (block) { - if (block->unit_used) { - int i; - for (i = 0; i < block->unit_maxused; i++) { - struct unit_head *head = block2unit(block, i); - if( head->block != NULL && head->size > msize ) { - for( j = 0; j < 100; j++ ) { - if( data[j].file == head->file && data[j].line == head->line ) { - data[j].size += head->size; - data[j].count += 1; - break; - } else if( data[j].size == 0 ) { - data[j].file = head->file; - data[j].line = head->line; - data[j].size = head->size; - data[j].count += 1; - break; - } - } - size += (unsigned int)head->size; - count++; - } - } - } - block = block->block_next; - } - - while(large) { - if( large->size > msize ) { - for( j = 0; j < 100; j++ ) { - if( data[j].file == large->unit_head.file && data[j].line == large->unit_head.line ) { - data[j].size += large->size; - data[j].count += 1; - break; - } else if( data[j].size == 0 ) { - data[j].file = large->unit_head.file; - data[j].line = large->unit_head.line; - data[j].size = large->size; - data[j].count += 1; - break; - } - } - size += (unsigned int)large->size; - count++; - } - large = large->next; - } - for( j = 0; j < 100; j++ ) { - if( data[j].size != 0 ) { - ShowMessage("[malloc] : "CL_WHITE"%s"CL_RESET":"CL_WHITE"%d"CL_RESET" %d instances => %.2f MB\n",data[j].file,data[j].line,data[j].count,(double)((data[j].size)/1024)/1024); - } - } - ShowMessage("[malloc] : reporting %u instances | %.2f MB\n",count,(double)((size)/1024)/1024); - ShowMessage("[malloc] : internal usage %.2f MB | %.2f MB\n",(double)((memmgr_usage_bytes_t-memmgr_usage_bytes)/1024)/1024,(double)((memmgr_usage_bytes_t)/1024)/1024); - - if (extra) { - ShowMessage("[malloc] : unit_head_large: %"PRIuS" bytes\n", sizeof(struct unit_head_large)); - ShowMessage("[malloc] : unit_head: %"PRIuS" bytes\n", sizeof(struct unit_head)); - ShowMessage("[malloc] : block: %"PRIuS" bytes\n", sizeof(struct block)); - } - -} - -/** - * Initializes the Memory Manager. - */ -static void memmgr_init(void) -{ -#ifdef LOG_MEMMGR - memset(hash_unfill, 0, sizeof(hash_unfill)); -#endif /* LOG_MEMMGR */ -} - -/** - * Prints initialization messages from the Memory Manager. - */ -static void memmgr_init_messages(void) -{ -#ifdef LOG_MEMMGR - sprintf(memmer_logfile, "log/%s.leaks", SERVER_NAME); - ShowStatus("Memory manager initialized: "CL_WHITE"%s"CL_RESET"\n", memmer_logfile); -#endif /* LOG_MEMMGR */ -} -#endif /* USE_MEMMGR */ - - -/*====================================== -* Initialize -*-------------------------------------- -*/ - - -/// Tests the memory for errors and memory leaks. -void malloc_memory_check(void) -{ - MEMORY_CHECK(); -} - - -/// Returns true if a pointer is valid. -/// The check is best-effort, false positives are possible. -bool malloc_verify_ptr(void* ptr) { -#ifdef USE_MEMMGR - return memmgr_verify(ptr) && MEMORY_VERIFY(ptr); -#else - return MEMORY_VERIFY(ptr); -#endif -} - - -size_t malloc_usage (void) { -#ifdef USE_MEMMGR - return memmgr_usage (); -#else - return MEMORY_USAGE(); -#endif -} - -void malloc_final (void) { -#ifdef USE_MEMMGR - memmgr_final (); -#endif - MEMORY_CHECK(); - if( iMalloc->post_shutdown ) - iMalloc->post_shutdown(); -} - -/** - * Prints initialization status messages. - * - * This is separated from malloc_init() in order to be run after giving the - * chance to other modules to initialize, in case they want to silence any - * status messages, but at the same time require malloc. - */ -void malloc_init_messages(void) -{ -#ifdef USE_MEMMGR - memmgr_init_messages(); -#endif -} - -void malloc_init(void) -{ -#ifdef USE_MEMMGR - memmgr_usage_bytes_t = 0; - memmgr_usage_bytes = 0; -#endif -#if defined(DMALLOC) && defined(CYGWIN) - // http://dmalloc.com/docs/latest/online/dmalloc_19.html - dmalloc_debug_setup(getenv("DMALLOC_OPTIONS")); -#endif -#ifdef GCOLLECT - // don't garbage collect, only report inaccessible memory that was not deallocated - GC_find_leak = 1; - GC_INIT(); -#endif -#ifdef USE_MEMMGR - memmgr_init(); -#endif -} - -void malloc_defaults(void) { - iMalloc = &iMalloc_s; - iMalloc->init = malloc_init; - iMalloc->final = malloc_final; - iMalloc->memory_check = malloc_memory_check; - iMalloc->usage = malloc_usage; - iMalloc->verify_ptr = malloc_verify_ptr; - -// Athena's built-in Memory Manager -#ifdef USE_MEMMGR - iMalloc->malloc = mmalloc_; - iMalloc->calloc = mcalloc_; - iMalloc->realloc = mrealloc_; - iMalloc->reallocz = mreallocz_; - iMalloc->astrdup = mstrdup_; - iMalloc->free = mfree_; -#else - iMalloc->malloc = aMalloc_; - iMalloc->calloc = aCalloc_; - iMalloc->realloc = aRealloc_; - iMalloc->reallocz = aRealloc_;/* not using memory manager huhum o.o perhaps we could still do something about */ - iMalloc->astrdup = aStrdup_; - iMalloc->free = aFree_; -#endif - iMalloc->post_shutdown = NULL; - iMalloc->init_messages = malloc_init_messages; -} diff --git a/src/common/malloc.h b/src/common/malloc.h deleted file mode 100644 index b194c7cf3..000000000 --- a/src/common/malloc.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder - -#ifndef COMMON_MALLOC_H -#define COMMON_MALLOC_H - -#include "common/hercules.h" - -#define ALC_MARK __FILE__, __LINE__, __func__ - - -// default use of the built-in memory manager -#if !defined(NO_MEMMGR) && !defined(USE_MEMMGR) -#if defined(MEMWATCH) || defined(DMALLOC) || defined(GCOLLECT) -// disable built-in memory manager when using another memory library -#define NO_MEMMGR -#else -// use built-in memory manager by default -#define USE_MEMMGR -#endif -#endif - - -////////////////////////////////////////////////////////////////////// -// Enable memory manager logging by default -#define LOG_MEMMGR - -// no logging for minicore -#if defined(MINICORE) && defined(LOG_MEMMGR) - #undef LOG_MEMMGR -#endif - -# define aMalloc(n) (iMalloc->malloc((n),ALC_MARK)) -# define aCalloc(m,n) (iMalloc->calloc((m),(n),ALC_MARK)) -# define aRealloc(p,n) (iMalloc->realloc((p),(n),ALC_MARK)) -# define aReallocz(p,n) (iMalloc->reallocz((p),(n),ALC_MARK)) -# define aStrdup(p) (iMalloc->astrdup((p),ALC_MARK)) -# define aFree(p) (iMalloc->free((p),ALC_MARK)) - -/////////////// Buffer Creation ///////////////// -// Full credit for this goes to Shinomori [Ajarn] - -#ifdef __GNUC__ // GCC has variable length arrays - -#define CREATE_BUFFER(name, type, size) type name[size] -#define DELETE_BUFFER(name) - -#else // others don't, so we emulate them - -#define CREATE_BUFFER(name, type, size) type *name = (type *) aCalloc((size), sizeof(type)) -#define DELETE_BUFFER(name) aFree(name) - -#endif - -////////////// Others ////////////////////////// -// should be merged with any of above later -#define CREATE(result, type, number) ((result) = (type *) aCalloc((number), sizeof(type))) -#define RECREATE(result, type, number) ((result) = (type *) aReallocz((result), sizeof(type) * (number))) - -//////////////////////////////////////////////// - -struct malloc_interface { - void (*init) (void); - void (*final) (void); - /* */ - void* (*malloc)(size_t size, const char *file, int line, const char *func); - void* (*calloc)(size_t num, size_t size, const char *file, int line, const char *func); - void* (*realloc)(void *p, size_t size, const char *file, int line, const char *func); - void* (*reallocz)(void *p, size_t size, const char *file, int line, const char *func); - char* (*astrdup)(const char *p, const char *file, int line, const char *func); - void (*free)(void *p, const char *file, int line, const char *func); - /* */ - void (*memory_check)(void); - bool (*verify_ptr)(void* ptr); - size_t (*usage) (void); - /* */ - void (*post_shutdown) (void); - void (*init_messages) (void); -}; - -#ifdef HERCULES_CORE -void malloc_defaults(void); - -void memmgr_report(int extra); -#endif // HERCULES_CORE - -HPShared struct malloc_interface *iMalloc; - -#endif /* COMMON_MALLOC_H */ diff --git a/src/common/memmgr.c b/src/common/memmgr.c new file mode 100644 index 000000000..18caef95f --- /dev/null +++ b/src/common/memmgr.c @@ -0,0 +1,897 @@ +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams + +#define HERCULES_CORE + +#include "memmgr.h" + +#include "common/cbasetypes.h" +#include "common/core.h" +#include "common/showmsg.h" +#include "common/sysinfo.h" + +#include +#include +#include + +struct malloc_interface iMalloc_s; +struct malloc_interface *iMalloc; + +////////////// Memory Libraries ////////////////// + +#if defined(MEMWATCH) + +# include +# include +# define MALLOC(n,file,line,func) mwMalloc((n),(file),(line)) +# define CALLOC(m,n,file,line,func) mwCalloc((m),(n),(file),(line)) +# define REALLOC(p,n,file,line,func) mwRealloc((p),(n),(file),(line)) +# define STRDUP(p,file,line,func) mwStrdup((p),(file),(line)) +# define FREE(p,file,line,func) mwFree((p),(file),(line)) +# define MEMORY_USAGE() (size_t)0 +# define MEMORY_VERIFY(ptr) mwIsSafeAddr((ptr), 1) +# define MEMORY_CHECK() CHECK() + +#elif defined(DMALLOC) + +# include +# include +# include +# define MALLOC(n,file,line,func) dmalloc_malloc((file),(line),(n),DMALLOC_FUNC_MALLOC,0,0) +# define CALLOC(m,n,file,line,func) dmalloc_malloc((file),(line),(m)*(n),DMALLOC_FUNC_CALLOC,0,0) +# define REALLOC(p,n,file,line,func) dmalloc_realloc((file),(line),(p),(n),DMALLOC_FUNC_REALLOC,0) +# define STRDUP(p,file,line,func) strdup(p) +# define FREE(p,file,line,func) free(p) +# define MEMORY_USAGE() dmalloc_memory_allocated() +# define MEMORY_VERIFY(ptr) (dmalloc_verify(ptr) == DMALLOC_VERIFY_NOERROR) +# define MEMORY_CHECK() do { dmalloc_log_stats(); dmalloc_log_unfreed() } while(0) + +#elif defined(GCOLLECT) + +# include +# ifdef GC_ADD_CALLER +# define RETURN_ADDR 0, +# else +# define RETURN_ADDR +# endif +# define MALLOC(n,file,line,func) GC_debug_malloc((n), RETURN_ADDR (file),(line)) +# define CALLOC(m,n,file,line,func) GC_debug_malloc((m)*(n), RETURN_ADDR (file),(line)) +# define REALLOC(p,n,file,line,func) GC_debug_realloc((p),(n), RETURN_ADDR (file),(line)) +# define STRDUP(p,file,line,func) GC_debug_strdup((p), RETURN_ADDR (file),(line)) +# define FREE(p,file,line,func) GC_debug_free(p) +# define MEMORY_USAGE() GC_get_heap_size() +# define MEMORY_VERIFY(ptr) (GC_base(ptr) != NULL) +# define MEMORY_CHECK() GC_gcollect() + +# undef RETURN_ADDR + +#else + +# define MALLOC(n,file,line,func) malloc(n) +# define CALLOC(m,n,file,line,func) calloc((m),(n)) +# define REALLOC(p,n,file,line,func) realloc((p),(n)) +# define STRDUP(p,file,line,func) strdup(p) +# define FREE(p,file,line,func) free(p) +# define MEMORY_USAGE() (size_t)0 +# define MEMORY_VERIFY(ptr) true +# define MEMORY_CHECK() + +#endif + +void* aMalloc_(size_t size, const char *file, int line, const char *func) +{ + void *ret = MALLOC(size, file, line, func); + // ShowMessage("%s:%d: in func %s: aMalloc %d\n",file,line,func,size); + if (ret == NULL){ + ShowFatalError("%s:%d: in func %s: aMalloc error out of memory!\n",file,line,func); + exit(EXIT_FAILURE); + } + + return ret; +} +void* aCalloc_(size_t num, size_t size, const char *file, int line, const char *func) +{ + void *ret = CALLOC(num, size, file, line, func); + // ShowMessage("%s:%d: in func %s: aCalloc %d %d\n",file,line,func,num,size); + if (ret == NULL){ + ShowFatalError("%s:%d: in func %s: aCalloc error out of memory!\n", file, line, func); + exit(EXIT_FAILURE); + } + return ret; +} +void* aRealloc_(void *p, size_t size, const char *file, int line, const char *func) +{ + void *ret = REALLOC(p, size, file, line, func); + // ShowMessage("%s:%d: in func %s: aRealloc %p %d\n",file,line,func,p,size); + if (ret == NULL){ + ShowFatalError("%s:%d: in func %s: aRealloc error out of memory!\n",file,line,func); + exit(EXIT_FAILURE); + } + return ret; +} +char* aStrdup_(const char *p, const char *file, int line, const char *func) +{ + char *ret = STRDUP(p, file, line, func); + // ShowMessage("%s:%d: in func %s: aStrdup %p\n",file,line,func,p); + if (ret == NULL){ + ShowFatalError("%s:%d: in func %s: aStrdup error out of memory!\n", file, line, func); + exit(EXIT_FAILURE); + } + return ret; +} +void aFree_(void *p, const char *file, int line, const char *func) +{ + // ShowMessage("%s:%d: in func %s: aFree %p\n",file,line,func,p); + if (p) + FREE(p, file, line, func); + //p = NULL; +} + + +#ifdef USE_MEMMGR + +#if defined(DEBUG) +#define DEBUG_MEMMGR +#endif + +/* USE_MEMMGR */ + +/* +* Memory manager +* able to handle malloc and free efficiently +* Since the complex processing, I might be slightly heavier. +* +* (I'm sorry for the poor description ^ ^;) such as data structures +* Divided into "blocks" of a plurality of memory, "unit" of a plurality of blocks further +* I have to divide. Size of the unit, a plurality of distribution equal to the capacity of one block +* That's what you have. For example, if one unit of 32KB, one block 1 Yu 32Byte +* Knit, or are able to gather 1024, gathered 512 units 64Byte +* I can be or have. (Excluding padding, the unit_head) +* +* Lead-linked list (block_prev, block_next) in each other is the same size block +* Linked list (hash_prev, hash_nect) even among such one in the block with the figure +* I like to have. Thus, reuse of memory no longer needed can be performed efficiently. +*/ + +/* Alignment of the block */ +#define BLOCK_ALIGNMENT1 16 +#define BLOCK_ALIGNMENT2 64 + +/* Amount of data entering a block */ +#define BLOCK_DATA_COUNT1 128 +#define BLOCK_DATA_COUNT2 608 + +/* The size of the block: 16*128 + 64*576 = 40KB */ +#define BLOCK_DATA_SIZE1 ( BLOCK_ALIGNMENT1 * BLOCK_DATA_COUNT1 ) +#define BLOCK_DATA_SIZE2 ( BLOCK_ALIGNMENT2 * BLOCK_DATA_COUNT2 ) +#define BLOCK_DATA_SIZE ( BLOCK_DATA_SIZE1 + BLOCK_DATA_SIZE2 ) + +/* The number of blocks to be allocated at a time. */ +#define BLOCK_ALLOC 104 + +/* block */ +struct block { + struct block *block_next; ///< Then the allocated area + struct block *unfill_prev; ///< The previous area not filled + struct block *unfill_next; ///< The next area not filled + unsigned short unit_size; ///< The size of the unit + unsigned short unit_hash; ///< The hash of the unit + unsigned short unit_count; ///< The number of units + unsigned short unit_used; ///< The number of used units + unsigned short unit_unfill; ///< The number of unused units + unsigned short unit_maxused; ///< The maximum value of units used + char data[BLOCK_DATA_SIZE]; +}; + +struct unit_head { + struct block *block; + const char* file; + unsigned short line; + unsigned short size; + long checksum; +}; + +static struct block* hash_unfill[BLOCK_DATA_COUNT1 + BLOCK_DATA_COUNT2 + 1]; +static struct block* block_first, *block_last, block_head; + +/* Data for areas that do not use the memory be turned */ +struct unit_head_large { + size_t size; + struct unit_head_large* prev; + struct unit_head_large* next; + struct unit_head unit_head; +}; + +static struct unit_head_large *unit_head_large_first = NULL; + +static struct block* block_malloc(unsigned short hash); +static void block_free(struct block* p); +static size_t memmgr_usage_bytes; +static size_t memmgr_usage_bytes_t; + + +#define block2unit(p, n) ((struct unit_head*)(&(p)->data[ p->unit_size * (n) ])) +#define memmgr_assert(v) do { if(!(v)) { ShowError("Memory manager: assertion '" #v "' failed!\n"); } } while(0) + +static unsigned short size2hash( size_t size ) +{ + if( size <= BLOCK_DATA_SIZE1 ) { + return (unsigned short)(size + BLOCK_ALIGNMENT1 - 1) / BLOCK_ALIGNMENT1; + } else if( size <= BLOCK_DATA_SIZE ){ + return (unsigned short)(size - BLOCK_DATA_SIZE1 + BLOCK_ALIGNMENT2 - 1) / BLOCK_ALIGNMENT2 + + BLOCK_DATA_COUNT1; + } else { + return 0xffff; // If it exceeds the block length hash I do not + } +} + +static size_t hash2size( unsigned short hash ) +{ + if( hash <= BLOCK_DATA_COUNT1) { + return hash * BLOCK_ALIGNMENT1; + } else { + return (hash - BLOCK_DATA_COUNT1) * BLOCK_ALIGNMENT2 + BLOCK_DATA_SIZE1; + } +} + +void *mmalloc_(size_t size, const char *file, int line, const char *func) { + struct block *block; + short size_hash = size2hash( size ); + struct unit_head *head; + + if (((long) size) < 0) { + ShowError("mmalloc_: %"PRIdS"\n", size); + return NULL; + } + + if(size == 0) { + return NULL; + } + memmgr_usage_bytes += size; + + /* To ensure the area that exceeds the length of the block, using malloc () to */ + /* At that time, the distinction by assigning NULL to unit_head.block */ + if(hash2size(size_hash) > BLOCK_DATA_SIZE - sizeof(struct unit_head)) { + struct unit_head_large* p = (struct unit_head_large*)MALLOC(sizeof(struct unit_head_large)+size,file,line,func); + memmgr_usage_bytes_t += size+sizeof(struct unit_head_large); + if(p != NULL) { + p->size = size; + p->unit_head.block = NULL; + p->unit_head.size = 0; + p->unit_head.file = file; + p->unit_head.line = (unsigned short)line; + p->prev = NULL; + if (unit_head_large_first == NULL) + p->next = NULL; + else { + unit_head_large_first->prev = p; + p->next = unit_head_large_first; + } + unit_head_large_first = p; + *(long*)((char*)p + sizeof(struct unit_head_large) - sizeof(long) + size) = 0xdeadbeaf; + return (char *)p + sizeof(struct unit_head_large) - sizeof(long); + } else { + ShowFatalError("Memory manager::memmgr_alloc failed (allocating %"PRIuS"+%"PRIuS" bytes at %s:%d).\n", + sizeof(struct unit_head_large), size, file, line); + exit(EXIT_FAILURE); + } + } + + /* When a block of the same size is not ensured, to ensure a new */ + if(hash_unfill[size_hash]) { + block = hash_unfill[size_hash]; + } else { + block = block_malloc(size_hash); + } + + if( block->unit_unfill == 0xFFFF ) { + // there are no more free space that + memmgr_assert(block->unit_used < block->unit_count); + memmgr_assert(block->unit_used == block->unit_maxused); + head = block2unit(block, block->unit_maxused); + block->unit_used++; + block->unit_maxused++; + } else { + head = block2unit(block, block->unit_unfill); + block->unit_unfill = head->size; + block->unit_used++; + } + + if( block->unit_unfill == 0xFFFF && block->unit_maxused >= block->unit_count) { + // Since I ran out of the unit, removed from the list unfill + if( block->unfill_prev == &block_head) { + hash_unfill[ size_hash ] = block->unfill_next; + } else { + block->unfill_prev->unfill_next = block->unfill_next; + } + if( block->unfill_next ) { + block->unfill_next->unfill_prev = block->unfill_prev; + } + block->unfill_prev = NULL; + } + +#ifdef DEBUG_MEMMGR + { + size_t i, sz = hash2size( size_hash ); + for( i=0; iline != 0xfdfd ) + { + ShowError("Memory manager: freed-data is changed. (freed in %s line %d)\n", head->file,head->line); + } + else + { + ShowError("Memory manager: not-allocated-data is changed.\n"); + } + break; + } + } + memset( (char *)head + sizeof(struct unit_head) - sizeof(long), 0xcd, sz ); + } +#endif + + head->block = block; + head->file = file; + head->line = (unsigned short)line; + head->size = (unsigned short)size; + *(long*)((char*)head + sizeof(struct unit_head) - sizeof(long) + size) = 0xdeadbeaf; + return (char *)head + sizeof(struct unit_head) - sizeof(long); +} + +void *mcalloc_(size_t num, size_t size, const char *file, int line, const char *func) { + void *p = iMalloc->malloc(num * size,file,line,func); + if (p) + memset(p, 0, num * size); + return p; +} + +void *mrealloc_(void *memblock, size_t size, const char *file, int line, const char *func) { + size_t old_size; + if(memblock == NULL) { + return iMalloc->malloc(size,file,line,func); + } + + old_size = ((struct unit_head *)((char *)memblock - sizeof(struct unit_head) + sizeof(long)))->size; + if( old_size == 0 ) { + old_size = ((struct unit_head_large *)((char *)memblock - sizeof(struct unit_head_large) + sizeof(long)))->size; + } + if(old_size > size) { + // Size reduction - return> as it is (negligence) + return memblock; + } else { + // Size Large + void *p = iMalloc->malloc(size,file,line,func); + if(p != NULL) { + memcpy(p,memblock,old_size); + } + iMalloc->free(memblock,file,line,func); + return p; + } +} + +/* a mrealloc_ clone with the difference it 'z'eroes the newly created memory */ +void *mreallocz_(void *memblock, size_t size, const char *file, int line, const char *func) { + size_t old_size; + void *p = NULL; + + if(memblock == NULL) { + p = iMalloc->malloc(size,file,line,func); + memset(p,0,size); + return p; + } + + old_size = ((struct unit_head *)((char *)memblock - sizeof(struct unit_head) + sizeof(long)))->size; + if( old_size == 0 ) { + old_size = ((struct unit_head_large *)((char *)memblock - sizeof(struct unit_head_large) + sizeof(long)))->size; + } + if(old_size > size) { + // Size reduction - return> as it is (negligence) + return memblock; + } else { + // Size Large + p = iMalloc->malloc(size,file,line,func); + if(p != NULL) { + memcpy(p,memblock,old_size); + memset((char*)p+old_size,0,size-old_size); + } + iMalloc->free(memblock,file,line,func); + return p; + } +} + + +char *mstrdup_(const char *p, const char *file, int line, const char *func) { + if(p == NULL) { + return NULL; + } else { + size_t len = strlen(p); + char *string = (char *)iMalloc->malloc(len + 1,file,line,func); + memcpy(string,p,len+1); + return string; + } +} + +void mfree_(void *ptr, const char *file, int line, const char *func) { + struct unit_head *head; + + if (ptr == NULL) + return; + + head = (struct unit_head *)((char *)ptr - sizeof(struct unit_head) + sizeof(long)); + if(head->size == 0) { + /* area that is directly secured by malloc () */ + struct unit_head_large *head_large = (struct unit_head_large *)((char *)ptr - sizeof(struct unit_head_large) + sizeof(long)); + if( + *(long*)((char*)head_large + sizeof(struct unit_head_large) - sizeof(long) + head_large->size) + != 0xdeadbeaf) + { + ShowError("Memory manager: args of aFree 0x%p is overflowed pointer %s line %d\n", ptr, file, line); + } else { + head->size = 0xFFFF; + if(head_large->prev) { + head_large->prev->next = head_large->next; + } else { + unit_head_large_first = head_large->next; + } + if(head_large->next) { + head_large->next->prev = head_large->prev; + } + memmgr_usage_bytes -= head_large->size; + memmgr_usage_bytes_t -= head_large->size + sizeof(struct unit_head_large); +#ifdef DEBUG_MEMMGR + // set freed memory to 0xfd + memset(ptr, 0xfd, head_large->size); +#endif + FREE(head_large,file,line,func); + } + } else { + /* Release unit */ + struct block *block = head->block; + if( (char*)head - (char*)block > sizeof(struct block) ) { + ShowError("Memory manager: args of aFree 0x%p is invalid pointer %s line %d\n", ptr, file, line); + } else if(head->block == NULL) { + ShowError("Memory manager: args of aFree 0x%p is freed pointer %s:%d@%s\n", ptr, file, line, func); + } else if(*(long*)((char*)head + sizeof(struct unit_head) - sizeof(long) + head->size) != 0xdeadbeaf) { + ShowError("Memory manager: args of aFree 0x%p is overflowed pointer %s line %d\n", ptr, file, line); + } else { + memmgr_usage_bytes -= head->size; + head->block = NULL; +#ifdef DEBUG_MEMMGR + memset(ptr, 0xfd, block->unit_size - sizeof(struct unit_head) + sizeof(long) ); + head->file = file; + head->line = (unsigned short)line; +#endif + memmgr_assert( block->unit_used > 0 ); + if(--block->unit_used == 0) { + /* Release of the block */ + block_free(block); + } else { + if( block->unfill_prev == NULL) { + // add to unfill list + if( hash_unfill[ block->unit_hash ] ) { + hash_unfill[ block->unit_hash ]->unfill_prev = block; + } + block->unfill_prev = &block_head; + block->unfill_next = hash_unfill[ block->unit_hash ]; + hash_unfill[ block->unit_hash ] = block; + } + head->size = block->unit_unfill; + block->unit_unfill = (unsigned short)(((uintptr_t)head - (uintptr_t)block->data) / block->unit_size); + } + } + } +} + +/* Allocating blocks */ +static struct block* block_malloc(unsigned short hash) +{ + struct block *p; + if(hash_unfill[0] != NULL) { + /* Space for the block has already been secured */ + p = hash_unfill[0]; + hash_unfill[0] = hash_unfill[0]->unfill_next; + } else { + int i; + /* Newly allocated space for the block */ + p = (struct block*)MALLOC(sizeof(struct block) * (BLOCK_ALLOC), __FILE__, __LINE__, __func__ ); + memmgr_usage_bytes_t += sizeof(struct block) * (BLOCK_ALLOC); + if(p == NULL) { + ShowFatalError("Memory manager::block_alloc failed.\n"); + exit(EXIT_FAILURE); + } + + if(block_first == NULL) { + /* First ensure */ + block_first = p; + } else { + block_last->block_next = p; + } + block_last = &p[BLOCK_ALLOC - 1]; + block_last->block_next = NULL; + /* Linking the block */ + for(i=0;iunfill_prev = &block_head; + p->unfill_next = NULL; + p->unit_size = (unsigned short)(hash2size( hash ) + sizeof(struct unit_head)); + p->unit_hash = hash; + p->unit_count = BLOCK_DATA_SIZE / p->unit_size; + p->unit_used = 0; + p->unit_unfill = 0xFFFF; + p->unit_maxused = 0; +#ifdef DEBUG_MEMMGR + memset( p->data, 0xfd, sizeof(p->data) ); +#endif + return p; +} + +static void block_free(struct block* p) +{ + if( p->unfill_prev ) { + if( p->unfill_prev == &block_head) { + hash_unfill[ p->unit_hash ] = p->unfill_next; + } else { + p->unfill_prev->unfill_next = p->unfill_next; + } + if( p->unfill_next ) { + p->unfill_next->unfill_prev = p->unfill_prev; + } + p->unfill_prev = NULL; + } + + p->unfill_next = hash_unfill[0]; + hash_unfill[0] = p; +} + +size_t memmgr_usage (void) +{ + return memmgr_usage_bytes / 1024; +} + +#ifdef LOG_MEMMGR +static char memmer_logfile[128]; +static FILE *log_fp; + +static void memmgr_log(char *buf, char *vcsinfo) { + if( !log_fp ) { + time_t raw; + struct tm* t; + + log_fp = fopen(memmer_logfile,"at"); + if (!log_fp) log_fp = stdout; + + time(&raw); + t = localtime(&raw); + fprintf(log_fp, "\nMemory manager: Memory leaks found at %d/%02d/%02d %02dh%02dm%02ds (%s).\n", + (t->tm_year+1900), (t->tm_mon+1), t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, vcsinfo); + } + fprintf(log_fp, "%s", buf); + return; +} +#endif /* LOG_MEMMGR */ + +/// Returns true if the memory location is active. +/// Active means it is allocated and points to a usable part. +/// +/// @param ptr Pointer to the memory +/// @return true if the memory is active +bool memmgr_verify(void* ptr) +{ + struct block* block = block_first; + struct unit_head_large* large = unit_head_large_first; + + if( ptr == NULL ) + return false;// never valid + + // search small blocks + while( block ) + { + if( (char*)ptr >= (char*)block && (char*)ptr < ((char*)block) + sizeof(struct block) ) + {// found memory block + if( block->unit_used && (char*)ptr >= block->data ) + {// memory block is being used and ptr points to a sub-unit + size_t i = (size_t)((char*)ptr - block->data)/block->unit_size; + struct unit_head* head = block2unit(block, i); + if( i < block->unit_maxused && head->block != NULL ) + {// memory unit is allocated, check if ptr points to the usable part + return ( (char*)ptr >= ((char*)head) + sizeof(struct unit_head) - sizeof(long) + && (char*)ptr < ((char*)head) + sizeof(struct unit_head) - sizeof(long) + head->size ); + } + } + return false; + } + block = block->block_next; + } + + // search large blocks + while( large ) + { + if( (char*)ptr >= (char*)large && (char*)ptr < ((char*)large) + large->size ) + {// found memory block, check if ptr points to the usable part + return ( (char*)ptr >= ((char*)large) + sizeof(struct unit_head_large) - sizeof(long) + && (char*)ptr < ((char*)large) + sizeof(struct unit_head_large) - sizeof(long) + large->size ); + } + large = large->next; + } + return false; +} + +static void memmgr_final (void) +{ + struct block *block = block_first; + struct unit_head_large *large = unit_head_large_first; + char vcsinfo[256]; +#ifdef LOG_MEMMGR + int count = 0; +#endif /* LOG_MEMMGR */ + snprintf(vcsinfo, sizeof(vcsinfo), "%s rev '%s'", sysinfo->vcstype(), sysinfo->vcsrevision_src()); // Cache VCS info before we free() it + sysinfo->final(); + + while (block) { + if (block->unit_used) { + int i; + for (i = 0; i < block->unit_maxused; i++) { + struct unit_head *head = block2unit(block, i); + if(head->block != NULL) { + char* ptr = (char *)head + sizeof(struct unit_head) - sizeof(long); +#ifdef LOG_MEMMGR + char buf[1024]; + sprintf (buf, + "%04d : %s line %d size %lu address 0x%p\n", ++count, + head->file, head->line, (unsigned long)head->size, ptr); + memmgr_log(buf, vcsinfo); +#endif /* LOG_MEMMGR */ + // get block pointer and free it [celest] + iMalloc->free(ptr, ALC_MARK); + } + } + } + block = block->block_next; + } + + while(large) { + struct unit_head_large *large2; +#ifdef LOG_MEMMGR + char buf[1024]; + sprintf (buf, + "%04d : %s line %d size %lu address 0x%p\n", ++count, + large->unit_head.file, large->unit_head.line, (unsigned long)large->size, &large->unit_head.checksum); + memmgr_log(buf, vcsinfo); +#endif /* LOG_MEMMGR */ + large2 = large->next; + FREE(large,file,line,func); + large = large2; + } +#ifdef LOG_MEMMGR + if(count == 0) { + ShowInfo("Memory manager: No memory leaks found.\n"); + } else { + ShowWarning("Memory manager: Memory leaks found and fixed.\n"); + fclose(log_fp); + } +#endif /* LOG_MEMMGR */ +} +/* [Ind/Hercules] */ +void memmgr_report (int extra) { + struct block *block = block_first; + struct unit_head_large *large = unit_head_large_first; + unsigned int count = 0, size = 0; + int j; + unsigned short msize = 1024; + struct { + const char *file; + unsigned short line; + size_t size; + unsigned int count; + } data[100]; + memset(&data, 0, sizeof(data)); + + if( extra != 0 ) + msize = extra; + + while (block) { + if (block->unit_used) { + int i; + for (i = 0; i < block->unit_maxused; i++) { + struct unit_head *head = block2unit(block, i); + if( head->block != NULL && head->size > msize ) { + for( j = 0; j < 100; j++ ) { + if( data[j].file == head->file && data[j].line == head->line ) { + data[j].size += head->size; + data[j].count += 1; + break; + } else if( data[j].size == 0 ) { + data[j].file = head->file; + data[j].line = head->line; + data[j].size = head->size; + data[j].count += 1; + break; + } + } + size += (unsigned int)head->size; + count++; + } + } + } + block = block->block_next; + } + + while(large) { + if( large->size > msize ) { + for( j = 0; j < 100; j++ ) { + if( data[j].file == large->unit_head.file && data[j].line == large->unit_head.line ) { + data[j].size += large->size; + data[j].count += 1; + break; + } else if( data[j].size == 0 ) { + data[j].file = large->unit_head.file; + data[j].line = large->unit_head.line; + data[j].size = large->size; + data[j].count += 1; + break; + } + } + size += (unsigned int)large->size; + count++; + } + large = large->next; + } + for( j = 0; j < 100; j++ ) { + if( data[j].size != 0 ) { + ShowMessage("[malloc] : "CL_WHITE"%s"CL_RESET":"CL_WHITE"%d"CL_RESET" %d instances => %.2f MB\n",data[j].file,data[j].line,data[j].count,(double)((data[j].size)/1024)/1024); + } + } + ShowMessage("[malloc] : reporting %u instances | %.2f MB\n",count,(double)((size)/1024)/1024); + ShowMessage("[malloc] : internal usage %.2f MB | %.2f MB\n",(double)((memmgr_usage_bytes_t-memmgr_usage_bytes)/1024)/1024,(double)((memmgr_usage_bytes_t)/1024)/1024); + + if (extra) { + ShowMessage("[malloc] : unit_head_large: %"PRIuS" bytes\n", sizeof(struct unit_head_large)); + ShowMessage("[malloc] : unit_head: %"PRIuS" bytes\n", sizeof(struct unit_head)); + ShowMessage("[malloc] : block: %"PRIuS" bytes\n", sizeof(struct block)); + } + +} + +/** + * Initializes the Memory Manager. + */ +static void memmgr_init(void) +{ +#ifdef LOG_MEMMGR + memset(hash_unfill, 0, sizeof(hash_unfill)); +#endif /* LOG_MEMMGR */ +} + +/** + * Prints initialization messages from the Memory Manager. + */ +static void memmgr_init_messages(void) +{ +#ifdef LOG_MEMMGR + sprintf(memmer_logfile, "log/%s.leaks", SERVER_NAME); + ShowStatus("Memory manager initialized: "CL_WHITE"%s"CL_RESET"\n", memmer_logfile); +#endif /* LOG_MEMMGR */ +} +#endif /* USE_MEMMGR */ + + +/*====================================== +* Initialize +*-------------------------------------- +*/ + + +/// Tests the memory for errors and memory leaks. +void malloc_memory_check(void) +{ + MEMORY_CHECK(); +} + + +/// Returns true if a pointer is valid. +/// The check is best-effort, false positives are possible. +bool malloc_verify_ptr(void* ptr) { +#ifdef USE_MEMMGR + return memmgr_verify(ptr) && MEMORY_VERIFY(ptr); +#else + return MEMORY_VERIFY(ptr); +#endif +} + + +size_t malloc_usage (void) { +#ifdef USE_MEMMGR + return memmgr_usage (); +#else + return MEMORY_USAGE(); +#endif +} + +void malloc_final (void) { +#ifdef USE_MEMMGR + memmgr_final (); +#endif + MEMORY_CHECK(); + if( iMalloc->post_shutdown ) + iMalloc->post_shutdown(); +} + +/** + * Prints initialization status messages. + * + * This is separated from malloc_init() in order to be run after giving the + * chance to other modules to initialize, in case they want to silence any + * status messages, but at the same time require malloc. + */ +void malloc_init_messages(void) +{ +#ifdef USE_MEMMGR + memmgr_init_messages(); +#endif +} + +void malloc_init(void) +{ +#ifdef USE_MEMMGR + memmgr_usage_bytes_t = 0; + memmgr_usage_bytes = 0; +#endif +#if defined(DMALLOC) && defined(CYGWIN) + // http://dmalloc.com/docs/latest/online/dmalloc_19.html + dmalloc_debug_setup(getenv("DMALLOC_OPTIONS")); +#endif +#ifdef GCOLLECT + // don't garbage collect, only report inaccessible memory that was not deallocated + GC_find_leak = 1; + GC_INIT(); +#endif +#ifdef USE_MEMMGR + memmgr_init(); +#endif +} + +void malloc_defaults(void) { + iMalloc = &iMalloc_s; + iMalloc->init = malloc_init; + iMalloc->final = malloc_final; + iMalloc->memory_check = malloc_memory_check; + iMalloc->usage = malloc_usage; + iMalloc->verify_ptr = malloc_verify_ptr; + +// Athena's built-in Memory Manager +#ifdef USE_MEMMGR + iMalloc->malloc = mmalloc_; + iMalloc->calloc = mcalloc_; + iMalloc->realloc = mrealloc_; + iMalloc->reallocz = mreallocz_; + iMalloc->astrdup = mstrdup_; + iMalloc->free = mfree_; +#else + iMalloc->malloc = aMalloc_; + iMalloc->calloc = aCalloc_; + iMalloc->realloc = aRealloc_; + iMalloc->reallocz = aRealloc_;/* not using memory manager huhum o.o perhaps we could still do something about */ + iMalloc->astrdup = aStrdup_; + iMalloc->free = aFree_; +#endif + iMalloc->post_shutdown = NULL; + iMalloc->init_messages = malloc_init_messages; +} diff --git a/src/common/memmgr.h b/src/common/memmgr.h new file mode 100644 index 000000000..b194c7cf3 --- /dev/null +++ b/src/common/memmgr.h @@ -0,0 +1,89 @@ +// Copyright (c) Athena Dev Teams - Licensed under GNU GPL +// For more information, see LICENCE in the main folder + +#ifndef COMMON_MALLOC_H +#define COMMON_MALLOC_H + +#include "common/hercules.h" + +#define ALC_MARK __FILE__, __LINE__, __func__ + + +// default use of the built-in memory manager +#if !defined(NO_MEMMGR) && !defined(USE_MEMMGR) +#if defined(MEMWATCH) || defined(DMALLOC) || defined(GCOLLECT) +// disable built-in memory manager when using another memory library +#define NO_MEMMGR +#else +// use built-in memory manager by default +#define USE_MEMMGR +#endif +#endif + + +////////////////////////////////////////////////////////////////////// +// Enable memory manager logging by default +#define LOG_MEMMGR + +// no logging for minicore +#if defined(MINICORE) && defined(LOG_MEMMGR) + #undef LOG_MEMMGR +#endif + +# define aMalloc(n) (iMalloc->malloc((n),ALC_MARK)) +# define aCalloc(m,n) (iMalloc->calloc((m),(n),ALC_MARK)) +# define aRealloc(p,n) (iMalloc->realloc((p),(n),ALC_MARK)) +# define aReallocz(p,n) (iMalloc->reallocz((p),(n),ALC_MARK)) +# define aStrdup(p) (iMalloc->astrdup((p),ALC_MARK)) +# define aFree(p) (iMalloc->free((p),ALC_MARK)) + +/////////////// Buffer Creation ///////////////// +// Full credit for this goes to Shinomori [Ajarn] + +#ifdef __GNUC__ // GCC has variable length arrays + +#define CREATE_BUFFER(name, type, size) type name[size] +#define DELETE_BUFFER(name) + +#else // others don't, so we emulate them + +#define CREATE_BUFFER(name, type, size) type *name = (type *) aCalloc((size), sizeof(type)) +#define DELETE_BUFFER(name) aFree(name) + +#endif + +////////////// Others ////////////////////////// +// should be merged with any of above later +#define CREATE(result, type, number) ((result) = (type *) aCalloc((number), sizeof(type))) +#define RECREATE(result, type, number) ((result) = (type *) aReallocz((result), sizeof(type) * (number))) + +//////////////////////////////////////////////// + +struct malloc_interface { + void (*init) (void); + void (*final) (void); + /* */ + void* (*malloc)(size_t size, const char *file, int line, const char *func); + void* (*calloc)(size_t num, size_t size, const char *file, int line, const char *func); + void* (*realloc)(void *p, size_t size, const char *file, int line, const char *func); + void* (*reallocz)(void *p, size_t size, const char *file, int line, const char *func); + char* (*astrdup)(const char *p, const char *file, int line, const char *func); + void (*free)(void *p, const char *file, int line, const char *func); + /* */ + void (*memory_check)(void); + bool (*verify_ptr)(void* ptr); + size_t (*usage) (void); + /* */ + void (*post_shutdown) (void); + void (*init_messages) (void); +}; + +#ifdef HERCULES_CORE +void malloc_defaults(void); + +void memmgr_report(int extra); +#endif // HERCULES_CORE + +HPShared struct malloc_interface *iMalloc; + +#endif /* COMMON_MALLOC_H */ diff --git a/src/common/mutex.c b/src/common/mutex.c index 715609628..af1a6d155 100644 --- a/src/common/mutex.c +++ b/src/common/mutex.c @@ -6,7 +6,7 @@ #include "mutex.h" #include "common/cbasetypes.h" // for WIN32 -#include "common/malloc.h" +#include "common/memmgr.h" #include "common/showmsg.h" #include "common/timer.h" diff --git a/src/common/socket.c b/src/common/socket.c index b4b67da40..b418a468f 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -10,7 +10,7 @@ #include "common/HPM.h" #include "common/cbasetypes.h" #include "common/db.h" -#include "common/malloc.h" +#include "common/memmgr.h" #include "common/mmo.h" #include "common/nullpo.h" #include "common/showmsg.h" diff --git a/src/common/sql.c b/src/common/sql.c index ee759eb61..4262a10a1 100644 --- a/src/common/sql.c +++ b/src/common/sql.c @@ -7,7 +7,7 @@ #include "sql.h" #include "common/cbasetypes.h" -#include "common/malloc.h" +#include "common/memmgr.h" #include "common/showmsg.h" #include "common/strlib.h" #include "common/timer.h" diff --git a/src/common/strlib.c b/src/common/strlib.c index fcd1b483b..fefabe52b 100644 --- a/src/common/strlib.c +++ b/src/common/strlib.c @@ -7,7 +7,7 @@ #include "strlib.h" #include "common/cbasetypes.h" -#include "common/malloc.h" +#include "common/memmgr.h" #include "common/showmsg.h" #include diff --git a/src/common/sysinfo.c b/src/common/sysinfo.c index d218e6e99..1baf33086 100644 --- a/src/common/sysinfo.c +++ b/src/common/sysinfo.c @@ -10,7 +10,7 @@ #include "common/cbasetypes.h" #include "common/core.h" -#include "common/malloc.h" +#include "common/memmgr.h" #include "common/strlib.h" #include // fopen diff --git a/src/common/thread.c b/src/common/thread.c index d5bbd7f97..d9cd42aa6 100644 --- a/src/common/thread.c +++ b/src/common/thread.c @@ -11,7 +11,7 @@ #include "thread.h" #include "common/cbasetypes.h" -#include "common/malloc.h" +#include "common/memmgr.h" #include "common/showmsg.h" #include "common/sysinfo.h" // sysinfo->getpagesize() diff --git a/src/common/timer.c b/src/common/timer.c index f6ce00d54..f31ae0ffe 100644 --- a/src/common/timer.c +++ b/src/common/timer.c @@ -8,7 +8,7 @@ #include "common/cbasetypes.h" #include "common/db.h" -#include "common/malloc.h" +#include "common/memmgr.h" #include "common/showmsg.h" #include "common/utils.h" -- cgit v1.2.3-60-g2f50