📄 memory.cpp
字号:
#include <hk_base/base.h>
#include <malloc.h>
class hk_Memory_With_Size {
public:
hk_int32 m_size;
enum {
MAGIC_MEMORY_WITH_SIZE = 0x2345656
} m_magic;
hk_int32 m_dummy[2];
};
void hk_Memory::init_memory( char *buffer, int buffer_size )
{
m_memory_start = buffer;
m_used_end = buffer;
m_memory_end = m_used_end + buffer_size;
m_allocated_memory_blocks = HK_NULL;
for (int i = HK_MEMORY_MAX_ROW-1; i>=0 ; i-- )
{
m_free_list[i] = HK_NULL;
m_blocks_in_use[i] = 0;
}
for (int j = 0; j <= HK_MEMORY_MAX_SIZE_SMALL_BLOCK; j++ )
{
int row = size_to_row(j);
m_size_to_row[ j ] = row;
m_row_to_size[row] = j;
}
{ // statistics
for (int i = 0; i< HK_MEMORY_CLASS_MAX; i++)
{
hk_Memory_Statistics &s = m_statistics[i];
s.m_max_size_in_use = 0;
s.m_size_in_use = 0;
s.m_n_allocates = 0;
s.m_blocks_in_use = 0;
}
}
}
hk_Memory::hk_Memory()
{
#ifdef HK_MEMORY_POOL_INITIAL_SIZE
init_memory( new char[HK_MEMORY_POOL_INITIAL_SIZE], 0 );
#else
init_memory( HK_NULL, 0 );
#endif
}
hk_Memory::hk_Memory(char *buffer, int buffer_size)
{
init_memory( buffer, buffer_size );
}
hk_Memory::~hk_Memory()
{
//[XXX this does not work in havok since global arrays
// may be destructed after this has been called :(
//while ( m_allocated_memory_blocks ){
// hk_Memory_Block *b = m_allocated_memory_blocks;
// m_allocated_memory_blocks = m_allocated_memory_blocks->m_next;
// hk_Memory::aligned_free( (void *)b );
//}
//]
}
void *hk_Memory::allocate_real( int size )
{
if ( size > HK_MEMORY_MAX_SIZE_SMALL_BLOCK)
{
#ifdef HK_CHECK
hk_Console::get_instance()->printf("big block allocated size %i\n", size );
#endif
return hk_Memory::aligned_malloc( size, HK_MEMORY_CACHE_ALIGNMENT);
}
int row = m_size_to_row[ size ];
size = m_row_to_size[ row ];
int allocated_size = size;
void *result;
// allocate first block
if ( size + m_used_end > m_memory_end)
{
#ifdef HK_CHECK
hk_Console::get_instance()->printf("running out of space: block size %i\n", size );
#endif
hk_Memory_Block *b = (hk_Memory_Block *)hk_Memory::aligned_malloc( sizeof(hk_Memory_Block) + HK_MEMORY_EXTRA_BLOCK_SIZE, HK_MEMORY_CACHE_ALIGNMENT );
b->m_next = m_allocated_memory_blocks;
m_allocated_memory_blocks = b;
m_memory_start = (char *)(b+1);
m_used_end = m_memory_start;
m_memory_end = m_used_end + HK_MEMORY_EXTRA_BLOCK_SIZE;
}
result = (void *)m_used_end;
hk_Memory_Elem *el = (hk_Memory_Elem *) m_used_end;
el->m_magic = 0;
m_used_end += size;
// allocate rest to get make sure the alignment is ok
int biu = m_blocks_in_use[row];
while ( allocated_size < 256 )
{
if ( size + m_used_end < m_memory_end){
hk_Memory_Elem *el = (hk_Memory_Elem *) m_used_end;
el->m_magic = 0;
this->deallocate( m_used_end, size, HK_MEMORY_CLASS_DUMMY );
m_used_end += size;
}else{
break;
}
allocated_size += size;
}
m_blocks_in_use[row] = biu;
return result;
}
void* hk_Memory::allocate(int size, hk_MEMORY_CLASS cl)
{
#ifdef HK_MEMORY_ENABLE_STATISTICS
hk_Memory_Statistics &s = m_statistics[cl];
s.m_size_in_use += size;
s.m_blocks_in_use += 1;
s.m_n_allocates += 1;
if ( s.m_size_in_use > s.m_max_size_in_use)
{
s.m_max_size_in_use = s.m_size_in_use;
}
#endif
#ifdef HK_MEMORY_ENABLE_DEBUG_CHECK
hk_Memory_With_Size *x = (hk_Memory_With_Size *)this->hk_Memory::aligned_malloc( size + sizeof( hk_Memory_With_Size ), HK_MEMORY_CACHE_ALIGNMENT );
x->m_size = size;
x->m_magic = hk_Memory_With_Size::MAGIC_MEMORY_WITH_SIZE;
return (void *)(x+1);
#else
if ( size <= HK_MEMORY_MAX_SIZE_SMALL_BLOCK){
int row = m_size_to_row[size];
m_blocks_in_use[row]++;
hk_Memory_Elem *n = m_free_list[row];
if ( n ){
m_free_list[row] = n->m_next;
n->m_magic = 0;
return (void *)n;
}
}
return allocate_real( size );
#endif
}
void hk_Memory::deallocate(void* p, int size, hk_MEMORY_CLASS cl)
{
#ifdef HK_MEMORY_ENABLE_STATISTICS
hk_Memory_Statistics &s = m_statistics[cl];
s.m_size_in_use -= size;
s.m_blocks_in_use -= 1;
#endif
#ifdef HK_MEMORY_ENABLE_DEBUG_CHECK
{
hk_Memory_With_Size *x = (hk_Memory_With_Size *)p;
x--;
HK_ASSERT( x->m_magic == hk_Memory_With_Size::MAGIC_MEMORY_WITH_SIZE );
HK_ASSERT( x->m_size == size );
this->aligned_free( x );
}
#else
if ( size <= HK_MEMORY_MAX_SIZE_SMALL_BLOCK ){
hk_Memory_Elem *me = (hk_Memory_Elem *)p;
int row = m_size_to_row[size];
m_blocks_in_use[row]--;
me->m_next = m_free_list[row];
HK_ASSERT( me->m_magic != HK_MEMORY_MAGIC_NUMBER);
me->m_magic = HK_MEMORY_MAGIC_NUMBER;
m_free_list[row] = me;
}else{
hk_Memory::aligned_free((char *)p);
}
#endif
}
int hk_Memory::size_to_row( int size )
{
HK_ASSERT (HK_MEMORY_MAX_ROW == 12 );
if (size <= 8 ) return 1;
else if (size <= 16 ) return 2;
else if (size <= 32 ) return 3;
else if (size <= 48 ) return 4;
else if (size <= 64 ) return 5;
else if (size <= 96 ) return 6;
else if (size <= 128 ) return 7;
else if (size <= 160 ) return 8;
else if (size <= 192 ) return 9;
else if (size <= 256 ) return 10;
else if (size <= 512 ) return 11;
else{
HK_BREAK;
return -1;
}
}
void* hk_Memory::allocate_debug(int n,
const char* /*file*/,
int /*line*/)
{
return new char[n];
}
void hk_Memory::deallocate_debug(
void* p,
int /*n*/,
const char* /*file*/,
int /*line*/)
{
delete[] static_cast<char*>(p);
}
void* hk_Memory::allocate_and_store_size(int byte_size, hk_MEMORY_CLASS cl)
{
hk_Memory_With_Size *x = (hk_Memory_With_Size *)this->allocate( byte_size + sizeof( hk_Memory_With_Size ), cl);
x->m_size = byte_size;
x->m_magic = hk_Memory_With_Size::MAGIC_MEMORY_WITH_SIZE;
return (void *)(x+1);
}
void hk_Memory::deallocate_stored_size(void* p , hk_MEMORY_CLASS cl)
{
if(p)
{
hk_Memory_With_Size *x = (hk_Memory_With_Size *)p;
x--;
HK_ASSERT( x->m_magic == hk_Memory_With_Size::MAGIC_MEMORY_WITH_SIZE );
this->deallocate( x, x->m_size + sizeof( hk_Memory_With_Size ), cl );
}
}
void *hk_Memory::aligned_malloc( hk_size_t size, hk_size_t alignment)
{
#if defined(WIN32_)
return _aligned_malloc ( size, alignment );
#else
return ::malloc(size);
#endif
}
void hk_Memory::aligned_free( void *data )
{
#if defined(WIN32_)
_aligned_free ( data );
#else
::free(data);
#endif
}
hk_Memory *hk_Memory::get_instance()
{
static hk_Memory s_memory_instance;
return &s_memory_instance;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -