diff options
-rw-r--r-- | indra/llcommon/llmemory.cpp | 157 | ||||
-rw-r--r-- | indra/llcommon/llmemory.h | 32 |
2 files changed, 136 insertions, 53 deletions
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index f9a2770691..f1285841b3 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -1404,14 +1404,10 @@ void LLPrivateMemoryPool::addToHashTable(LLMemoryChunk* chunk) return; //already inserted. } - need_rehash = mChunkHashList[start_key]->mHashNext != NULL ; - if(!need_rehash) - { - llassert_always(!chunk->mHashNext) ; + llassert_always(!chunk->mHashNext) ; - chunk->mHashNext = mChunkHashList[start_key] ; - mChunkHashList[start_key] = chunk ; - } + chunk->mHashNext = mChunkHashList[start_key] ; + mChunkHashList[start_key] = chunk ; } else { @@ -1440,52 +1436,15 @@ void LLPrivateMemoryPool::addToHashTable(LLMemoryChunk* chunk) { if(end_key < start_key) { - for(U16 i = start_key + 1 ; i < mHashFactor; i++) - { - if(mChunkHashList[i]) - { - llassert_always(mChunkHashList[i] != chunk) ; - need_rehash = true ; - break ; - } - else - { - mChunkHashList[i] = chunk ; - } - } - + need_rehash = fillHashTable(start_key + 1, mHashFactor, chunk) ; if(!need_rehash) { - for(U16 i = 0 ; i < end_key; i++) - { - if(mChunkHashList[i]) - { - llassert_always(mChunkHashList[i] != chunk) ; - need_rehash = true ; - break ; - } - else - { - mChunkHashList[i] = chunk ; - } - } + need_rehash = fillHashTable(0, end_key, chunk) ; } } else { - for(i = start_key + 1; i < end_key; i++) - { - if(mChunkHashList[i]) - { - llassert_always(mChunkHashList[i] != chunk) ; - need_rehash = true ; - break ; - } - else - { - mChunkHashList[i] = chunk ; - } - } + need_rehash = fillHashTable(start_key + 1, end_key, chunk) ; } } @@ -1495,7 +1454,7 @@ void LLPrivateMemoryPool::addToHashTable(LLMemoryChunk* chunk) while(HASH_FACTORS[i] <= mHashFactor) i++; mHashFactor = HASH_FACTORS[i] ; - llassert_always(mHashFactor != 0xFFFF) ;//stop point of the recursive calls + llassert_always(mHashFactor != 0xFFFF) ;//stop point to prevent endlessly recursive calls rehash() ; } @@ -1540,6 +1499,8 @@ void LLPrivateMemoryPool::removeFromHashTable(LLMemoryChunk* chunk) void LLPrivateMemoryPool::rehash() { + llinfos << "new hash factor: " << mHashFactor << llendl ; + mChunkHashList.clear() ; mChunkHashList.resize(mHashFactor, NULL) ; @@ -1556,8 +1517,100 @@ void LLPrivateMemoryPool::rehash() } } +bool LLPrivateMemoryPool::fillHashTable(U16 start, U16 end, LLMemoryChunk* chunk) +{ + for(U16 i = start; i < end; i++) + { + if(mChunkHashList[i]) //the slot is occupied. + { + llassert_always(mChunkHashList[i] != chunk) ; + return true ; + } + else + { + mChunkHashList[i] = chunk ; + } + } + + return false ; +} + +//-------------------------------------------------------------------- +//class LLPrivateMemoryPoolManager +//-------------------------------------------------------------------- +LLPrivateMemoryPoolManager* LLPrivateMemoryPoolManager::sInstance = NULL ; + +LLPrivateMemoryPoolManager::LLPrivateMemoryPoolManager() +{ +} + +LLPrivateMemoryPoolManager::~LLPrivateMemoryPoolManager() +{ + //all private pools should be released by their owners before reaching here. + llassert_always(mPoolList.empty()) ; + +#if 0 + if(!mPoolList.empty()) + { + for(std::set<LLPrivateMemoryPool*>::iterator iter = mPoolList.begin(); iter != mPoolList.end(); ++iter) + { + delete *iter; + } + mPoolList.clear() ; + } +#endif +} + +//static +LLPrivateMemoryPoolManager* LLPrivateMemoryPoolManager::getInstance() +{ + if(!sInstance) + { + sInstance = new LLPrivateMemoryPoolManager() ; + } + return sInstance ; +} + +//static +void LLPrivateMemoryPoolManager::destroyClass() +{ + if(sInstance) + { + delete sInstance ; + sInstance = NULL ; + } +} + +LLPrivateMemoryPool* LLPrivateMemoryPoolManager::newPool(U32 max_size, bool threaded) +{ + LLPrivateMemoryPool* pool = new LLPrivateMemoryPool(max_size, threaded) ; + mPoolList.insert(pool) ; + + return pool ; +} + +void LLPrivateMemoryPoolManager::deletePool(LLPrivateMemoryPool* pool) +{ + mPoolList.erase(pool) ; + delete pool; +} + +//debug +void LLPrivateMemoryPoolManager::updateStatistics() +{ + mTotalReservedSize = 0 ; + mTotalAllocatedSize = 0 ; + + for(std::set<LLPrivateMemoryPool*>::iterator iter = mPoolList.begin(); iter != mPoolList.end(); ++iter) + { + mTotalReservedSize += (*iter)->getTotalReservedSize() ; + mTotalAllocatedSize += (*iter)->getTotalAllocatedSize() ; + } +} + //-------------------------------------------------------------------- //class LLPrivateMemoryPoolTester +//-------------------------------------------------------------------- LLPrivateMemoryPoolTester* LLPrivateMemoryPoolTester::sInstance = NULL ; LLPrivateMemoryPool* LLPrivateMemoryPoolTester::sPool = NULL ; LLPrivateMemoryPoolTester::LLPrivateMemoryPoolTester() @@ -1589,7 +1642,7 @@ void LLPrivateMemoryPoolTester::destroy() if(sPool) { - ::delete sPool ; + LLPrivateMemoryPoolManager::getInstance()->deletePool(sPool) ; sPool = NULL ; } } @@ -1600,9 +1653,9 @@ void LLPrivateMemoryPoolTester::run(bool threaded) if(sPool) { - ::delete sPool ; + LLPrivateMemoryPoolManager::getInstance()->deletePool(sPool) ; } - sPool = ::new LLPrivateMemoryPool(max_pool_size, threaded) ; + sPool = LLPrivateMemoryPoolManager::getInstance()->newPool(max_pool_size, threaded) ; //run the test correctnessTest() ; @@ -1610,7 +1663,7 @@ void LLPrivateMemoryPoolTester::run(bool threaded) //fragmentationtest() ; //release pool. - ::delete sPool ; + LLPrivateMemoryPoolManager::getInstance()->deletePool(sPool) ; sPool = NULL ; } diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index f7ca33a279..e42dc174b5 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -73,6 +73,8 @@ private: // class LL_COMMON_API LLPrivateMemoryPool { + friend class LLPrivateMemoryPoolManager ; + public: class LL_COMMON_API LLMemoryBlock //each block is devided into slots uniformly { @@ -181,15 +183,17 @@ public: LLMemoryChunk* mHashNext ; } ; -public: +private: LLPrivateMemoryPool(U32 max_size, bool threaded) ; ~LLPrivateMemoryPool() ; +public: char *allocate(U32 size) ; void free(void* addr) ; void dump() ; U32 getTotalAllocatedSize() ; + U32 getTotalReservedSize() {return mReservedPoolSize;} private: void lock() ; @@ -202,6 +206,7 @@ private: void addToHashTable(LLMemoryChunk* chunk) ; void removeFromHashTable(LLMemoryChunk* chunk) ; void rehash() ; + bool fillHashTable(U16 start, U16 end, LLMemoryChunk* chunk) ; LLMemoryChunk* findChunk(const char* addr) ; void destroyPool() ; @@ -226,6 +231,31 @@ private: U16 mHashFactor ; }; +class LL_COMMON_API LLPrivateMemoryPoolManager +{ +private: + LLPrivateMemoryPoolManager() ; + ~LLPrivateMemoryPoolManager() ; + +public: + static LLPrivateMemoryPoolManager* getInstance() ; + static void destroyClass() ; + + LLPrivateMemoryPool* newPool(U32 max_size, bool threaded) ; + void deletePool(LLPrivateMemoryPool* pool) ; + +private: + static LLPrivateMemoryPoolManager* sInstance ; + std::set<LLPrivateMemoryPool*> mPoolList ; + +public: + //debug and statistics info. + void updateStatistics() ; + + U32 mTotalReservedSize ; + U32 mTotalAllocatedSize ; +}; + // //the below singleton is used to test the private memory pool. // |