diff options
author | Xiaohong Bao <bao@lindenlab.com> | 2011-01-07 14:57:35 -0700 |
---|---|---|
committer | Xiaohong Bao <bao@lindenlab.com> | 2011-01-07 14:57:35 -0700 |
commit | 7daa3d1ca10199468946feef0ce8eb67489deee0 (patch) | |
tree | e212d4170de2e7d859d8ae855e1aeb2c001880ed /indra | |
parent | 9434f0c2a0e46c580a2aacc04cc1b58876bd3bd8 (diff) |
fixed a hash bug, enlarged the overhead for large allocations, and add new chunk to the tail of the linked list so new allocations go to oldest chunks first.
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llcommon/llmemory.cpp | 46 | ||||
-rw-r--r-- | indra/llcommon/llmemory.h | 3 |
2 files changed, 32 insertions, 17 deletions
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 1f40f5e17a..543f17baf4 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -393,8 +393,6 @@ LLPrivateMemoryPool::LLMemoryBlock::~LLMemoryBlock() //create and initialize a memory block void LLPrivateMemoryPool::LLMemoryBlock::init(char* buffer, U32 buffer_size, U32 slot_size) { - llassert_always(buffer_size >= slot_size) ; - mBuffer = buffer ; mBufferSize = buffer_size ; mSlotSize = slot_size ; @@ -590,12 +588,18 @@ void LLPrivateMemoryPool::LLMemoryChunk::init(char* buffer, U32 buffer_size, U32 } //static -U32 LLPrivateMemoryPool::LLMemoryChunk::getMaxOverhead(U32 data_buffer_size, U32 min_page_size) +U32 LLPrivateMemoryPool::LLMemoryChunk::getMaxOverhead(U32 data_buffer_size, U32 min_slot_size, + U32 max_slot_size, U32 min_block_size, U32 max_block_size) { //for large allocations, reserve some extra memory for meta data to avoid wasting much - if(data_buffer_size / min_page_size < 64) //large allocations + if(data_buffer_size / min_slot_size < 64) //large allocations { - return 4096 ; //4KB + U32 overhead = sizeof(LLMemoryChunk) + (data_buffer_size / min_block_size) * sizeof(LLMemoryBlock) + + sizeof(LLMemoryBlock*) * (max_slot_size / min_slot_size) + sizeof(LLMemoryBlock*) * (max_block_size / min_block_size + 1) ; + + //round to integer times of min_block_size + overhead = ((overhead + min_block_size - 1) / min_block_size) * min_block_size ; + return overhead ; } else { @@ -1290,12 +1294,14 @@ LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::addChunk(S32 chunk_inde if(chunk_index < LARGE_ALLOCATION) { preferred_size = CHUNK_SIZE ; //4MB - overhead = LLMemoryChunk::getMaxOverhead(preferred_size, MIN_BLOCK_SIZES[chunk_index]) ; + overhead = LLMemoryChunk::getMaxOverhead(preferred_size, MIN_SLOT_SIZES[chunk_index], + MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ; } else { preferred_size = LARGE_CHUNK_SIZE ; //16MB - overhead = LLMemoryChunk::getMaxOverhead(preferred_size, MIN_BLOCK_SIZES[chunk_index]) ; + overhead = LLMemoryChunk::getMaxOverhead(preferred_size, MIN_SLOT_SIZES[chunk_index], + MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ; } checkSize(preferred_size + overhead) ; @@ -1306,20 +1312,28 @@ LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::addChunk(S32 chunk_inde { return NULL ; } - memset(buffer, 0, preferred_size + overhead) ; - + LLMemoryChunk* chunk = new (buffer) LLMemoryChunk() ; chunk->init(buffer, preferred_size + overhead, MIN_SLOT_SIZES[chunk_index], MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ; - //add to the head of the linked list - chunk->mNext = mChunkList[chunk_index] ; - if(mChunkList[chunk_index]) + //add to the tail of the linked list { - mChunkList[chunk_index]->mPrev = chunk ; + if(!mChunkList[chunk_index]) + { + mChunkList[chunk_index] = chunk ; + } + else + { + LLMemoryChunk* cur = mChunkList[chunk_index] ; + while(cur->mNext) + { + cur = cur->mNext ; + } + cur->mNext = chunk ; + chunk->mPrev = cur ; + } } - chunk->mPrev = NULL ; - mChunkList[chunk_index] = chunk ; //insert into the hash table addToHashTable(chunk) ; @@ -1425,7 +1439,7 @@ void LLPrivateMemoryPool::addToHashTable(LLMemoryChunk* chunk) { llassert_always(mChunkHashList[end_key] != chunk) - need_rehash = mChunkHashList[end_key]->mHashNext != NULL ; + need_rehash = mChunkHashList[end_key]->mHashNext != NULL || mChunkHashList[end_key] == chunk->mHashNext; if(!need_rehash) { mChunkHashList[end_key]->mHashNext = chunk ; diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index e42dc174b5..5a2889958b 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -142,7 +142,8 @@ public: bool containsAddress(const char* addr) const; - static U32 getMaxOverhead(U32 data_buffer_size, U32 min_page_size) ; + static U32 getMaxOverhead(U32 data_buffer_size, U32 min_slot_size, + U32 max_slot_size, U32 min_block_size, U32 max_block_size) ; void dump() ; |