diff options
| author | Xiaohong Bao <bao@lindenlab.com> | 2011-01-06 16:17:38 -0700 | 
|---|---|---|
| committer | Xiaohong Bao <bao@lindenlab.com> | 2011-01-06 16:17:38 -0700 | 
| commit | a3759a7815f7ba55b825bc76f30a1e333e01f295 (patch) | |
| tree | d1653bbe6f0433edca88aa612fdd80af017ba7cb /indra/llcommon | |
| parent | f4a8027feb2bbeafe7b0cfb3b05fd27f3cf243d3 (diff) | |
add the class LLPrivateMemoryPoolManager
Diffstat (limited to 'indra/llcommon')
| -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.  // | 
