summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorXiaohong Bao <bao@lindenlab.com>2011-01-07 14:57:35 -0700
committerXiaohong Bao <bao@lindenlab.com>2011-01-07 14:57:35 -0700
commit7daa3d1ca10199468946feef0ce8eb67489deee0 (patch)
treee212d4170de2e7d859d8ae855e1aeb2c001880ed /indra
parent9434f0c2a0e46c580a2aacc04cc1b58876bd3bd8 (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.cpp46
-rw-r--r--indra/llcommon/llmemory.h3
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() ;