diff options
author | shennetsind <notind@gmail.com> | 2013-05-17 11:08:38 -0700 |
---|---|---|
committer | shennetsind <notind@gmail.com> | 2013-05-17 11:08:38 -0700 |
commit | 080f7a22740225df70a488849587b462a5d6b1a3 (patch) | |
tree | 0c1dc751af9f06e1ce3729d271de301f78a4e611 /src/common/malloc.c | |
parent | 754af15505f32237f8063e51ae9a1cb90788dff4 (diff) | |
parent | 25e848f1a0f9317d63106cae048a1ef838411cb2 (diff) | |
download | hercules-080f7a22740225df70a488849587b462a5d6b1a3.tar.gz hercules-080f7a22740225df70a488849587b462a5d6b1a3.tar.bz2 hercules-080f7a22740225df70a488849587b462a5d6b1a3.tar.xz hercules-080f7a22740225df70a488849587b462a5d6b1a3.zip |
Merge pull request #1 from Earisu/master
updating, with earisu's
Diffstat (limited to 'src/common/malloc.c')
-rw-r--r-- | src/common/malloc.c | 162 |
1 files changed, 95 insertions, 67 deletions
diff --git a/src/common/malloc.c b/src/common/malloc.c index 9976a28d5..77eef2508 100644 --- a/src/common/malloc.c +++ b/src/common/malloc.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #include "../common/malloc.h" #include "../common/core.h" @@ -129,49 +130,49 @@ void aFree_(void *p, const char *file, int line, const char *func) /* USE_MEMMGR */ /* - * メモリマネージャ - * malloc , free の処理を効率的に出来るようにしたもの。 - * 複雑な処理を行っているので、若干重くなるかもしれません。 - * - * データ構造など(説明下手ですいません^^; ) - * ・メモリを複数の「ブロック」に分けて、さらにブロックを複数の「ユニット」 - * に分けています。ユニットのサイズは、1ブロックの容量を複数個に均等配分 - * したものです。たとえば、1ユニット32KBの場合、ブロック1つは32Byteのユ - * ニットが、1024個集まって出来ていたり、64Byteのユニットが 512個集まって - * 出来ていたりします。(padding,unit_head を除く) - * - * ・ブロック同士はリンクリスト(block_prev,block_next) でつながり、同じサイ - * ズを持つブロック同士もリンクリスト(hash_prev,hash_nect) でつな - * がっています。それにより、不要となったメモリの再利用が効率的に行えます。 - */ - -/* ブロックのアライメント */ +* 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 -/* ブロックの大きさ: 16*128 + 64*576 = 40KB */ +/* 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; /* 次に確保した領域 */ - struct block* unfill_prev; /* 次の埋まっていない領域 */ - struct block* unfill_next; /* 次の埋まっていない領域 */ - unsigned short unit_size; /* ユニットの大きさ */ - unsigned short unit_hash; /* ユニットのハッシュ */ - unsigned short unit_count; /* ユニットの個数 */ - unsigned short unit_used; /* 使用ユニット数 */ - unsigned short unit_unfill; /* 未使用ユニットの場所 */ - unsigned short unit_maxused; /* 使用ユニットの最大値 */ + 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 ]; }; @@ -186,7 +187,7 @@ struct unit_head { 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; @@ -209,9 +210,9 @@ static unsigned short size2hash( size_t size ) 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; + + BLOCK_DATA_COUNT1; } else { - return 0xffff; // ブロック長を超える場合は hash にしない + return 0xffff; // If it exceeds the block length hash I do not } } @@ -234,14 +235,14 @@ void* _mmalloc(size_t size, const char *file, int line, const char *func ) ShowError("_mmalloc: %d\n", size); return NULL; } - + if(size == 0) { return NULL; } memmgr_usage_bytes += size; - /* ブロック長を超える領域の確保には、malloc() を用いる */ - /* その際、unit_head.block に NULL を代入して区別する */ + /* 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); if(p != NULL) { @@ -266,7 +267,7 @@ void* _mmalloc(size_t size, const char *file, int line, const char *func ) } } - /* 同一サイズのブロックが確保されていない時、新たに確保する */ + /* 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 { @@ -274,7 +275,7 @@ void* _mmalloc(size_t size, const char *file, int line, const char *func ) } if( block->unit_unfill == 0xFFFF ) { - // free済み領域が残っていない + // 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); @@ -287,7 +288,7 @@ void* _mmalloc(size_t size, const char *file, int line, const char *func ) } if( block->unit_unfill == 0xFFFF && block->unit_maxused >= block->unit_count) { - // ユニットを使い果たしたので、unfillリストから削除 + // 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 { @@ -331,7 +332,7 @@ void* _mmalloc(size_t size, const char *file, int line, const char *func ) void* _mcalloc(size_t num, size_t size, const char *file, int line, const char *func ) { - void *p = _mmalloc(num * size,file,line,func); + void *p = malloclib->malloc(num * size,file,line,func); memset(p,0,num * size); return p; } @@ -340,7 +341,7 @@ void* _mrealloc(void *memblock, size_t size, const char *file, int line, const c { size_t old_size; if(memblock == NULL) { - return _mmalloc(size,file,line,func); + return malloclib->malloc(size,file,line,func); } old_size = ((struct unit_head *)((char *)memblock - sizeof(struct unit_head) + sizeof(long)))->size; @@ -348,15 +349,15 @@ void* _mrealloc(void *memblock, size_t size, const char *file, int line, const c 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 { - // サイズ拡大 - void *p = _mmalloc(size,file,line,func); + // Size Large + void *p = malloclib->malloc(size,file,line,func); if(p != NULL) { memcpy(p,memblock,old_size); } - _mfree(memblock,file,line,func); + malloclib->free(memblock,file,line,func); return p; } } @@ -367,7 +368,7 @@ char* _mstrdup(const char *p, const char *file, int line, const char *func ) return NULL; } else { size_t len = strlen(p); - char *string = (char *)_mmalloc(len + 1,file,line,func); + char *string = (char *)malloclib->malloc(len + 1,file,line,func); memcpy(string,p,len+1); return string; } @@ -382,7 +383,7 @@ void _mfree(void *ptr, const char *file, int line, const char *func ) head = (struct unit_head *)((char *)ptr - sizeof(struct unit_head) + sizeof(long)); if(head->size == 0) { - /* malloc() で直に確保された領域 */ + /* 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) @@ -407,7 +408,7 @@ void _mfree(void *ptr, const char *file, int line, const char *func ) 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); @@ -425,11 +426,11 @@ void _mfree(void *ptr, const char *file, int line, const char *func ) #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) { - // unfill リストに追加 + // add to unfill list if( hash_unfill[ block->unit_hash ] ) { hash_unfill[ block->unit_hash ]->unfill_prev = block; } @@ -444,17 +445,17 @@ void _mfree(void *ptr, const char *file, int line, const char *func ) } } -/* ブロックを確保する */ +/* Allocating blocks */ static struct block* block_malloc(unsigned short hash) { int i; 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 { - /* ブロック用の領域を新たに確保する */ + /* Newly allocated space for the block */ p = (struct block*)MALLOC(sizeof(struct block) * (BLOCK_ALLOC), __FILE__, __LINE__, __func__ ); if(p == NULL) { ShowFatalError("Memory manager::block_alloc failed.\n"); @@ -462,17 +463,17 @@ static struct block* block_malloc(unsigned short hash) } 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;i<BLOCK_ALLOC;i++) { if(i != 0) { - // p[0] はこれから使うのでリンクには加えない + // I do not add the link p [0], so we will use p[i].unfill_next = hash_unfill[0]; hash_unfill[0] = &p[i]; p[i].unfill_prev = NULL; @@ -484,7 +485,7 @@ static struct block* block_malloc(unsigned short hash) } } - // unfill に追加 + // Add to unfill memmgr_assert(hash_unfill[ hash ] == NULL); hash_unfill[ hash ] = p; p->unfill_prev = &block_head; @@ -530,18 +531,20 @@ static FILE *log_fp; static void memmgr_log (char *buf) { - if( !log_fp ) - { + if( !log_fp ) { time_t raw; struct tm* t; + const char* svn = get_svn_revision(); + const char* git = get_git_hash(); 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 (Revision %s).\n", - (t->tm_year+1900), (t->tm_mon+1), t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, get_svn_revision()); + fprintf(log_fp, "\nMemory manager: Memory leaks found at %d/%02d/%02d %02dh%02dm%02ds (rev %s).\n", + (t->tm_year+1900), (t->tm_mon+1), t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, + git[0] != HERC_UNKNOWN_VER ? git : svn[0] != HERC_UNKNOWN_VER ? svn : "Unknown"); } fprintf(log_fp, "%s", buf); return; @@ -618,7 +621,7 @@ static void memmgr_final (void) memmgr_log (buf); #endif /* LOG_MEMMGR */ // get block pointer and free it [celest] - _mfree(ptr, ALC_MARK); + malloclib->free(ptr, ALC_MARK); } } } @@ -660,9 +663,9 @@ static void memmgr_init (void) /*====================================== - * Initialise - *-------------------------------------- - */ +* Initialise +*-------------------------------------- +*/ /// Tests the memory for errors and memory leaks. @@ -716,3 +719,28 @@ void malloc_init (void) memmgr_init (); #endif } + +void malloc_defaults() +{ + malloclib = &malloclib_s; + malloclib->init = malloc_init; + malloclib->final = malloc_final; + malloclib->memory_check = malloc_memory_check; + malloclib->usage = malloc_usage; + malloclib->verify_ptr = malloc_verify_ptr; + +// Athena's built-in Memory Manager +#ifdef USE_MEMMGR + malloclib->malloc = _mmalloc; + malloclib->calloc = _mcalloc; + malloclib->realloc = _mrealloc; + malloclib->strdup = _mstrdup; + malloclib->free = _mfree; +#else + malloclib->malloc = aMalloc_; + malloclib->calloc = aCalloc_; + malloclib->realloc = aRealloc_; + malloclib->strdup = aStrdup_; + malloclib->free = aFree_; +#endif +} |