diff options
Diffstat (limited to 'indra/llcommon')
| -rw-r--r-- | indra/llcommon/llmemory.cpp | 95 | ||||
| -rw-r--r-- | indra/llcommon/llmemory.h | 11 | 
2 files changed, 79 insertions, 27 deletions
| diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 8c02ad8290..3b27a1639a 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -165,33 +165,60 @@ void LLMemory::logMemoryInfo(BOOL update)  	llinfos << "Current allocated page size (KB): " << sAllocatedPageSizeInKB << llendl ;  	llinfos << "Current availabe physical memory(KB): " << sAvailPhysicalMemInKB << llendl ;  	llinfos << "Current max usable memory(KB): " << sMaxPhysicalMemInKB << llendl ; + +	llinfos << "--- private pool information -- " << llendl ; +	llinfos << "Total reserved (KB): " << LLPrivateMemoryPoolManager::getInstance()->mTotalReservedSize / 1024 << llendl ; +	llinfos << "Total allocated (KB): " << LLPrivateMemoryPoolManager::getInstance()->mTotalAllocatedSize / 1024 << llendl ;  }  //return 0: everything is normal;  //return 1: the memory pool is low, but not in danger;  //return -1: the memory pool is in danger, is about to crash.  //static  -S32 LLMemory::isMemoryPoolLow() +bool LLMemory::isMemoryPoolLow()  {  	static const U32 LOW_MEMEOY_POOL_THRESHOLD_KB = 64 * 1024 ; //64 MB for emergency use +	const static U32 MAX_SIZE_CHECKED_MEMORY_BLOCK = 64 * 1024 * 1024 ; //64 MB +	static void* last_reserved_address = NULL ;  	if(!sEnableMemoryFailurePrevention)  	{ -		return 0 ; //no memory failure prevention. +		return false ; //no memory failure prevention.  	}  	if(sAvailPhysicalMemInKB < (LOW_MEMEOY_POOL_THRESHOLD_KB >> 2)) //out of physical memory  	{ -		return -1 ; +		return true ;  	}  	if(sAllocatedPageSizeInKB + (LOW_MEMEOY_POOL_THRESHOLD_KB >> 2) > sMaxHeapSizeInKB) //out of virtual address space.  	{ -		return -1 ; +		return true ;  	} -	return (S32)(sAvailPhysicalMemInKB < LOW_MEMEOY_POOL_THRESHOLD_KB ||  +	bool is_low = (S32)(sAvailPhysicalMemInKB < LOW_MEMEOY_POOL_THRESHOLD_KB ||   		sAllocatedPageSizeInKB + LOW_MEMEOY_POOL_THRESHOLD_KB > sMaxHeapSizeInKB) ; + +	//check the virtual address space fragmentation +	if(!is_low) +	{ +		if(!last_reserved_address) +		{ +			last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ; +		} +		else +		{ +			last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ; +			if(!last_reserved_address) //failed, try once more +			{ +				last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ; +			} +		} + +		is_low = !last_reserved_address ; //allocation failed +	} + +	return is_low ;  }  //static  @@ -1289,15 +1316,13 @@ U16 LLPrivateMemoryPool::LLMemoryChunk::getPageLevel(U32 size)  //--------------------------------------------------------------------  const U32 CHUNK_SIZE = 4 << 20 ; //4 MB  const U32 LARGE_CHUNK_SIZE = 4 * CHUNK_SIZE ; //16 MB -LLPrivateMemoryPool::LLPrivateMemoryPool(S32 type) : +LLPrivateMemoryPool::LLPrivateMemoryPool(S32 type, U32 max_pool_size) :  	mMutexp(NULL),	  	mReservedPoolSize(0),  	mHashFactor(1), -	mType(type) +	mType(type), +	mMaxPoolSize(max_pool_size)  { -	const U32 MAX_POOL_SIZE = 256 * 1024 * 1024 ; //256 MB - -	mMaxPoolSize = MAX_POOL_SIZE ;  	if(type == STATIC_THREADED || type == VOLATILE_THREADED)  	{  		mMutexp = new LLMutex ; @@ -1362,16 +1387,31 @@ char* LLPrivateMemoryPool::allocate(U32 size)  				chunk = chunk->mNext ;  			}  		} - -		chunk = addChunk(chunk_idx) ; -		if(chunk) +		else  		{ -			p = chunk->allocate(size) ; +			chunk = addChunk(chunk_idx) ; +			if(chunk) +			{ +				p = chunk->allocate(size) ; +			}  		}  	}  	unlock() ; +	if(!p) //to get memory from the private pool failed, try the heap directly +	{ +		static bool to_log = true ; +		 +		if(to_log) +		{ +			llwarns << "The memory pool overflows, now using heap directly!" << llendl ; +			to_log = false ; +		} + +		return (char*)malloc(size) ; +	} +  	return p ;  } @@ -1472,7 +1512,7 @@ void  LLPrivateMemoryPool::destroyPool()  	unlock() ;  } -void  LLPrivateMemoryPool::checkSize(U32 asked_size) +bool LLPrivateMemoryPool::checkSize(U32 asked_size)  {  	if(mReservedPoolSize + asked_size > mMaxPoolSize)  	{ @@ -1480,8 +1520,12 @@ void  LLPrivateMemoryPool::checkSize(U32 asked_size)  		llinfos << "Total reserved size: " << mReservedPoolSize + asked_size << llendl ;  		llinfos << "Total_allocated Size: " << getTotalAllocatedSize() << llendl ; -		llerrs << "The pool is overflowing..." << llendl ; +		//llerrs << "The pool is overflowing..." << llendl ; + +		return false ;  	} + +	return true ;  }  LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::addChunk(S32 chunk_index) @@ -1501,7 +1545,11 @@ LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::addChunk(S32 chunk_inde  			MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ;  	} -	checkSize(preferred_size + overhead) ; +	if(!checkSize(preferred_size + overhead)) +	{ +		return NULL ; +	} +  	mReservedPoolSize += preferred_size + overhead ;  	char* buffer = (char*)malloc(preferred_size + overhead) ; @@ -1593,7 +1641,7 @@ LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::findChunk(const char* a  void LLPrivateMemoryPool::addToHashTable(LLMemoryChunk* chunk)   { -	static const U16 HASH_FACTORS[] = {41, 83, 193, 317, 419, 523, 0xFFFF};  +	static const U16 HASH_FACTORS[] = {41, 83, 193, 317, 419, 523, 719, 997, 1523, 0xFFFF};   	U16 i ;  	if(mChunkHashList.empty()) @@ -1774,7 +1822,7 @@ void LLPrivateMemoryPool::LLChunkHashElement::remove(LLPrivateMemoryPool::LLMemo  //--------------------------------------------------------------------  LLPrivateMemoryPoolManager* LLPrivateMemoryPoolManager::sInstance = NULL ; -LLPrivateMemoryPoolManager::LLPrivateMemoryPoolManager(BOOL enabled)  +LLPrivateMemoryPoolManager::LLPrivateMemoryPoolManager(BOOL enabled, U32 max_pool_size)   {  	mPoolList.resize(LLPrivateMemoryPool::MAX_TYPES) ; @@ -1784,6 +1832,9 @@ LLPrivateMemoryPoolManager::LLPrivateMemoryPoolManager(BOOL enabled)  	}  	mPrivatePoolEnabled = enabled ; + +	const U32 MAX_POOL_SIZE = 256 * 1024 * 1024 ; //256 MB +	mMaxPrivatePoolSize = llmax(max_pool_size, MAX_POOL_SIZE) ;  }  LLPrivateMemoryPoolManager::~LLPrivateMemoryPoolManager()  @@ -1826,11 +1877,11 @@ LLPrivateMemoryPoolManager::~LLPrivateMemoryPoolManager()  }  //static  -void LLPrivateMemoryPoolManager::initClass(BOOL enabled)  +void LLPrivateMemoryPoolManager::initClass(BOOL enabled, U32 max_pool_size)   {  	llassert_always(!sInstance) ; -	sInstance = new LLPrivateMemoryPoolManager(enabled) ; +	sInstance = new LLPrivateMemoryPoolManager(enabled, max_pool_size) ;  }  //static  @@ -1862,7 +1913,7 @@ LLPrivateMemoryPool* LLPrivateMemoryPoolManager::newPool(S32 type)  	if(!mPoolList[type])  	{ -		mPoolList[type] = new LLPrivateMemoryPool(type) ; +		mPoolList[type] = new LLPrivateMemoryPool(type, mMaxPrivatePoolSize) ;  	}  	return mPoolList[type] ; diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index db753f0d8b..6967edd7e7 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -122,7 +122,7 @@ public:  	static void initMaxHeapSizeGB(F32 max_heap_size_gb, BOOL prevent_heap_failure);  	static void updateMemoryInfo() ;  	static void logMemoryInfo(BOOL update = FALSE); -	static S32  isMemoryPoolLow(); +	static bool isMemoryPoolLow();  	static U32 getAvailableMemKB() ;  	static U32 getMaxMemKB() ; @@ -303,7 +303,7 @@ public:  	} ;  private: -	LLPrivateMemoryPool(S32 type) ; +	LLPrivateMemoryPool(S32 type, U32 max_pool_size) ;  	~LLPrivateMemoryPool() ;  	char *allocate(U32 size) ; @@ -320,7 +320,7 @@ private:  	void unlock() ;	  	S32 getChunkIndex(U32 size) ;  	LLMemoryChunk*  addChunk(S32 chunk_index) ; -	void checkSize(U32 asked_size) ; +	bool checkSize(U32 asked_size) ;  	void removeChunk(LLMemoryChunk* chunk) ;  	U16  findHashKey(const char* addr);  	void addToHashTable(LLMemoryChunk* chunk) ; @@ -383,12 +383,12 @@ private:  class LL_COMMON_API LLPrivateMemoryPoolManager  {  private: -	LLPrivateMemoryPoolManager(BOOL enabled) ; +	LLPrivateMemoryPoolManager(BOOL enabled, U32 max_pool_size) ;  	~LLPrivateMemoryPoolManager() ;  public:	  	static LLPrivateMemoryPoolManager* getInstance() ; -	static void initClass(BOOL enabled) ; +	static void initClass(BOOL enabled, U32 pool_size) ;  	static void destroyClass() ;  	LLPrivateMemoryPool* newPool(S32 type) ; @@ -398,6 +398,7 @@ private:  	static LLPrivateMemoryPoolManager* sInstance ;  	std::vector<LLPrivateMemoryPool*> mPoolList ;  	BOOL mPrivatePoolEnabled; +	U32  mMaxPrivatePoolSize;  public:  	//debug and statistics info. | 
