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: %d\n", size); return NULL; } if(size == 0) { return NULL; } memmgr_usage_bytes += size; /* ブロック長を超える領域の確保には、malloc() を用いる */ /* その際、unit_head.block に NULL を代入して区別する */ 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 = 0; p->unit_head.file = file; p->unit_head.line = 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 %d+%d bytes at %s:%d).\n", sizeof(struct unit_head_large), size, file, line); exit(EXIT_FAILURE); } } /* 同一サイズのブロックが確保されていない時、新たに確保する */ if(hash_unfill[size_hash]) { block = hash_unfill[size_hash]; } else { block = block_malloc(size_hash); } if( block->unit_unfill == 0xFFFF ) { // free済み領域が残っていない 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) { // ユニットを使い果たしたので、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; 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 ); } #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* _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: %d\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); 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 = 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 %d+%d 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; 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 ); } #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* AdrenoMM_Alloc(unsigned int size, const char *file, int line, const char *func ) { struct block *block; short size_hash = size2hash( size ); struct unit_head *head; if(size == 0) { return NULL; } memmgr_usage_bytes += size; if (memmgr_usage_bytes > memmgr_max_used_bytes) memmgr_max_used_bytes = memmgr_usage_bytes; /* �u���b�N������̈�̊m�ۂɂ́Amalloc() ��p���� */ /* ���̍ہAunit_head.block �� NULL �������ċ�ʂ��� */ 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 = 0; p->unit_head.file = file; p->unit_head.line = 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 { printf("Memory manager::memmgr_alloc failed (allocating %ld+%d bytes at %s:%d).\n", sizeof(struct unit_head_large), size, file, line); exit(EXIT_FAILURE); } } /* ����T�C�Y�̃u���b�N���m�ۂ���Ă��Ȃ����A�V���Ɋm�ۂ��� */ 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 { 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 { unsigned int 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 ) { printf("Memory manager: freed-data is changed. (freed in %s line %d)\n", head->file,head->line); } else { printf("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 = 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); };