diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llcommon/llmemory.cpp | 95 | ||||
| -rw-r--r-- | indra/llcommon/llmemory.h | 11 | ||||
| -rw-r--r-- | indra/newview/app_settings/settings.xml | 11 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 58 | ||||
| -rw-r--r-- | indra/newview/llviewerdisplay.cpp | 2 | 
5 files changed, 101 insertions, 76 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. diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index be4ec93946..15f1bbd1b1 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -5657,6 +5657,17 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>MemoryPrivatePoolSize</key> +    <map> +      <key>Comment</key> +      <string>Size of the private memory pool in MB (min. value is 256)</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>U32</string> +      <key>Value</key> +      <integer>512</integer> +    </map>      <key>MemProfiling</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 11e2e1e607..a4640f5504 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -724,7 +724,7 @@ bool LLAppViewer::init()  	//set the max heap size.  	initMaxHeapSize() ; -	LLPrivateMemoryPoolManager::initClass((BOOL)gSavedSettings.getBOOL("MemoryPrivatePoolEnabled")) ; +	LLPrivateMemoryPoolManager::initClass((BOOL)gSavedSettings.getBOOL("MemoryPrivatePoolEnabled"), (U32)gSavedSettings.getU32("MemoryPrivatePoolSize")) ;  	// write Google Breakpad minidump files to our log directory  	std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); @@ -1124,63 +1124,25 @@ void LLAppViewer::checkMemory()  {  	const static F32 MEMORY_CHECK_INTERVAL = 1.0f ; //second  	//const static F32 MAX_QUIT_WAIT_TIME = 30.0f ; //seconds -	const static U32 MAX_SIZE_CHECKED_MEMORY_BLOCK = 64 * 1024 * 1024 ; //64 MB -	//static F32 force_quit_timer = MAX_QUIT_WAIT_TIME + MEMORY_CHECK_INTERVAL ; -	static void* last_reserved_address = NULL ; +	//static F32 force_quit_timer = MAX_QUIT_WAIT_TIME + MEMORY_CHECK_INTERVAL ;	 -	if(MEMORY_CHECK_INTERVAL > mMemCheckTimer.getElapsedTimeF32()) +	if(!gGLManager.mDebugGPU)  	{  		return ;  	} -	mMemCheckTimer.reset() ; - -	if(gGLManager.mDebugGPU) -	{ -		//update the availability of memory -		LLMemory::updateMemoryInfo() ; -	} -	//check the virtual address space fragmentation -	if(!last_reserved_address) -	{ -		last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ; -	} -	else +	if(MEMORY_CHECK_INTERVAL > mMemCheckTimer.getElapsedTimeF32())  	{ -		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) ; -		} +		return ;  	} +	mMemCheckTimer.reset() ; -	S32 is_low = !last_reserved_address || LLMemory::isMemoryPoolLow() ; - -	//if(is_low < 0) //to force quit -	//{ -	//	if(force_quit_timer > MAX_QUIT_WAIT_TIME) //just hit the limit for the first time -	//	{ -	//		//send out the notification to tell the viewer is about to quit in 30 seconds. -	//		LLNotification::Params params("ForceQuitDueToLowMemory"); -	//		LLNotifications::instance().add(params); +	//update the availability of memory +	LLMemory::updateMemoryInfo() ; -	//		force_quit_timer = MAX_QUIT_WAIT_TIME - MEMORY_CHECK_INTERVAL ; -	//	} -	//	else -	//	{ -	//		force_quit_timer -= MEMORY_CHECK_INTERVAL ; -	//		if(force_quit_timer < 0.f) -	//		{ -	//			forceQuit() ; //quit -	//		} -	//	} -	//} -	//else -	//{ -	//	force_quit_timer = MAX_QUIT_WAIT_TIME + MEMORY_CHECK_INTERVAL ; -	//} +	bool is_low = LLMemory::isMemoryPoolLow() ; -	LLPipeline::throttleNewMemoryAllocation(!is_low ? FALSE : TRUE) ;		 +	LLPipeline::throttleNewMemoryAllocation(is_low) ;		  	if(is_low)  	{ diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 6142ee0dd6..19326c4e30 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -202,7 +202,7 @@ void display_stats()  		gMemoryAllocated = LLMemory::getCurrentRSS();  		U32 memory = (U32)(gMemoryAllocated / (1024*1024));  		llinfos << llformat("MEMORY: %d MB", memory) << llendl; -		LLMemory::logMemoryInfo() ; +		LLMemory::logMemoryInfo(TRUE) ;  		gRecentMemoryTime.reset();  	}  } | 
