summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/malloc.c530
1 files changed, 225 insertions, 305 deletions
diff --git a/src/common/malloc.c b/src/common/malloc.c
index 8b985bbd7..88d43b21e 100644
--- a/src/common/malloc.c
+++ b/src/common/malloc.c
@@ -129,83 +129,100 @@ char* _bstrdup(const char *chr)
* �o���Ă����肵�܂��B�ipadding,unit_head �������j
*
* �E�u���b�N���m�̓����N���X�g(block_prev,block_next) �ł‚Ȃ���A�����T�C
- * �Y�����ƒu���b�N���m�������N���X�g(samesize_prev,samesize_nect) �ł‚�
+ * �Y�����ƒu���b�N���m�������N���X�g(hash_prev,hash_nect) �ł‚�
* �����Ă��܂��B����ɂ��A�s�v�ƂȂ����������̍ė��p�������I�ɍs���܂��B
*/
+/* �u���b�N�̃A���C�����g */
+#define BLOCK_ALIGNMENT1 16
+#define BLOCK_ALIGNMENT2 64
+
/* �u���b�N�ɓ���f�[�^�� */
-#define BLOCK_DATA_SIZE 80*1024
+#define BLOCK_DATA_COUNT1 128
+#define BLOCK_DATA_COUNT2 608
-/* ��x�Ɋm�ۂ���u���b�N�̐��B */
-#define BLOCK_ALLOC 32
+/* �u���b�N�̑傫��: 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 )
-/* �u���b�N�̃A���C�����g */
-#define BLOCK_ALIGNMENT 64
+/* ��x�Ɋm�ۂ���u���b�N�̐��B */
+#define BLOCK_ALLOC 104
/* �u���b�N */
struct block {
- int block_no; /* �u���b�N�ԍ� */
- struct block* block_prev; /* �O�Ɋm�ۂ����̈� */
struct block* block_next; /* ���Ɋm�ۂ����̈� */
- int samesize_no; /* �����T�C�Y�̔ԍ� */
- struct block* samesize_prev; /* �����T�C�Y�̑O�̗̈� */
- struct block* samesize_next; /* �����T�C�Y�̎��̗̈� */
- size_t unit_size; /* ���j�b�g�̃o�C�g�� 0=���g�p */
- size_t unit_hash; /* ���j�b�g�̃n�b�V�� */
- int unit_count; /* ���j�b�g�̐� */
- int unit_used; /* �g�p�ς݃��j�b�g */
- char data[BLOCK_DATA_SIZE];
+ struct block* unfill_prev; /* ���̖��܂��Ă��Ȃ��̈� */
+ struct block* unfill_next; /* ���̖��܂��Ă��Ȃ��̈� */
+ unsigned short unit_size; /* ���j�b�g�̑傫�� */
+ unsigned short unit_hash; /* ���j�b�g�̃n�b�V�� */
+ unsigned short unit_count; /* ���j�b�g�̌� */
+ unsigned short unit_used; /* �g�p���j�b�g�� */
+ unsigned short unit_unfill; /* ���g�p���j�b�g�̏ꏊ */
+ unsigned short unit_maxused; /* �g�p���j�b�g�̍ő�l */
+ char data[ BLOCK_DATA_SIZE ];
};
struct unit_head {
- struct block* block;
- size_t size;
- const char* file;
- int line;
- unsigned int checksum;
-};
-
-struct chunk {
- char *block;
- struct chunk *next;
+ struct block *block;
+ const char* file;
+ unsigned short line;
+ unsigned short size;
+ long checksum;
};
-static struct block* block_first = NULL;
-static struct block* block_last = NULL;
-static struct block* block_unused = NULL;
-
-/* ���j�b�g�ւ̃n�b�V���B80KB/64Byte = 1280�� */
-static struct block* unit_first[BLOCK_DATA_SIZE/BLOCK_ALIGNMENT]; /* �ŏ� */
-static struct block* unit_unfill[BLOCK_DATA_SIZE/BLOCK_ALIGNMENT]; /* ���܂��ĂȂ� */
-static struct block* unit_last[BLOCK_DATA_SIZE/BLOCK_ALIGNMENT]; /* �Ō� */
+static struct block* hash_unfill[BLOCK_DATA_COUNT1 + BLOCK_DATA_COUNT2 + 1];
+static struct block* block_first, *block_last, block_head;
/* ���������g���񂹂Ȃ��̈�p�̃f�[�^ */
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 chunk *chunk_first = NULL;
+static struct block* block_malloc(unsigned short hash);
+static void block_free(struct block* p);
+static size_t memmgr_usage_bytes;
-static struct block* block_malloc(void);
-static void block_free(struct block* p);
-static void memmgr_info(void);
-static unsigned int memmgr_usage_bytes = 0;
+#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; // �u���b�N���𒴂���ꍇ�� hash �ɂ��Ȃ�
+ }
+}
+
+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 )
{
- int i;
struct block *block;
- size_t size_hash;
+ short size_hash = size2hash( size );
+ struct unit_head *head;
if (((long) size) < 0) {
ShowError("_mmalloc: %d\n", size);
return 0;
}
- size_hash = (size+BLOCK_ALIGNMENT-1) / BLOCK_ALIGNMENT;
if(size == 0) {
return NULL;
}
@@ -213,11 +230,12 @@ void* _mmalloc(size_t size, const char *file, int line, const char *func )
/* �u���b�N���𒴂���̈�̊m�ۂɂ́Amalloc() ��p���� */
/* ���̍ہAunit_head.block �� NULL �������ċ�ʂ��� */
- if(size_hash * BLOCK_ALIGNMENT > BLOCK_DATA_SIZE - sizeof(struct unit_head)) {
+ 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) {
+ p->size = size;
p->unit_head.block = NULL;
- p->unit_head.size = size;
+ p->unit_head.size = 0;
p->unit_head.file = file;
p->unit_head.line = line;
p->prev = NULL;
@@ -228,12 +246,8 @@ void* _mmalloc(size_t size, const char *file, int line, const char *func )
p->next = unit_head_large_first;
}
unit_head_large_first = p;
-#ifdef DEBUG_MEMMGR
- // set allocated data to 0xCD (clean memory)
- memset((char *)p + sizeof(struct unit_head_large) - sizeof(int), 0xCD, size);
-#endif
- *(int*)((char*)p + sizeof(struct unit_head_large) - sizeof(int) + size) = 0xdeadbeaf;
- return (char *)p + sizeof(struct unit_head_large) - sizeof(int);
+ *(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 %d+%d bytes at %s:%d).\n", sizeof(struct unit_head_large), size, file, line);
exit(EXIT_FAILURE);
@@ -241,68 +255,66 @@ void* _mmalloc(size_t size, const char *file, int line, const char *func )
}
/* ����T�C�Y�̃u���b�N���m�ۂ���Ă��Ȃ����A�V���Ɋm�ۂ��� */
- if(unit_unfill[size_hash] == NULL) {
- block = block_malloc();
- if(unit_first[size_hash] == NULL) {
- /* ����m�� */
- unit_first[size_hash] = block;
- unit_last[size_hash] = block;
- block->samesize_no = 0;
- block->samesize_prev = NULL;
- block->samesize_next = NULL;
+ if(hash_unfill[size_hash]) {
+ block = hash_unfill[size_hash];
+ } else {
+ block = block_malloc(size_hash);
+ }
+
+ if( block->unit_unfill == 0xFFFF ) {
+ // free�ςݗ̈悪�c���Ă��Ȃ�
+ 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) {
+ // ���j�b�g���g���ʂ������̂ŁAunfill���X�g����폜
+ if( block->unfill_prev == &block_head) {
+ hash_unfill[ size_hash ] = block->unfill_next;
} else {
- /* �A����� */
- unit_last[size_hash]->samesize_next = block;
- block->samesize_no = unit_last[size_hash]->samesize_no + 1;
- block->samesize_prev = unit_last[size_hash];
- block->samesize_next = NULL;
- unit_last[size_hash] = block;
+ block->unfill_prev->unfill_next = block->unfill_next;
}
- unit_unfill[size_hash] = block;
- block->unit_size = size_hash * BLOCK_ALIGNMENT + sizeof(struct unit_head);
- block->unit_count = (int)(BLOCK_DATA_SIZE / block->unit_size);
- block->unit_used = 0;
- block->unit_hash = size_hash;
- /* ���g�pFlag�𗧂Ă� */
- for(i=0;i<block->unit_count;i++) {
- ((struct unit_head*)(&block->data[block->unit_size * i]))->block = NULL;
+ if( block->unfill_next ) {
+ block->unfill_next->unfill_prev = block->unfill_prev;
}
- }
- /* ���j�b�g�g�p�����Z */
- block = unit_unfill[size_hash];
- block->unit_used++;
-
- /* ���j�b�g����S�Ďg���ʂ����� */
- if(block->unit_count == block->unit_used) {
- do {
- unit_unfill[size_hash] = unit_unfill[size_hash]->samesize_next;
- } while(
- unit_unfill[size_hash] != NULL &&
- unit_unfill[size_hash]->unit_count == unit_unfill[size_hash]->unit_used
- );
+ block->unfill_prev = NULL;
}
- /* �u���b�N�̒��̋󂫃��j�b�g�{�� */
- for(i=0;i<block->unit_count;i++) {
- struct unit_head *head = (struct unit_head*)(&block->data[block->unit_size * i]);
- if(head->block == NULL) {
- head->block = block;
- head->size = size;
- head->line = line;
- head->file = file;
#ifdef DEBUG_MEMMGR
- // set allocated memory to 0xCD (clean memory)
- memset((char *)head + sizeof(struct unit_head) - sizeof(int), 0xCD, size);
-#endif
- *(int*)((char*)head + sizeof(struct unit_head) - sizeof(int) + size) = 0xdeadbeaf;
- return (char *)head + sizeof(struct unit_head) - sizeof(int);
+ {
+ size_t i, sz = hash2size( size_hash );
+ for( i=0; i<sz; i++ )
+ {
+ if( ((unsigned char*)head)[ sizeof(struct unit_head) - sizeof(long) + i] != 0xfd )
+ {
+ if( head->line != 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 );
}
- // �����ɗ��Ă͂����Ȃ��B
- ShowFatalError("Memory manager::memmgr_malloc() serious error (allocating %d+%d bytes at %s:%d)\n", sizeof(struct unit_head_large), size, file, line);
- memmgr_info();
- exit(EXIT_FAILURE);
- //return NULL;
+#endif
+
+ head->block = block;
+ head->file = file;
+ head->line = 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 )
@@ -319,7 +331,10 @@ void* _mrealloc(void *memblock, size_t size, const char *file, int line, const c
return _mmalloc(size,file,line,func);
}
- old_size = ((struct unit_head *)((char *)memblock - sizeof(struct unit_head) + sizeof(int)))->size;
+ 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) {
// �T�C�Y�k�� -> ���̂܂ܕԂ��i�蔲���j
return memblock;
@@ -349,24 +364,21 @@ char* _mstrdup(const char *p, const char *file, int line, const char *func )
void _mfree(void *ptr, const char *file, int line, const char *func )
{
struct unit_head *head;
- size_t size_hash;
if (ptr == NULL)
return;
- head = (struct unit_head *)((char *)ptr - sizeof(struct unit_head) + sizeof(int));
- size_hash = (head->size+BLOCK_ALIGNMENT-1) / BLOCK_ALIGNMENT;
-
- if(head->block == NULL) {
- if(size_hash * BLOCK_ALIGNMENT > BLOCK_DATA_SIZE - sizeof(struct unit_head)) {
- /* malloc() �Œ��Ɋm�ۂ��ꂽ�̈� */
- struct unit_head_large *head_large = (struct unit_head_large *)((char *)ptr - sizeof(struct unit_head_large) + sizeof(int));
- if(
- *(int*)((char*)head_large + sizeof(struct unit_head_large) - sizeof(int) + head->size)
- != 0xdeadbeaf)
- {
- ShowError("Memory manager: args of aFree is overflowed pointer %s line %d\n", file, line);
- }
+ head = (struct unit_head *)((char *)ptr - sizeof(struct unit_head) + sizeof(long));
+ if(head->size == 0) {
+ /* malloc() �Œ��Ɋm�ۂ��ꂽ�̈� */
+ 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 is overflowed pointer %s line %d\n", file, line);
+ } else {
+ head->size = -1;
if(head_large->prev) {
head_large->prev->next = head_large->next;
} else {
@@ -375,192 +387,123 @@ void _mfree(void *ptr, const char *file, int line, const char *func )
if(head_large->next) {
head_large->next->prev = head_large->prev;
}
- head->block = NULL;
- memmgr_usage_bytes -= head->size;
+ memmgr_usage_bytes -= head_large->size;
#ifdef DEBUG_MEMMGR
- // set freed memory to 0xDD (dead memory)
- memset(ptr, 0xDD, head->size);
+ // set freed memory to 0xfd
+ memset(ptr, 0xfd, head_large->size);
#endif
FREE(head_large,file,line,func);
- } else {
- ShowError("Memory manager: args of aFree is freed pointer %s:%d@%s\n", file, line, func);
}
- ptr = NULL;
- return;
} else {
/* ���j�b�g��� */
struct block *block = head->block;
- if((unsigned long)block % sizeof(struct block) != 0) {
- ShowError("Memory manager: args of aFree is not valid pointer %s line %d\n", file, line);
- } else if(*(int*)((char*)head + sizeof(struct unit_head) - sizeof(int) + head->size) != 0xdeadbeaf) {
+ if( (char*)head - (char*)block > sizeof(struct block) ) {
+ ShowError("Memory manager: args of aFree is invalid pointer %s line %d\n",file,line);
+ } else if(head->block == NULL) {
+ ShowError("Memory manager: args of aFree is freed pointer %s:%d@%s\n", file, line, func);
+ } else if(*(long*)((char*)head + sizeof(struct unit_head) - sizeof(long) + head->size) != 0xdeadbeaf) {
ShowError("Memory manager: args of aFree is overflowed pointer %s line %d\n", file, line);
} else {
- head->block = NULL;
+ memmgr_usage_bytes -= head->size;
+ head->block = NULL;
#ifdef DEBUG_MEMMGR
- // set freed memory to 0xDD (dead memory)
- memset(ptr, 0xDD, head->size);
+ memset(ptr, 0xfd, block->unit_size - sizeof(struct unit_head) + sizeof(long) );
+ head->file = file;
+ head->line = line;
#endif
- memmgr_usage_bytes -= head->size;
+ memmgr_assert( block->unit_used > 0 );
if(--block->unit_used == 0) {
/* �u���b�N�̉�� */
- if(unit_unfill[block->unit_hash] == block) {
- /* �󂫃��j�b�g�Ɏw�肳��Ă��� */
- do {
- unit_unfill[block->unit_hash] = unit_unfill[block->unit_hash]->samesize_next;
- } while(
- unit_unfill[block->unit_hash] != NULL &&
- unit_unfill[block->unit_hash]->unit_count == unit_unfill[block->unit_hash]->unit_used
- );
- }
- if(block->samesize_prev == NULL && block->samesize_next == NULL) {
- /* �Ɨ��u���b�N�̉�� */
- unit_first[block->unit_hash] = NULL;
- unit_last[block->unit_hash] = NULL;
- unit_unfill[block->unit_hash] = NULL;
- } else if(block->samesize_prev == NULL) {
- /* �擪�u���b�N�̉�� */
- unit_first[block->unit_hash] = block->samesize_next;
- (block->samesize_next)->samesize_prev = NULL;
- } else if(block->samesize_next == NULL) {
- /* ���[�u���b�N�̉�� */
- unit_last[block->unit_hash] = block->samesize_prev;
- (block->samesize_prev)->samesize_next = NULL;
- } else {
- /* ���ԃu���b�N�̉�� */
- (block->samesize_next)->samesize_prev = block->samesize_prev;
- (block->samesize_prev)->samesize_next = block->samesize_next;
- }
block_free(block);
} else {
- /* �󂫃��j�b�g�̍Đݒ� */
- if(
- unit_unfill[block->unit_hash] == NULL ||
- unit_unfill[block->unit_hash]->samesize_no > block->samesize_no
- ) {
- unit_unfill[block->unit_hash] = block;
+ if( block->unfill_prev == NULL) {
+ // unfill ���X�g�ɒlj�
+ 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)(((unsigned long)head - (unsigned long)block->data) / block->unit_size);
}
- ptr = NULL;
}
}
}
-/* ���݂̏󋵂�\������ */
-static void memmgr_info(void)
+/* �u���b�N���m�ۂ��� */
+static struct block* block_malloc(unsigned short hash)
{
int i;
struct block *p;
- ShowInfo("** Memory Manager Information **\n");
- if(block_first == NULL) {
- ShowMessage("Uninitialized.\n");
- return;
- }
- ShowMessage(
- "Blocks: %04u , BlockSize: %06u Byte , Used: %08uKB\n",
- block_last->block_no+1,sizeof(struct block),
- (block_last->block_no+1) * sizeof(struct block) / 1024
- );
- p = block_first;
- for(i=0;i<=block_last->block_no;i++) {
- ShowMessage(" Block #%04u : ",p->block_no);
- if(p->unit_size == 0) {
- ShowMessage("unused.\n");
- } else {
- ShowMessage(
- "size: %05u byte. used: %04u/%04u prev:",
- p->unit_size - sizeof(struct unit_head),p->unit_used,p->unit_count
- );
- if(p->samesize_prev == NULL) {
- ShowMessage("NULL");
- } else {
- ShowMessage("%04u",(p->samesize_prev)->block_no);
- }
- ShowMessage(" next:");
- if(p->samesize_next == NULL) {
- ShowMessage("NULL");
- } else {
- ShowMessage("%04u",(p->samesize_next)->block_no);
- }
- ShowMessage("\n");
- }
- p = p->block_next;
- }
-}
-
-/* �u���b�N���m�ۂ��� */
-static struct block* block_malloc(void)
-{
- if(block_unused != NULL) {
+ if(hash_unfill[0] != NULL) {
/* �u���b�N�p�̗̈�͊m�ۍς� */
- struct block* ret = block_unused;
- do {
- block_unused = block_unused->block_next;
- } while(block_unused != NULL && block_unused->unit_size != 0);
- return ret;
+ p = hash_unfill[0];
+ hash_unfill[0] = hash_unfill[0]->unfill_next;
} else {
/* �u���b�N�p�̗̈��V���Ɋm�ۂ��� */
- int i;
- int block_no;
- struct block* p;
- struct chunk* chunk;
- char *pb = (char *)CALLOC(sizeof(struct block),BLOCK_ALLOC+1,file,line,func);
- if(pb == NULL) {
+ p = (struct block*)MALLOC(sizeof(struct block) * (BLOCK_ALLOC), file,line,func );
+ if(p == NULL) {
ShowFatalError("Memory manager::block_alloc failed.\n");
exit(EXIT_FAILURE);
}
- // store original block address in chunk
- chunk = (struct chunk *)MALLOC(sizeof(struct chunk),file,line,func);
- if (chunk == NULL) {
- ShowFatalError("Memory manager::block_alloc failed.\n");
- exit(EXIT_FAILURE);
- }
- chunk->block = pb;
- chunk->next = (chunk_first) ? chunk_first : NULL;
- chunk_first = chunk;
-
- // �u���b�N�̃|�C���^�̐擪��sizeof(block) �A���C�����g�ɑ�����
- // ���̃A�h���X��free() ���邱�Ƃ͂Ȃ��̂ŁA���ڃ|�C���^��ύX���Ă���B
- pb += sizeof(struct block) - ((unsigned long)pb % sizeof(struct block));
- p = (struct block*)pb;
if(block_first == NULL) {
/* ����m�� */
- block_no = 0;
- block_first = p;
+ block_first = p;
} else {
- block_no = block_last->block_no + 1;
block_last->block_next = p;
- p->block_prev = block_last;
}
block_last = &p[BLOCK_ALLOC - 1];
+ block_last->block_next = NULL;
/* �u���b�N��A�������� */
for(i=0;i<BLOCK_ALLOC;i++) {
if(i != 0) {
- p[i].block_prev = &p[i-1];
+ // p[0] �͂��ꂩ��g���̂Ń����N�ɂ͉����Ȃ�
+ p[i].unfill_next = hash_unfill[0];
+ hash_unfill[0] = &p[i];
+ p[i].unfill_prev = NULL;
}
if(i != BLOCK_ALLOC -1) {
p[i].block_next = &p[i+1];
}
- p[i].block_no = block_no + i;
}
-
- /* ���g�p�u���b�N�ւ̃|�C���^���X�V */
- block_unused = &p[1];
- p->unit_size = 1;
- return p;
}
+
+ // unfill �ɒlj�
+ memmgr_assert(hash_unfill[ hash ] == NULL);
+ hash_unfill[ hash ] = p;
+ p->unfill_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)
{
- /* free() �����ɁA���g�p�t���O��t���邾�� */
- p->unit_size = 0;
- /* ���g�p�|�C���^�[���X�V���� */
- if(block_unused == NULL) {
- block_unused = p;
- } else if(block_unused->block_no > p->block_no) {
- block_unused = 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;
}
unsigned int memmgr_usage (void)
@@ -592,75 +535,43 @@ static void memmgr_log (char *buf)
static void memmgr_final (void)
{
struct block *block = block_first;
- struct chunk *chunk = chunk_first, *chunk2;
- struct unit_head_large *large = unit_head_large_first, *large2;
- int i;
+ struct unit_head_large *large = unit_head_large_first;
#ifdef LOG_MEMMGR
int count = 0;
- char buf[128];
#endif
while (block) {
- if (block->unit_size) {
- for (i = 0; i < block->unit_count; i++) {
- struct unit_head *head = (struct unit_head*)(&block->data[block->unit_size * i]);
- if(head->block != NULL)
- {
- #ifdef LOG_MEMMGR
+ if (block->unfill_prev) {
+ int i;
+ for (i = 0; i < block->unit_maxused; i++) {
+ struct unit_head *head = block2unit(block, i);
+ if(head->block != NULL) {
+#ifdef LOG_MEMMGR
+ char buf[128];
sprintf (buf,
"%04d : %s line %d size %lu\n", ++count,
head->file, head->line, (unsigned long)head->size);
memmgr_log (buf);
- #endif
+#endif
// get block pointer and free it [celest]
- _mfree ((char *)head + sizeof(struct unit_head) - sizeof(int), ALC_MARK);
+ _mfree ((char *)head + sizeof(struct unit_head) - sizeof(short), ALC_MARK);
}
}
}
- //if (block->block_no >= block2->block_no + BLOCK_ALLOC - 1) {
- // reached a new block array
- //block = block->block_next;
-
- /* Okay wise guys... this is how block2 was allocated: [Skotlex]
- struct block* p;
- char *pb = (char *) CALLOC (sizeof(struct block),BLOCK_ALLOC + 1);
- pb += sizeof(struct block) - ((unsigned long)pb % sizeof(struct block));
- p = (struct block*)pb;
-
- The reason we get an invalid pointer is that we allocated pb, not p.
- So how do you get pb when you only have p?
- The answer is, you can't, because the original pointer was lost when
- memory-aligning the block. So we either forget this FREE or use a
- self-reference...
- Since we are already quitting, it might be ok to just not free the block
- as it is.
- */
- // didn't realise that before o.o -- block chunks are now freed below [celest]
- // FREE(block2);
- //block2 = block;
- //continue;
- //}
block = block->block_next;
}
- // free the allocated block chunks
- chunk = chunk_first;
- while (chunk) {
- chunk2 = chunk->next;
- FREE(chunk->block,file,line,func);
- FREE(chunk,file,line,func);
- chunk = chunk2;
- }
-
while(large) {
- large2 = large->next;
- #ifdef LOG_MEMMGR
+ struct unit_head_large *large2;
+#ifdef LOG_MEMMGR
+ char buf[128];
sprintf (buf,
"%04d : %s line %d size %lu\n", ++count,
large->unit_head.file, large->unit_head.line, (unsigned long)large->unit_head.size);
memmgr_log (buf);
- #endif
+#endif
+ large2 = large->next;
FREE(large,file,line,func);
large = large2;
}
@@ -677,10 +588,10 @@ static void memmgr_final (void)
static void memmgr_init (void)
{
- #ifdef LOG_MEMMGR
- sprintf(memmer_logfile, "log/%s.leaks", SERVER_NAME);
- ShowStatus("Memory manager initialised: "CL_WHITE"%s"CL_RESET"\n", memmer_logfile);
- #endif
+#ifdef LOG_MEMMGR
+ sprintf(memmer_logfile, "log/%s.leaks", SERVER_NAME);
+ ShowStatus("Memory manager initialised: "CL_WHITE"%s"CL_RESET"\n", memmer_logfile);
+#endif
return;
}
#endif
@@ -691,6 +602,15 @@ static void memmgr_init (void)
*--------------------------------------
*/
+bool malloc_verify(void* ptr)
+{
+#ifdef USE_MEMMGR
+
+#endif
+
+ return true;
+}
+
unsigned int malloc_usage (void)
{
#ifdef USE_MEMMGR