diff options
Diffstat (limited to 'indra/llcommon')
| -rw-r--r-- | indra/llcommon/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | indra/llcommon/llallocator.cpp | 33 | ||||
| -rw-r--r-- | indra/llcommon/llallocator.h | 6 | ||||
| -rw-r--r-- | indra/llcommon/llfasttimer.cpp (renamed from indra/llcommon/llfasttimer_class.cpp) | 349 | ||||
| -rw-r--r-- | indra/llcommon/llfasttimer.h | 362 | ||||
| -rw-r--r-- | indra/llcommon/llfasttimer_class.h | 276 | ||||
| -rw-r--r-- | indra/llcommon/llinitparam.h | 200 | ||||
| -rw-r--r-- | indra/llcommon/llmemory.h | 4 | ||||
| -rw-r--r-- | indra/llcommon/llmemtype.cpp | 232 | ||||
| -rw-r--r-- | indra/llcommon/llmemtype.h | 242 | ||||
| -rw-r--r-- | indra/llcommon/llstat.cpp | 1031 | ||||
| -rw-r--r-- | indra/llcommon/llstat.h | 283 | ||||
| -rw-r--r-- | indra/llcommon/lluuid.cpp | 37 | ||||
| -rw-r--r-- | indra/llcommon/lluuid.h | 3 | ||||
| -rw-r--r-- | indra/llcommon/llversionviewer.h | 41 | 
15 files changed, 636 insertions, 2469 deletions
| diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 66e2bc9095..f3afd9c1a9 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -53,7 +53,7 @@ set(llcommon_SOURCE_FILES      lleventfilter.cpp      llevents.cpp      lleventtimer.cpp -    llfasttimer_class.cpp +    llfasttimer.cpp      llfile.cpp      llfindlocale.cpp      llfixedbuffer.cpp @@ -71,7 +71,6 @@ set(llcommon_SOURCE_FILES      llmd5.cpp      llmemory.cpp      llmemorystream.cpp -    llmemtype.cpp      llmetrics.cpp      llmetricperformancetester.cpp      llmortician.cpp @@ -168,7 +167,6 @@ set(llcommon_HEADER_FILES      lleventemitter.h      llextendedstatus.h      llfasttimer.h -    llfasttimer_class.h      llfile.h      llfindlocale.h      llfixedbuffer.h @@ -197,7 +195,6 @@ set(llcommon_HEADER_FILES      llmd5.h      llmemory.h      llmemorystream.h -    llmemtype.h      llmetrics.h      llmetricperformancetester.h      llmortician.h @@ -249,7 +246,6 @@ set(llcommon_HEADER_FILES      lluuid.h      lluuidhashmap.h      llversionserver.h -    llversionviewer.h      llworkerthread.h      ll_template_cast.h      metaclass.h diff --git a/indra/llcommon/llallocator.cpp b/indra/llcommon/llallocator.cpp index 87654b5b97..34fc28d8cc 100644 --- a/indra/llcommon/llallocator.cpp +++ b/indra/llcommon/llallocator.cpp @@ -35,28 +35,6 @@  DECLARE_bool(heap_profile_use_stack_trace);  //DECLARE_double(tcmalloc_release_rate); -// static -void LLAllocator::pushMemType(S32 type) -{ -    if(isProfiling()) -    { -    	PushMemType(type); -    } -} - -// static -S32 LLAllocator::popMemType() -{ -    if (isProfiling()) -    { -    	return PopMemType(); -    } -    else -    { -        return -1; -    } -} -  void LLAllocator::setProfilingEnabled(bool should_enable)  {      // NULL disables dumping to disk @@ -94,17 +72,6 @@ std::string LLAllocator::getRawProfile()  // stub implementations for when tcmalloc is disabled  // -// static -void LLAllocator::pushMemType(S32 type) -{ -} - -// static -S32 LLAllocator::popMemType() -{ -    return -1; -} -  void LLAllocator::setProfilingEnabled(bool should_enable)  {  } diff --git a/indra/llcommon/llallocator.h b/indra/llcommon/llallocator.h index a91dd57d14..d26ad73c5b 100644 --- a/indra/llcommon/llallocator.h +++ b/indra/llcommon/llallocator.h @@ -29,16 +29,10 @@  #include <string> -#include "llmemtype.h"  #include "llallocator_heap_profile.h"  class LL_COMMON_API LLAllocator {      friend class LLMemoryView; -    friend class LLMemType; - -private: -	static void pushMemType(S32 type); -	static S32 popMemType();  public:      void setProfilingEnabled(bool should_enable); diff --git a/indra/llcommon/llfasttimer_class.cpp b/indra/llcommon/llfasttimer.cpp index 463f558c2c..6970c29092 100644 --- a/indra/llcommon/llfasttimer_class.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -1,5 +1,5 @@  /**  - * @file llfasttimer_class.cpp + * @file llfasttimer.cpp   * @brief Implementation of the fast timer.   *   * $LicenseInfo:firstyear=2004&license=viewerlgpl$ @@ -64,19 +64,12 @@ BOOL LLFastTimer::sMetricLog = FALSE;  LLMutex* LLFastTimer::sLogLock = NULL;  std::queue<LLSD> LLFastTimer::sLogQueue; -#define USE_RDTSC 0 -  #if LL_LINUX || LL_SOLARIS  U64 LLFastTimer::sClockResolution = 1000000000; // Nanosecond resolution  #else  U64 LLFastTimer::sClockResolution = 1000000; // Microsecond resolution  #endif -std::vector<LLFastTimer::FrameState>* LLFastTimer::sTimerInfos = NULL; -U64				LLFastTimer::sTimerCycles = 0; -U32				LLFastTimer::sTimerCalls = 0; - -  // FIXME: move these declarations to the relevant modules  // helper functions @@ -109,52 +102,35 @@ static timer_tree_dfs_iterator_t end_timer_tree()  	return timer_tree_dfs_iterator_t();   } - -  // factory class that creates NamedTimers via static DeclareTimer objects  class NamedTimerFactory : public LLSingleton<NamedTimerFactory>  {  public:  	NamedTimerFactory() -		: mActiveTimerRoot(NULL), -		  mTimerRoot(NULL), -		  mAppTimer(NULL), -		  mRootFrameState(NULL) +	:	mTimerRoot(NULL)  	{}  	/*virtual */ void initSingleton()  	{  		mTimerRoot = new LLFastTimer::NamedTimer("root"); - -		mActiveTimerRoot = new LLFastTimer::NamedTimer("Frame"); -		mActiveTimerRoot->setCollapsed(false); - -		mRootFrameState = new LLFastTimer::FrameState(mActiveTimerRoot); -		mRootFrameState->mParent = &mTimerRoot->getFrameState(); -		mActiveTimerRoot->setParent(mTimerRoot); - -		mAppTimer = new LLFastTimer(mRootFrameState); +		mRootFrameState.setNamedTimer(mTimerRoot); +		mTimerRoot->setFrameState(&mRootFrameState); +		mTimerRoot->mParent = mTimerRoot; +		mTimerRoot->setCollapsed(false); +		mRootFrameState.mParent = &mRootFrameState;  	}  	~NamedTimerFactory()  	{  		std::for_each(mTimers.begin(), mTimers.end(), DeletePairedPointer()); -		delete mAppTimer; -		delete mActiveTimerRoot;   		delete mTimerRoot; -		delete mRootFrameState;  	} -	LLFastTimer::NamedTimer& createNamedTimer(const std::string& name) +	LLFastTimer::NamedTimer& createNamedTimer(const std::string& name, LLFastTimer::FrameState* state)  	{ -		timer_map_t::iterator found_it = mTimers.find(name); -		if (found_it != mTimers.end()) -		{ -			return *found_it->second; -		} -  		LLFastTimer::NamedTimer* timer = new LLFastTimer::NamedTimer(name); +		timer->setFrameState(state);  		timer->setParent(mTimerRoot);  		mTimers.insert(std::make_pair(name, timer)); @@ -171,12 +147,9 @@ public:  		return NULL;  	} -	LLFastTimer::NamedTimer* getActiveRootTimer() { return mActiveTimerRoot; }  	LLFastTimer::NamedTimer* getRootTimer() { return mTimerRoot; } -	const LLFastTimer* getAppTimer() { return mAppTimer; } -	LLFastTimer::FrameState& getRootFrameState() { return *mRootFrameState; } -	typedef std::map<std::string, LLFastTimer::NamedTimer*> timer_map_t; +	typedef std::multimap<std::string, LLFastTimer::NamedTimer*> timer_map_t;  	timer_map_t::iterator beginTimers() { return mTimers.begin(); }  	timer_map_t::iterator endTimers() { return mTimers.end(); }  	S32 timerCount() { return mTimers.size(); } @@ -184,55 +157,19 @@ public:  private:  	timer_map_t mTimers; -	LLFastTimer::NamedTimer*		mActiveTimerRoot;  	LLFastTimer::NamedTimer*		mTimerRoot; -	LLFastTimer*						mAppTimer; -	LLFastTimer::FrameState*		mRootFrameState; +	LLFastTimer::FrameState			mRootFrameState;  }; -void update_cached_pointers_if_changed() -{ -	// detect when elements have moved and update cached pointers -	static LLFastTimer::FrameState* sFirstTimerAddress = NULL; -	if (&*(LLFastTimer::getFrameStateList().begin()) != sFirstTimerAddress) -	{ -		LLFastTimer::DeclareTimer::updateCachedPointers(); -	} -	sFirstTimerAddress = &*(LLFastTimer::getFrameStateList().begin()); -} -  LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name, bool open ) -:	mTimer(NamedTimerFactory::instance().createNamedTimer(name)) +:	mTimer(NamedTimerFactory::instance().createNamedTimer(name, &mFrameState))  {  	mTimer.setCollapsed(!open); -	mFrameState = &mTimer.getFrameState(); -	update_cached_pointers_if_changed();  }  LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name) -:	mTimer(NamedTimerFactory::instance().createNamedTimer(name)) -{ -	mFrameState = &mTimer.getFrameState(); -	update_cached_pointers_if_changed(); -} - -// static -void LLFastTimer::DeclareTimer::updateCachedPointers() +:	mTimer(NamedTimerFactory::instance().createNamedTimer(name, &mFrameState))  { -	// propagate frame state pointers to timer declarations -	for (instance_iter it = beginInstances(); it != endInstances(); ++it) -	{ -		// update cached pointer -		it->mFrameState = &it->mTimer.getFrameState(); -	} - -	// also update frame states of timers on stack -	LLFastTimer* cur_timerp = LLFastTimer::sCurTimerData.mCurTimer; -	while(cur_timerp->mLastTimerData.mCurTimer != cur_timerp)	 -	{ -		cur_timerp->mFrameState = &cur_timerp->mFrameState->mTimer->getFrameState(); -		cur_timerp = cur_timerp->mLastTimerData.mCurTimer; -	}  }  //static @@ -244,7 +181,7 @@ U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer  #else // windows or x86-mac or x86-linux or x86-solaris  U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer  { -#if USE_RDTSC || !LL_WINDOWS +#if LL_FASTTIMER_USE_RDTSC || !LL_WINDOWS  	//getCPUFrequency returns MHz and sCPUClockFrequency wants to be in Hz  	static U64 sCPUClockFrequency = U64(LLProcessorInfo().getCPUFrequency()*1000000.0); @@ -265,14 +202,13 @@ U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer  }  #endif -LLFastTimer::FrameState::FrameState(LLFastTimer::NamedTimer* timerp) +LLFastTimer::FrameState::FrameState()  :	mActiveCount(0),  	mCalls(0),  	mSelfTimeCounter(0),  	mParent(NULL),  	mLastCaller(NULL), -	mMoveUpTree(false), -	mTimer(timerp) +	mMoveUpTree(false)  {} @@ -283,12 +219,9 @@ LLFastTimer::NamedTimer::NamedTimer(const std::string& name)  	mTotalTimeCounter(0),  	mCountAverage(0),  	mCallAverage(0), -	mNeedsSorting(false) +	mNeedsSorting(false), +	mFrameState(NULL)  { -	info_list_t& frame_state_list = getFrameStateList(); -	mFrameStateIndex = frame_state_list.size(); -	getFrameStateList().push_back(FrameState(this)); -  	mCountHistory = new U32[HISTORY_NUM];  	memset(mCountHistory, 0, sizeof(U32) * HISTORY_NUM);  	mCallHistory = new U32[HISTORY_NUM]; @@ -355,6 +288,7 @@ S32 LLFastTimer::NamedTimer::getDepth()  	while(timerp)  	{  		depth++; +		if (timerp->getParent() == timerp) break;  		timerp = timerp->mParent;  	}  	return depth; @@ -369,15 +303,6 @@ void LLFastTimer::NamedTimer::processTimes()  	accumulateTimings();  } -// sort timer info structs by depth first traversal order -struct SortTimersDFS -{ -	bool operator()(const LLFastTimer::FrameState& i1, const LLFastTimer::FrameState& i2) -	{ -		return i1.mTimer->getFrameStateIndex() < i2.mTimer->getFrameStateIndex(); -	} -}; -  // sort child timers by name  struct SortTimerByName  { @@ -425,8 +350,8 @@ void LLFastTimer::NamedTimer::buildHierarchy()  		{  			// since ancestors have already been visited, reparenting won't affect tree traversal  			//step up tree, bringing our descendants with us -			//llinfos << "Moving " << timerp->getName() << " from child of " << timerp->getParent()->getName() << -			//	" to child of " << timerp->getParent()->getParent()->getName() << llendl; +			LL_DEBUGS("FastTimers") << "Moving " << timerp->getName() << " from child of " << timerp->getParent()->getName() << +				" to child of " << timerp->getParent()->getParent()->getName() << LL_ENDL;  			timerp->setParent(timerp->getParent()->getParent());  			timerp->getFrameState().mMoveUpTree = false; @@ -458,7 +383,7 @@ void LLFastTimer::NamedTimer::accumulateTimings()  	LLFastTimer* cur_timer = sCurTimerData.mCurTimer;  	// root defined by parent pointing to self  	CurTimerData* cur_data = &sCurTimerData; -	while(cur_timer->mLastTimerData.mCurTimer != cur_timer) +	while(cur_timer && cur_timer->mLastTimerData.mCurTimer != cur_timer)  	{  		U32 cumulative_time_delta = cur_time - cur_timer->mStartTime;  		U32 self_time_delta = cumulative_time_delta - cur_data->mChildTime; @@ -473,7 +398,7 @@ void LLFastTimer::NamedTimer::accumulateTimings()  	}  	// traverse tree in DFS post order, or bottom up -	for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getActiveRootTimer()); +	for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getRootTimer());  		it != end_timer_tree_bottom_up();  		++it)  	{ @@ -507,12 +432,12 @@ void LLFastTimer::NamedTimer::resetFrame()  		static S32 call_count = 0;  		if (call_count % 100 == 0)  		{ -			llinfos << "countsPerSecond (32 bit): " << countsPerSecond() << llendl; -			llinfos << "get_clock_count (64 bit): " << get_clock_count() << llendl; -			llinfos << "LLProcessorInfo().getCPUFrequency() " << LLProcessorInfo().getCPUFrequency() << llendl; -			llinfos << "getCPUClockCount32() " << getCPUClockCount32() << llendl; -			llinfos << "getCPUClockCount64() " << getCPUClockCount64() << llendl; -			llinfos << "elapsed sec " << ((F64)getCPUClockCount64())/((F64)LLProcessorInfo().getCPUFrequency()*1000000.0) << llendl; +			LL_DEBUGS("FastTimers") << "countsPerSecond (32 bit): " << countsPerSecond() << LL_ENDL; +			LL_DEBUGS("FastTimers") << "get_clock_count (64 bit): " << get_clock_count() << llendl; +			LL_DEBUGS("FastTimers") << "LLProcessorInfo().getCPUFrequency() " << LLProcessorInfo().getCPUFrequency() << LL_ENDL; +			LL_DEBUGS("FastTimers") << "getCPUClockCount32() " << getCPUClockCount32() << LL_ENDL; +			LL_DEBUGS("FastTimers") << "getCPUClockCount64() " << getCPUClockCount64() << LL_ENDL; +			LL_DEBUGS("FastTimers") << "elapsed sec " << ((F64)getCPUClockCount64())/((F64)LLProcessorInfo().getCPUFrequency()*1000000.0) << LL_ENDL;  		}  		call_count++; @@ -544,48 +469,22 @@ void LLFastTimer::NamedTimer::resetFrame()  		}  	} - -	// tag timers by position in depth first traversal of tree -	S32 index = 0; -	for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer()); -		it != end_timer_tree(); -		++it) -	{ -		NamedTimer* timerp = (*it); -		 -		timerp->mFrameStateIndex = index; -		index++; - -		llassert_always(timerp->mFrameStateIndex < (S32)getFrameStateList().size()); -	} - -	// sort timers by DFS traversal order to improve cache coherency -	std::sort(getFrameStateList().begin(), getFrameStateList().end(), SortTimersDFS()); - -	// update pointers into framestatelist now that we've sorted it -	DeclareTimer::updateCachedPointers(); -  	// reset for next frame +	for (instance_iter it = beginInstances(); it != endInstances(); ++it)  	{ -		for (instance_iter it = beginInstances(); it != endInstances(); ++it) -		{ -			NamedTimer& timer = *it; +		NamedTimer& timer = *it; -			FrameState& info = timer.getFrameState(); -			info.mSelfTimeCounter = 0; -			info.mCalls = 0; -			info.mLastCaller = NULL; -			info.mMoveUpTree = false; -			// update parent pointer in timer state struct -			if (timer.mParent) -			{ -				info.mParent = &timer.mParent->getFrameState(); -			} +		FrameState& info = timer.getFrameState(); +		info.mSelfTimeCounter = 0; +		info.mCalls = 0; +		info.mLastCaller = NULL; +		info.mMoveUpTree = false; +		// update parent pointer in timer state struct +		if (timer.mParent) +		{ +			info.mParent = &timer.mParent->getFrameState();  		}  	} - -	//sTimerCycles = 0; -	//sTimerCalls = 0;  }  //static @@ -600,7 +499,7 @@ void LLFastTimer::NamedTimer::reset()  	// root defined by parent pointing to self  	CurTimerData* cur_data = &sCurTimerData;  	LLFastTimer* cur_timer = cur_data->mCurTimer; -	while(cur_timer->mLastTimerData.mCurTimer != cur_timer) +	while(cur_timer && cur_timer->mLastTimerData.mCurTimer != cur_timer)  	{  		cur_timer->mStartTime = cur_time;  		cur_data->mChildTime = 0; @@ -630,17 +529,6 @@ void LLFastTimer::NamedTimer::reset()  	sCurFrameIndex = 0;  } -//static  -LLFastTimer::info_list_t& LLFastTimer::getFrameStateList()  -{  -	if (!sTimerInfos)  -	{  -		sTimerInfos = new info_list_t();  -	}  -	return *sTimerInfos;  -} - -  U32 LLFastTimer::NamedTimer::getHistoricalCount(S32 history_index) const  {  	S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::NamedTimer::HISTORY_NUM; @@ -655,18 +543,7 @@ U32 LLFastTimer::NamedTimer::getHistoricalCalls(S32 history_index ) const  LLFastTimer::FrameState& LLFastTimer::NamedTimer::getFrameState() const  { -	llassert_always(mFrameStateIndex >= 0); -	if (this == NamedTimerFactory::instance().getActiveRootTimer())  -	{ -		return NamedTimerFactory::instance().getRootFrameState(); -	} -	return getFrameStateList()[mFrameStateIndex]; -} - -// static -LLFastTimer::NamedTimer& LLFastTimer::NamedTimer::getRootNamedTimer() -{  -	return *NamedTimerFactory::instance().getActiveRootTimer();  +	return *mFrameState;  }  std::vector<LLFastTimer::NamedTimer*>::const_iterator LLFastTimer::NamedTimer::beginChildren() @@ -777,145 +654,3 @@ LLFastTimer::LLFastTimer(LLFastTimer::FrameState* state)  } -////////////////////////////////////////////////////////////////////////////// -// -// Important note: These implementations must be FAST! -// - - -#if LL_WINDOWS -// -// Windows implementation of CPU clock -// - -// -// NOTE: put back in when we aren't using platform sdk anymore -// -// because MS has different signatures for these functions in winnt.h -// need to rename them to avoid conflicts -//#define _interlockedbittestandset _renamed_interlockedbittestandset -//#define _interlockedbittestandreset _renamed_interlockedbittestandreset -//#include <intrin.h> -//#undef _interlockedbittestandset -//#undef _interlockedbittestandreset - -//inline U32 LLFastTimer::getCPUClockCount32() -//{ -//	U64 time_stamp = __rdtsc(); -//	return (U32)(time_stamp >> 8); -//} -// -//// return full timer value, *not* shifted by 8 bits -//inline U64 LLFastTimer::getCPUClockCount64() -//{ -//	return __rdtsc(); -//} - -// shift off lower 8 bits for lower resolution but longer term timing -// on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing -#if USE_RDTSC -U32 LLFastTimer::getCPUClockCount32() -{ -	U32 ret_val; -	__asm -	{ -        _emit   0x0f -        _emit   0x31 -		shr eax,8 -		shl edx,24 -		or eax, edx -		mov dword ptr [ret_val], eax -	} -    return ret_val; -} - -// return full timer value, *not* shifted by 8 bits -U64 LLFastTimer::getCPUClockCount64() -{ -	U64 ret_val; -	__asm -	{ -        _emit   0x0f -        _emit   0x31 -		mov eax,eax -		mov edx,edx -		mov dword ptr [ret_val+4], edx -		mov dword ptr [ret_val], eax -	} -    return ret_val; -} - -std::string LLFastTimer::sClockType = "rdtsc"; - -#else -//LL_COMMON_API U64 get_clock_count(); // in lltimer.cpp -// These use QueryPerformanceCounter, which is arguably fine and also works on AMD architectures. -U32 LLFastTimer::getCPUClockCount32() -{ -	return (U32)(get_clock_count()>>8); -} - -U64 LLFastTimer::getCPUClockCount64() -{ -	return get_clock_count(); -} - -std::string LLFastTimer::sClockType = "QueryPerformanceCounter"; -#endif - -#endif - - -#if (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__)) -// -// Linux and Solaris implementation of CPU clock - non-x86. -// This is accurate but SLOW!  Only use out of desperation. -// -// Try to use the MONOTONIC clock if available, this is a constant time counter -// with nanosecond resolution (but not necessarily accuracy) and attempts are -// made to synchronize this value between cores at kernel start. It should not -// be affected by CPU frequency. If not available use the REALTIME clock, but -// this may be affected by NTP adjustments or other user activity affecting -// the system time. -U64 LLFastTimer::getCPUClockCount64() -{ -	struct timespec tp; -	 -#ifdef CLOCK_MONOTONIC // MONOTONIC supported at build-time? -	if (-1 == clock_gettime(CLOCK_MONOTONIC,&tp)) // if MONOTONIC isn't supported at runtime then ouch, try REALTIME -#endif -		clock_gettime(CLOCK_REALTIME,&tp); - -	return (tp.tv_sec*LLFastTimer::sClockResolution)+tp.tv_nsec;         -} - -U32 LLFastTimer::getCPUClockCount32() -{ -	return (U32)(LLFastTimer::getCPUClockCount64() >> 8); -} - -std::string LLFastTimer::sClockType = "clock_gettime"; - -#endif // (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__)) - - -#if (LL_LINUX || LL_SOLARIS || LL_DARWIN) && (defined(__i386__) || defined(__amd64__)) -// -// Mac+Linux+Solaris FAST x86 implementation of CPU clock -U32 LLFastTimer::getCPUClockCount32() -{ -	U64 x; -	__asm__ volatile (".byte 0x0f, 0x31": "=A"(x)); -	return (U32)(x >> 8); -} - -U64 LLFastTimer::getCPUClockCount64() -{ -	U64 x; -	__asm__ volatile (".byte 0x0f, 0x31": "=A"(x)); -	return x; -} - -std::string LLFastTimer::sClockType = "rdtsc"; -#endif - diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 2b25f2fabb..e42e549df5 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -1,6 +1,6 @@  /**   * @file llfasttimer.h - * @brief Inline implementations of fast timers. + * @brief Declaration of a fast timer.   *   * $LicenseInfo:firstyear=2004&license=viewerlgpl$   * Second Life Viewer Source Code @@ -27,9 +27,363 @@  #ifndef LL_FASTTIMER_H  #define LL_FASTTIMER_H -// Implementation of getCPUClockCount32() and getCPUClockCount64 are now in llfastertimer_class.cpp. +#include "llinstancetracker.h" -// pull in the actual class definition -#include "llfasttimer_class.h" +#define FAST_TIMER_ON 1 +#define DEBUG_FAST_TIMER_THREADS 1 + +class LLMutex; + +#include <queue> +#include "llsd.h" + +#define LL_FASTTIMER_USE_RDTSC 1 + + +LL_COMMON_API void assert_main_thread(); + +class LL_COMMON_API LLFastTimer +{ +public: +	class NamedTimer; + +	struct LL_COMMON_API FrameState +	{ +		FrameState(); +		void setNamedTimer(NamedTimer* timerp) { mTimer = timerp; } + +		U32 				mSelfTimeCounter; +		U32 				mCalls; +		FrameState*			mParent;		// info for caller timer +		FrameState*			mLastCaller;	// used to bootstrap tree construction +		NamedTimer*			mTimer; +		U16					mActiveCount;	// number of timers with this ID active on stack +		bool				mMoveUpTree;	// needs to be moved up the tree of timers at the end of frame +	}; + +	// stores a "named" timer instance to be reused via multiple LLFastTimer stack instances +	class LL_COMMON_API NamedTimer +	:	public LLInstanceTracker<NamedTimer> +	{ +		friend class DeclareTimer; +	public: +		~NamedTimer(); + +		enum { HISTORY_NUM = 300 }; + +		const std::string& getName() const { return mName; } +		NamedTimer* getParent() const { return mParent; } +		void setParent(NamedTimer* parent); +		S32 getDepth(); +		std::string getToolTip(S32 history_index = -1); + +		typedef std::vector<NamedTimer*>::const_iterator child_const_iter; +		child_const_iter beginChildren(); +		child_const_iter endChildren(); +		std::vector<NamedTimer*>& getChildren(); + +		void setCollapsed(bool collapsed) { mCollapsed = collapsed; } +		bool getCollapsed() const { return mCollapsed; } + +		U32 getCountAverage() const { return mCountAverage; } +		U32 getCallAverage() const { return mCallAverage; } + +		U32 getHistoricalCount(S32 history_index = 0) const; +		U32 getHistoricalCalls(S32 history_index = 0) const; + +		void setFrameState(FrameState* state) { mFrameState = state; state->setNamedTimer(this); } +		FrameState& getFrameState() const; + +	private: +		friend class LLFastTimer; +		friend class NamedTimerFactory; + +		// +		// methods +		// +		NamedTimer(const std::string& name); +		// recursive call to gather total time from children +		static void accumulateTimings(); + +		// updates cumulative times and hierarchy, +		// can be called multiple times in a frame, at any point +		static void processTimes(); + +		static void buildHierarchy(); +		static void resetFrame(); +		static void reset(); + +		// +		// members +		// +		FrameState*		mFrameState; + +		std::string	mName; + +		U32 		mTotalTimeCounter; + +		U32 		mCountAverage; +		U32			mCallAverage; + +		U32*		mCountHistory; +		U32*		mCallHistory; + +		// tree structure +		NamedTimer*					mParent;				// NamedTimer of caller(parent) +		std::vector<NamedTimer*>	mChildren; +		bool						mCollapsed;				// don't show children +		bool						mNeedsSorting;			// sort children whenever child added +	}; + +	// used to statically declare a new named timer +	class LL_COMMON_API DeclareTimer +	:	public LLInstanceTracker<DeclareTimer> +	{ +		friend class LLFastTimer; +	public: +		DeclareTimer(const std::string& name, bool open); +		DeclareTimer(const std::string& name); + +		NamedTimer& getNamedTimer() { return mTimer; } + +	private: +		FrameState		mFrameState; +		NamedTimer&		mTimer; +	}; + +public: +	LLFastTimer(LLFastTimer::FrameState* state); + +	LL_FORCE_INLINE LLFastTimer(LLFastTimer::DeclareTimer& timer) +	:	mFrameState(&timer.mFrameState) +	{ +#if FAST_TIMER_ON +		LLFastTimer::FrameState* frame_state = mFrameState; +		mStartTime = getCPUClockCount32(); + +		frame_state->mActiveCount++; +		frame_state->mCalls++; +		// keep current parent as long as it is active when we are +		frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0); + +		LLFastTimer::CurTimerData* cur_timer_data = &LLFastTimer::sCurTimerData; +		mLastTimerData = *cur_timer_data; +		cur_timer_data->mCurTimer = this; +		cur_timer_data->mFrameState = frame_state; +		cur_timer_data->mChildTime = 0; +#endif +#if DEBUG_FAST_TIMER_THREADS +#if !LL_RELEASE +		assert_main_thread(); +#endif +#endif +	} + +	LL_FORCE_INLINE ~LLFastTimer() +	{ +#if FAST_TIMER_ON +		LLFastTimer::FrameState* frame_state = mFrameState; +		U32 total_time = getCPUClockCount32() - mStartTime; + +		frame_state->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime; +		frame_state->mActiveCount--; + +		// store last caller to bootstrap tree creation +		// do this in the destructor in case of recursion to get topmost caller +		frame_state->mLastCaller = mLastTimerData.mFrameState; + +		// we are only tracking self time, so subtract our total time delta from parents +		mLastTimerData.mChildTime += total_time; + +		LLFastTimer::sCurTimerData = mLastTimerData; +#endif +	} + +public: +	static LLMutex*			sLogLock; +	static std::queue<LLSD> sLogQueue; +	static BOOL				sLog; +	static BOOL				sMetricLog; +	static std::string		sLogName; +	static bool 			sPauseHistory; +	static bool 			sResetHistory; + +	// call this once a frame to reset timers +	static void nextFrame(); + +	// dumps current cumulative frame stats to log +	// call nextFrame() to reset timers +	static void dumpCurTimes(); + +	// call this to reset timer hierarchy, averages, etc. +	static void reset(); + +	static U64 countsPerSecond(); +	static S32 getLastFrameIndex() { return sLastFrameIndex; } +	static S32 getCurFrameIndex() { return sCurFrameIndex; } + +	static void writeLog(std::ostream& os); +	static const NamedTimer* getTimerByName(const std::string& name); + +	struct CurTimerData +	{ +		LLFastTimer*	mCurTimer; +		FrameState*		mFrameState; +		U32				mChildTime; +	}; +	static CurTimerData		sCurTimerData; + +private: + + +	////////////////////////////////////////////////////////////////////////////// +	// +	// Important note: These implementations must be FAST! +	// + + +#if LL_WINDOWS +	// +	// Windows implementation of CPU clock +	// + +	// +	// NOTE: put back in when we aren't using platform sdk anymore +	// +	// because MS has different signatures for these functions in winnt.h +	// need to rename them to avoid conflicts +	//#define _interlockedbittestandset _renamed_interlockedbittestandset +	//#define _interlockedbittestandreset _renamed_interlockedbittestandreset +	//#include <intrin.h> +	//#undef _interlockedbittestandset +	//#undef _interlockedbittestandreset + +	//inline U32 LLFastTimer::getCPUClockCount32() +	//{ +	//	U64 time_stamp = __rdtsc(); +	//	return (U32)(time_stamp >> 8); +	//} +	// +	//// return full timer value, *not* shifted by 8 bits +	//inline U64 LLFastTimer::getCPUClockCount64() +	//{ +	//	return __rdtsc(); +	//} + +	// shift off lower 8 bits for lower resolution but longer term timing +	// on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing +#if LL_FASTTIMER_USE_RDTSC +	static U32 getCPUClockCount32() +	{ +		U32 ret_val; +		__asm +		{ +			_emit   0x0f +				_emit   0x31 +				shr eax,8 +				shl edx,24 +				or eax, edx +				mov dword ptr [ret_val], eax +		} +		return ret_val; +	} + +	// return full timer value, *not* shifted by 8 bits +	static U64 getCPUClockCount64() +	{ +		U64 ret_val; +		__asm +		{ +			_emit   0x0f +				_emit   0x31 +				mov eax,eax +				mov edx,edx +				mov dword ptr [ret_val+4], edx +				mov dword ptr [ret_val], eax +		} +		return ret_val; +	} + +#else +	//LL_COMMON_API U64 get_clock_count(); // in lltimer.cpp +	// These use QueryPerformanceCounter, which is arguably fine and also works on AMD architectures. +	static U32 getCPUClockCount32() +	{ +		return (U32)(get_clock_count()>>8); +	} + +	static U64 getCPUClockCount64() +	{ +		return get_clock_count(); +	} + +#endif + +#endif + + +#if (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__)) +	// +	// Linux and Solaris implementation of CPU clock - non-x86. +	// This is accurate but SLOW!  Only use out of desperation. +	// +	// Try to use the MONOTONIC clock if available, this is a constant time counter +	// with nanosecond resolution (but not necessarily accuracy) and attempts are +	// made to synchronize this value between cores at kernel start. It should not +	// be affected by CPU frequency. If not available use the REALTIME clock, but +	// this may be affected by NTP adjustments or other user activity affecting +	// the system time. +	static U64 getCPUClockCount64() +	{ +		struct timespec tp; + +#ifdef CLOCK_MONOTONIC // MONOTONIC supported at build-time? +		if (-1 == clock_gettime(CLOCK_MONOTONIC,&tp)) // if MONOTONIC isn't supported at runtime then ouch, try REALTIME +#endif +			clock_gettime(CLOCK_REALTIME,&tp); + +		return (tp.tv_sec*sClockResolution)+tp.tv_nsec;         +	} + +	static U32 getCPUClockCount32() +	{ +		return (U32)(getCPUClockCount64() >> 8); +	} + +#endif // (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__)) + + +#if (LL_LINUX || LL_SOLARIS || LL_DARWIN) && (defined(__i386__) || defined(__amd64__)) +	// +	// Mac+Linux+Solaris FAST x86 implementation of CPU clock +	static U32 getCPUClockCount32() +	{ +		U64 x; +		__asm__ volatile (".byte 0x0f, 0x31": "=A"(x)); +		return (U32)(x >> 8); +	} + +	static U64 getCPUClockCount64() +	{ +		U64 x; +		__asm__ volatile (".byte 0x0f, 0x31": "=A"(x)); +		return x; +	} + +#endif + +	static U64 sClockResolution; + +	static S32				sCurFrameIndex; +	static S32				sLastFrameIndex; +	static U64				sLastFrameTime; + +	U32							mStartTime; +	LLFastTimer::FrameState*	mFrameState; +	LLFastTimer::CurTimerData	mLastTimerData; + +}; + +typedef class LLFastTimer LLFastTimer;  #endif // LL_LLFASTTIMER_H diff --git a/indra/llcommon/llfasttimer_class.h b/indra/llcommon/llfasttimer_class.h deleted file mode 100644 index f481e968a6..0000000000 --- a/indra/llcommon/llfasttimer_class.h +++ /dev/null @@ -1,276 +0,0 @@ -/** - * @file llfasttimer_class.h - * @brief Declaration of a fast timer. - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#ifndef LL_FASTTIMER_CLASS_H -#define LL_FASTTIMER_CLASS_H - -#include "llinstancetracker.h" - -#define FAST_TIMER_ON 1 -#define TIME_FAST_TIMERS 0 -#define DEBUG_FAST_TIMER_THREADS 1 - -class LLMutex; - -#include <queue> -#include "llsd.h" - -LL_COMMON_API void assert_main_thread(); - -class LL_COMMON_API LLFastTimer -{ -public: -	class NamedTimer; - -	struct LL_COMMON_API FrameState -	{ -		FrameState(NamedTimer* timerp); - -		U32 				mSelfTimeCounter; -		U32 				mCalls; -		FrameState*			mParent;		// info for caller timer -		FrameState*			mLastCaller;	// used to bootstrap tree construction -		NamedTimer*			mTimer; -		U16					mActiveCount;	// number of timers with this ID active on stack -		bool				mMoveUpTree;	// needs to be moved up the tree of timers at the end of frame -	}; - -	// stores a "named" timer instance to be reused via multiple LLFastTimer stack instances -	class LL_COMMON_API NamedTimer -	:	public LLInstanceTracker<NamedTimer> -	{ -		friend class DeclareTimer; -	public: -		~NamedTimer(); - -		enum { HISTORY_NUM = 300 }; - -		const std::string& getName() const { return mName; } -		NamedTimer* getParent() const { return mParent; } -		void setParent(NamedTimer* parent); -		S32 getDepth(); -		std::string getToolTip(S32 history_index = -1); - -		typedef std::vector<NamedTimer*>::const_iterator child_const_iter; -		child_const_iter beginChildren(); -		child_const_iter endChildren(); -		std::vector<NamedTimer*>& getChildren(); - -		void setCollapsed(bool collapsed) { mCollapsed = collapsed; } -		bool getCollapsed() const { return mCollapsed; } - -		U32 getCountAverage() const { return mCountAverage; } -		U32 getCallAverage() const { return mCallAverage; } - -		U32 getHistoricalCount(S32 history_index = 0) const; -		U32 getHistoricalCalls(S32 history_index = 0) const; - -		static NamedTimer& getRootNamedTimer(); - -		S32 getFrameStateIndex() const { return mFrameStateIndex; } - -		FrameState& getFrameState() const; - -	private: -		friend class LLFastTimer; -		friend class NamedTimerFactory; - -		// -		// methods -		// -		NamedTimer(const std::string& name); -		// recursive call to gather total time from children -		static void accumulateTimings(); - -		// updates cumulative times and hierarchy, -		// can be called multiple times in a frame, at any point -		static void processTimes(); - -		static void buildHierarchy(); -		static void resetFrame(); -		static void reset(); - -		// -		// members -		// -		S32			mFrameStateIndex; - -		std::string	mName; - -		U32 		mTotalTimeCounter; - -		U32 		mCountAverage; -		U32			mCallAverage; - -		U32*		mCountHistory; -		U32*		mCallHistory; - -		// tree structure -		NamedTimer*					mParent;				// NamedTimer of caller(parent) -		std::vector<NamedTimer*>	mChildren; -		bool						mCollapsed;				// don't show children -		bool						mNeedsSorting;			// sort children whenever child added -	}; - -	// used to statically declare a new named timer -	class LL_COMMON_API DeclareTimer -	:	public LLInstanceTracker<DeclareTimer> -	{ -		friend class LLFastTimer; -	public: -		DeclareTimer(const std::string& name, bool open); -		DeclareTimer(const std::string& name); - -		static void updateCachedPointers(); - -	private: -		NamedTimer&		mTimer; -		FrameState*		mFrameState; -	}; - -public: -	LLFastTimer(LLFastTimer::FrameState* state); - -	LL_FORCE_INLINE LLFastTimer(LLFastTimer::DeclareTimer& timer) -	:	mFrameState(timer.mFrameState) -	{ -#if TIME_FAST_TIMERS -		U64 timer_start = getCPUClockCount64(); -#endif -#if FAST_TIMER_ON -		LLFastTimer::FrameState* frame_state = mFrameState; -		mStartTime = getCPUClockCount32(); - -		frame_state->mActiveCount++; -		frame_state->mCalls++; -		// keep current parent as long as it is active when we are -		frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0); - -		LLFastTimer::CurTimerData* cur_timer_data = &LLFastTimer::sCurTimerData; -		mLastTimerData = *cur_timer_data; -		cur_timer_data->mCurTimer = this; -		cur_timer_data->mFrameState = frame_state; -		cur_timer_data->mChildTime = 0; -#endif -#if TIME_FAST_TIMERS -		U64 timer_end = getCPUClockCount64(); -		sTimerCycles += timer_end - timer_start; -#endif -#if DEBUG_FAST_TIMER_THREADS -#if !LL_RELEASE -		assert_main_thread(); -#endif -#endif -	} - -	LL_FORCE_INLINE ~LLFastTimer() -	{ -#if TIME_FAST_TIMERS -		U64 timer_start = getCPUClockCount64(); -#endif -#if FAST_TIMER_ON -		LLFastTimer::FrameState* frame_state = mFrameState; -		U32 total_time = getCPUClockCount32() - mStartTime; - -		frame_state->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime; -		frame_state->mActiveCount--; - -		// store last caller to bootstrap tree creation -		// do this in the destructor in case of recursion to get topmost caller -		frame_state->mLastCaller = mLastTimerData.mFrameState; - -		// we are only tracking self time, so subtract our total time delta from parents -		mLastTimerData.mChildTime += total_time; - -		LLFastTimer::sCurTimerData = mLastTimerData; -#endif -#if TIME_FAST_TIMERS -		U64 timer_end = getCPUClockCount64(); -		sTimerCycles += timer_end - timer_start; -		sTimerCalls++; -#endif -	} - -public: -	static LLMutex*			sLogLock; -	static std::queue<LLSD> sLogQueue; -	static BOOL				sLog; -	static BOOL				sMetricLog; -	static std::string		sLogName; -	static bool 			sPauseHistory; -	static bool 			sResetHistory; -	static U64				sTimerCycles; -	static U32				sTimerCalls; - -	typedef std::vector<FrameState> info_list_t; -	static info_list_t& getFrameStateList(); - - -	// call this once a frame to reset timers -	static void nextFrame(); - -	// dumps current cumulative frame stats to log -	// call nextFrame() to reset timers -	static void dumpCurTimes(); - -	// call this to reset timer hierarchy, averages, etc. -	static void reset(); - -	static U64 countsPerSecond(); -	static S32 getLastFrameIndex() { return sLastFrameIndex; } -	static S32 getCurFrameIndex() { return sCurFrameIndex; } - -	static void writeLog(std::ostream& os); -	static const NamedTimer* getTimerByName(const std::string& name); - -	struct CurTimerData -	{ -		LLFastTimer*	mCurTimer; -		FrameState*		mFrameState; -		U32				mChildTime; -	}; -	static CurTimerData		sCurTimerData; -	static std::string sClockType; - -private: -	static U32 getCPUClockCount32(); -	static U64 getCPUClockCount64(); -	static U64 sClockResolution; - -	static S32				sCurFrameIndex; -	static S32				sLastFrameIndex; -	static U64				sLastFrameTime; -	static info_list_t*		sTimerInfos; - -	U32							mStartTime; -	LLFastTimer::FrameState*	mFrameState; -	LLFastTimer::CurTimerData	mLastTimerData; - -}; - -typedef class LLFastTimer LLFastTimer; - -#endif // LL_LLFASTTIMER_CLASS_H diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index 9a6d1eff5c..0dd6030fa2 100644 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -31,6 +31,7 @@  #include <vector>  #include <boost/function.hpp>  #include <boost/type_traits/is_convertible.hpp> +#include <boost/type_traits/is_enum.hpp>  #include <boost/unordered_map.hpp>  #include <boost/shared_ptr.hpp> @@ -209,9 +210,7 @@ namespace LLInitParam  	class LL_COMMON_API Parser  	{  		LOG_CLASS(Parser); -  	public: -		  		typedef std::vector<std::pair<std::string, bool> >					name_stack_t;  		typedef std::pair<name_stack_t::iterator, name_stack_t::iterator>	name_stack_range_t;  		typedef std::vector<std::string>									possible_values_t; @@ -224,32 +223,81 @@ namespace LLInitParam  		typedef std::map<const std::type_info*, parser_write_func_t>	parser_write_func_map_t;  		typedef std::map<const std::type_info*, parser_inspect_func_t>	parser_inspect_func_map_t; +	private: +		template<typename T, bool is_enum = boost::is_enum<T>::value> +		struct ReaderWriter +		{ +			static bool read(T& param, Parser* parser) +			{ +				parser_read_func_map_t::iterator found_it = parser->mParserReadFuncs->find(&typeid(T)); +				if (found_it != parser->mParserReadFuncs->end()) +				{ +					return found_it->second(*parser, (void*)¶m); +				} +				return false; +			} +			 +			static bool write(const T& param, Parser* parser, name_stack_t& name_stack) +			{ +				parser_write_func_map_t::iterator found_it = parser->mParserWriteFuncs->find(&typeid(T)); +				if (found_it != parser->mParserWriteFuncs->end()) +				{ +					return found_it->second(*parser, (const void*)¶m, name_stack); +				} +				return false; +			} +		}; + +		// read enums as ints +		template<typename T> +		struct ReaderWriter<T, true> +		{ +			static bool read(T& param, Parser* parser) +			{ +				// read all enums as ints +				parser_read_func_map_t::iterator found_it = parser->mParserReadFuncs->find(&typeid(S32)); +				if (found_it != parser->mParserReadFuncs->end()) +				{ +					S32 value; +					if (found_it->second(*parser, (void*)&value)) +					{ +						param = (T)value; +						return true; +					} +				} +				return false; +			} + +			static bool write(const T& param, Parser* parser, name_stack_t& name_stack) +			{ +				parser_write_func_map_t::iterator found_it = parser->mParserWriteFuncs->find(&typeid(S32)); +				if (found_it != parser->mParserWriteFuncs->end()) +				{ +					return found_it->second(*parser, (const void*)¶m, name_stack); +				} +				return false; +			} +		}; + +	public: +  		Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)  		:	mParseSilently(false),  			mParserReadFuncs(&read_map),  			mParserWriteFuncs(&write_map),  			mParserInspectFuncs(&inspect_map)  		{} +  		virtual ~Parser();  		template <typename T> bool readValue(T& param)  	    { -		    parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T)); -		    if (found_it != mParserReadFuncs->end()) -		    { -			    return found_it->second(*this, (void*)¶m); -		    } -		    return false; +			return ReaderWriter<T>::read(param, this);  	    }  		template <typename T> bool writeValue(const T& param, name_stack_t& name_stack)  		{ -		    parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T)); -		    if (found_it != mParserWriteFuncs->end()) -		    { -			    return found_it->second(*this, (const void*)¶m, name_stack); -		    } -		    return false; +			return ReaderWriter<T>::write(param, this, name_stack);  		}  		// dispatch inspection to registered inspection functions, for each parameter in a param block @@ -841,30 +889,24 @@ namespace LLInitParam  			self_t& typed_param = static_cast<self_t&>(param);  			// no further names in stack, attempt to parse value now  			if (name_stack_range.first == name_stack_range.second) -			{ -				if (parser.readValue(typed_param.getValue())) +			{	 +				std::string name; + +				// try to parse a known named value +				if(name_value_lookup_t::valueNamesExist() +					&& parser.readValue(name) +					&& name_value_lookup_t::getValueFromName(name, typed_param.getValue()))  				{ -					typed_param.clearValueName(); +					typed_param.setValueName(name);  					typed_param.setProvided();  					return true;  				} -				 -				// try to parse a known named value -				if(name_value_lookup_t::valueNamesExist()) +				// try to read value directly +				else if (parser.readValue(typed_param.getValue()))  				{ -					// try to parse a known named value -					std::string name; -					if (parser.readValue(name)) -					{ -						// try to parse a per type named value -						if (name_value_lookup_t::getValueFromName(name, typed_param.getValue())) -						{ -							typed_param.setValueName(name); -							typed_param.setProvided(); -							return true; -						} - -					} +					typed_param.clearValueName(); +					typed_param.setProvided(); +					return true;  				}  			}  			return false; @@ -987,30 +1029,29 @@ namespace LLInitParam  		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)  		{   			self_t& typed_param = static_cast<self_t&>(param); -			// attempt to parse block... + +			if (name_stack_range.first == name_stack_range.second) +			{	// try to parse a known named value +				std::string name; + +				if(name_value_lookup_t::valueNamesExist() +					&& parser.readValue(name)				 +					&& name_value_lookup_t::getValueFromName(name, typed_param.getValue())) +				{ +					typed_param.setValueName(name); +					typed_param.setProvided(); +					return true; +				} +			} +			  			if(typed_param.deserializeBlock(parser, name_stack_range, new_name)) -			{ +			{	// attempt to parse block...  				typed_param.clearValueName();  				typed_param.setProvided();  				return true;  			} -			if(name_value_lookup_t::valueNamesExist()) -			{ -				// try to parse a known named value -				std::string name; -				if (parser.readValue(name)) -				{ -					// try to parse a per type named value -					if (name_value_lookup_t::getValueFromName(name, typed_param.getValue())) -					{ -						typed_param.setValueName(name); -						typed_param.setProvided(); -						return true; -					} -				} -			}  			return false;  		} @@ -1160,30 +1201,22 @@ namespace LLInitParam  			value_t value;  			// no further names in stack, attempt to parse value now  			if (name_stack_range.first == name_stack_range.second) -			{ -				// attempt to read value directly -				if (parser.readValue(value)) +			{	 +				std::string name; +				 +				// try to parse a known named value +				if(name_value_lookup_t::valueNamesExist() +					&& parser.readValue(name) +					&& name_value_lookup_t::getValueFromName(name, value))  				{  					typed_param.add(value); +					typed_param.mValues.back().setValueName(name);  					return true;  				} -				 -				// try to parse a known named value -				if(name_value_lookup_t::valueNamesExist()) +				else if (parser.readValue(value)) 	// attempt to read value directly  				{ -					// try to parse a known named value -					std::string name; -					if (parser.readValue(name)) -					{ -						// try to parse a per type named value -						if (name_value_lookup_t::getValueFromName(name, value)) -						{ -							typed_param.add(value); -							typed_param.mValues.back().setValueName(name); -							return true; -						} - -					} +					typed_param.add(value); +					return true;  				}  			}  			return false; @@ -1362,28 +1395,27 @@ namespace LLInitParam  			param_value_t& value = typed_param.mValues.back(); +			if (name_stack_range.first == name_stack_range.second) +			{	// try to parse a known named value +				std::string name; + +				if(name_value_lookup_t::valueNamesExist() +					&& parser.readValue(name) +					&& name_value_lookup_t::getValueFromName(name, value.getValue())) +				{ +					typed_param.mValues.back().setValueName(name); +					typed_param.setProvided(); +					return true; +				} +			} +  			// attempt to parse block...  			if(value.deserializeBlock(parser, name_stack_range, new_name))  			{  				typed_param.setProvided();  				return true;  			} -			else if(name_value_lookup_t::valueNamesExist()) -			{ -				// try to parse a known named value -				std::string name; -				if (parser.readValue(name)) -				{ -					// try to parse a per type named value -					if (name_value_lookup_t::getValueFromName(name, value.getValue())) -					{ -						typed_param.mValues.back().setValueName(name); -						typed_param.setProvided(); -						return true; -					} -				} -			}  			if (new_value)  			{	// failed to parse new value, pop it off diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 10013e0f92..e725bdd9fa 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -26,7 +26,9 @@  #ifndef LLMEMORY_H  #define LLMEMORY_H -#include "llmemtype.h" +#include "linden_common.h" + +class LLMutex ;  #if LL_WINDOWS && LL_DEBUG  #define LL_CHECK_MEMORY llassert(_CrtCheckMemory()); diff --git a/indra/llcommon/llmemtype.cpp b/indra/llcommon/llmemtype.cpp deleted file mode 100644 index 6290a7158f..0000000000 --- a/indra/llcommon/llmemtype.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/**  - * @file llmemtype.cpp - * @brief Simple memory allocation/deallocation tracking stuff here - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#include "llmemtype.h" -#include "llallocator.h" - -std::vector<char const *> LLMemType::DeclareMemType::mNameList; - -LLMemType::DeclareMemType LLMemType::MTYPE_INIT("Init"); -LLMemType::DeclareMemType LLMemType::MTYPE_STARTUP("Startup"); -LLMemType::DeclareMemType LLMemType::MTYPE_MAIN("Main"); -LLMemType::DeclareMemType LLMemType::MTYPE_FRAME("Frame"); - -LLMemType::DeclareMemType LLMemType::MTYPE_GATHER_INPUT("GatherInput"); -LLMemType::DeclareMemType LLMemType::MTYPE_JOY_KEY("JoyKey"); - -LLMemType::DeclareMemType LLMemType::MTYPE_IDLE("Idle"); -LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_PUMP("IdlePump"); -LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_NETWORK("IdleNetwork"); -LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_UPDATE_REGIONS("IdleUpdateRegions"); -LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_UPDATE_VIEWER_REGION("IdleUpdateViewerRegion"); -LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_UPDATE_SURFACE("IdleUpdateSurface"); -LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_UPDATE_PARCEL_OVERLAY("IdleUpdateParcelOverlay"); -LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_AUDIO("IdleAudio"); - -LLMemType::DeclareMemType LLMemType::MTYPE_CACHE_PROCESS_PENDING("CacheProcessPending"); -LLMemType::DeclareMemType LLMemType::MTYPE_CACHE_PROCESS_PENDING_ASKS("CacheProcessPendingAsks"); -LLMemType::DeclareMemType LLMemType::MTYPE_CACHE_PROCESS_PENDING_REPLIES("CacheProcessPendingReplies"); - -LLMemType::DeclareMemType LLMemType::MTYPE_MESSAGE_CHECK_ALL("MessageCheckAll"); -LLMemType::DeclareMemType LLMemType::MTYPE_MESSAGE_PROCESS_ACKS("MessageProcessAcks"); - -LLMemType::DeclareMemType LLMemType::MTYPE_RENDER("Render"); -LLMemType::DeclareMemType LLMemType::MTYPE_SLEEP("Sleep"); - -LLMemType::DeclareMemType LLMemType::MTYPE_NETWORK("Network"); -LLMemType::DeclareMemType LLMemType::MTYPE_PHYSICS("Physics"); -LLMemType::DeclareMemType LLMemType::MTYPE_INTERESTLIST("InterestList"); - -LLMemType::DeclareMemType LLMemType::MTYPE_IMAGEBASE("ImageBase"); -LLMemType::DeclareMemType LLMemType::MTYPE_IMAGERAW("ImageRaw"); -LLMemType::DeclareMemType LLMemType::MTYPE_IMAGEFORMATTED("ImageFormatted"); -		 -LLMemType::DeclareMemType LLMemType::MTYPE_APPFMTIMAGE("AppFmtImage"); -LLMemType::DeclareMemType LLMemType::MTYPE_APPRAWIMAGE("AppRawImage"); -LLMemType::DeclareMemType LLMemType::MTYPE_APPAUXRAWIMAGE("AppAuxRawImage"); -		 -LLMemType::DeclareMemType LLMemType::MTYPE_DRAWABLE("Drawable"); - -LLMemType::DeclareMemType LLMemType::MTYPE_OBJECT("Object"); -LLMemType::DeclareMemType LLMemType::MTYPE_OBJECT_PROCESS_UPDATE("ObjectProcessUpdate"); -LLMemType::DeclareMemType LLMemType::MTYPE_OBJECT_PROCESS_UPDATE_CORE("ObjectProcessUpdateCore"); - -LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY("Display"); -LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_UPDATE("DisplayUpdate"); -LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_UPDATE_CAMERA("DisplayUpdateCam"); -LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_UPDATE_GEOM("DisplayUpdateGeom"); -LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_SWAP("DisplaySwap"); -LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_UPDATE_HUD("DisplayUpdateHud"); -LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_GEN_REFLECTION("DisplayGenRefl"); -LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_IMAGE_UPDATE("DisplayImageUpdate"); -LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_STATE_SORT("DisplayStateSort"); -LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_SKY("DisplaySky"); -LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_RENDER_GEOM("DisplayRenderGeom"); -LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_RENDER_FLUSH("DisplayRenderFlush"); -LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_RENDER_UI("DisplayRenderUI"); -LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_RENDER_ATTACHMENTS("DisplayRenderAttach"); - -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_DATA("VertexData"); -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_CONSTRUCTOR("VertexConstr"); -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_DESTRUCTOR("VertexDestr"); -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_CREATE_VERTICES("VertexCreateVerts"); -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_CREATE_INDICES("VertexCreateIndices"); -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_DESTROY_BUFFER("VertexDestroyBuff");	 -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_DESTROY_INDICES("VertexDestroyIndices"); -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_UPDATE_VERTS("VertexUpdateVerts"); -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_UPDATE_INDICES("VertexUpdateIndices"); -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_ALLOCATE_BUFFER("VertexAllocateBuffer"); -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_RESIZE_BUFFER("VertexResizeBuffer"); -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_MAP_BUFFER("VertexMapBuffer"); -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES("VertexMapBufferVerts"); -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES("VertexMapBufferIndices"); -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_UNMAP_BUFFER("VertexUnmapBuffer"); -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_SET_STRIDE("VertexSetStride"); -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_SET_BUFFER("VertexSetBuffer"); -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_SETUP_VERTEX_BUFFER("VertexSetupVertBuff"); -LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_CLEANUP_CLASS("VertexCleanupClass"); - -LLMemType::DeclareMemType LLMemType::MTYPE_SPACE_PARTITION("SpacePartition"); - -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE("Pipeline"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_INIT("PipelineInit"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_CREATE_BUFFERS("PipelineCreateBuffs"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RESTORE_GL("PipelineRestroGL"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_UNLOAD_SHADERS("PipelineUnloadShaders"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_LIGHTING_DETAIL("PipelineLightingDetail"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_GET_POOL_TYPE("PipelineGetPoolType"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_ADD_POOL("PipelineAddPool"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_ALLOCATE_DRAWABLE("PipelineAllocDrawable"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_ADD_OBJECT("PipelineAddObj"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_CREATE_OBJECTS("PipelineCreateObjs"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_UPDATE_MOVE("PipelineUpdateMove"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_UPDATE_GEOM("PipelineUpdateGeom"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_MARK_VISIBLE("PipelineMarkVisible"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_MARK_MOVED("PipelineMarkMoved"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_MARK_SHIFT("PipelineMarkShift"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_SHIFT_OBJECTS("PipelineShiftObjs"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_MARK_TEXTURED("PipelineMarkTextured"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_MARK_REBUILD("PipelineMarkRebuild"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_UPDATE_CULL("PipelineUpdateCull"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_STATE_SORT("PipelineStateSort"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_POST_SORT("PipelinePostSort"); -		 -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_HUD_ELS("PipelineHudEls"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_HL("PipelineRenderHL"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_GEOM("PipelineRenderGeom"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_GEOM_DEFFERRED("PipelineRenderGeomDef"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_GEOM_POST_DEF("PipelineRenderGeomPostDef"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_GEOM_SHADOW("PipelineRenderGeomShadow"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_SELECT("PipelineRenderSelect"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_REBUILD_POOLS("PipelineRebuildPools"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_QUICK_LOOKUP("PipelineQuickLookup"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_OBJECTS("PipelineRenderObjs"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_GENERATE_IMPOSTOR("PipelineGenImpostors"); -LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_BLOOM("PipelineRenderBloom"); - -LLMemType::DeclareMemType LLMemType::MTYPE_UPKEEP_POOLS("UpkeepPools"); - -LLMemType::DeclareMemType LLMemType::MTYPE_AVATAR("Avatar"); -LLMemType::DeclareMemType LLMemType::MTYPE_AVATAR_MESH("AvatarMesh"); -LLMemType::DeclareMemType LLMemType::MTYPE_PARTICLES("Particles"); -LLMemType::DeclareMemType LLMemType::MTYPE_REGIONS("Regions"); - -LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY("Inventory"); -LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_DRAW("InventoryDraw"); -LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_BUILD_NEW_VIEWS("InventoryBuildNewViews"); -LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_DO_FOLDER("InventoryDoFolder"); -LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_POST_BUILD("InventoryPostBuild"); -LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_FROM_XML("InventoryFromXML"); -LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_CREATE_NEW_ITEM("InventoryCreateNewItem"); -LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_VIEW_INIT("InventoryViewInit"); -LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_VIEW_SHOW("InventoryViewShow"); -LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_VIEW_TOGGLE("InventoryViewToggle"); - -LLMemType::DeclareMemType LLMemType::MTYPE_ANIMATION("Animation"); -LLMemType::DeclareMemType LLMemType::MTYPE_VOLUME("Volume"); -LLMemType::DeclareMemType LLMemType::MTYPE_PRIMITIVE("Primitive"); -		 -LLMemType::DeclareMemType LLMemType::MTYPE_SCRIPT("Script"); -LLMemType::DeclareMemType LLMemType::MTYPE_SCRIPT_RUN("ScriptRun"); -LLMemType::DeclareMemType LLMemType::MTYPE_SCRIPT_BYTECODE("ScriptByteCode"); -		 -LLMemType::DeclareMemType LLMemType::MTYPE_IO_PUMP("IoPump"); -LLMemType::DeclareMemType LLMemType::MTYPE_IO_TCP("IoTCP"); -LLMemType::DeclareMemType LLMemType::MTYPE_IO_BUFFER("IoBuffer"); -LLMemType::DeclareMemType LLMemType::MTYPE_IO_HTTP_SERVER("IoHttpServer"); -LLMemType::DeclareMemType LLMemType::MTYPE_IO_SD_SERVER("IoSDServer"); -LLMemType::DeclareMemType LLMemType::MTYPE_IO_SD_CLIENT("IoSDClient"); -LLMemType::DeclareMemType LLMemType::MTYPE_IO_URL_REQUEST("IOUrlRequest"); - -LLMemType::DeclareMemType LLMemType::MTYPE_DIRECTX_INIT("DirectXInit"); - -LLMemType::DeclareMemType LLMemType::MTYPE_TEMP1("Temp1"); -LLMemType::DeclareMemType LLMemType::MTYPE_TEMP2("Temp2"); -LLMemType::DeclareMemType LLMemType::MTYPE_TEMP3("Temp3"); -LLMemType::DeclareMemType LLMemType::MTYPE_TEMP4("Temp4"); -LLMemType::DeclareMemType LLMemType::MTYPE_TEMP5("Temp5"); -LLMemType::DeclareMemType LLMemType::MTYPE_TEMP6("Temp6"); -LLMemType::DeclareMemType LLMemType::MTYPE_TEMP7("Temp7"); -LLMemType::DeclareMemType LLMemType::MTYPE_TEMP8("Temp8"); -LLMemType::DeclareMemType LLMemType::MTYPE_TEMP9("Temp9"); - -LLMemType::DeclareMemType LLMemType::MTYPE_OTHER("Other"); - - -LLMemType::DeclareMemType::DeclareMemType(char const * st) -{ -	mID = (S32)mNameList.size(); -	mName = st; - -	mNameList.push_back(mName); -} - -LLMemType::DeclareMemType::~DeclareMemType() -{ -} - -LLMemType::LLMemType(LLMemType::DeclareMemType& dt) -{ -	mTypeIndex = dt.mID; -	LLAllocator::pushMemType(dt.mID); -} - -LLMemType::~LLMemType() -{ -	LLAllocator::popMemType(); -} - -char const * LLMemType::getNameFromID(S32 id) -{ -	if (id < 0 || id >= (S32)DeclareMemType::mNameList.size()) -	{ -		return "INVALID"; -	} - -	return DeclareMemType::mNameList[id]; -} - -//-------------------------------------------------------------------------------------------------- diff --git a/indra/llcommon/llmemtype.h b/indra/llcommon/llmemtype.h deleted file mode 100644 index 4945dbaf60..0000000000 --- a/indra/llcommon/llmemtype.h +++ /dev/null @@ -1,242 +0,0 @@ -/**  - * @file llmemtype.h - * @brief Runtime memory usage debugging utilities. - * - * $LicenseInfo:firstyear=2005&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#ifndef LL_MEMTYPE_H -#define LL_MEMTYPE_H - -//---------------------------------------------------------------------------- -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- - -#include "linden_common.h" -//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -// WARNING: Never commit with MEM_TRACK_MEM == 1 -//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -#define MEM_TRACK_MEM (0 && LL_WINDOWS) - -#include <vector> - -#define MEM_TYPE_NEW(T) - -class LL_COMMON_API LLMemType -{ -public: - -	// class we'll initialize all instances of as -	// static members of MemType.  Then use -	// to construct any new mem type. -	class LL_COMMON_API DeclareMemType -	{ -	public: -		DeclareMemType(char const * st); -		~DeclareMemType(); -	 -		S32 mID; -		char const * mName; -		 -		// array so we can map an index ID to Name -		static std::vector<char const *> mNameList; -	}; - -	LLMemType(DeclareMemType& dt); -	~LLMemType(); - -	static char const * getNameFromID(S32 id); - -	static DeclareMemType MTYPE_INIT; -	static DeclareMemType MTYPE_STARTUP; -	static DeclareMemType MTYPE_MAIN; -	static DeclareMemType MTYPE_FRAME; - -	static DeclareMemType MTYPE_GATHER_INPUT; -	static DeclareMemType MTYPE_JOY_KEY; - -	static DeclareMemType MTYPE_IDLE; -	static DeclareMemType MTYPE_IDLE_PUMP; -	static DeclareMemType MTYPE_IDLE_NETWORK; -	static DeclareMemType MTYPE_IDLE_UPDATE_REGIONS; -	static DeclareMemType MTYPE_IDLE_UPDATE_VIEWER_REGION; -	static DeclareMemType MTYPE_IDLE_UPDATE_SURFACE; -	static DeclareMemType MTYPE_IDLE_UPDATE_PARCEL_OVERLAY; -	static DeclareMemType MTYPE_IDLE_AUDIO; - -	static DeclareMemType MTYPE_CACHE_PROCESS_PENDING; -	static DeclareMemType MTYPE_CACHE_PROCESS_PENDING_ASKS; -	static DeclareMemType MTYPE_CACHE_PROCESS_PENDING_REPLIES; - -	static DeclareMemType MTYPE_MESSAGE_CHECK_ALL; -	static DeclareMemType MTYPE_MESSAGE_PROCESS_ACKS; - -	static DeclareMemType MTYPE_RENDER; -	static DeclareMemType MTYPE_SLEEP; - -	static DeclareMemType MTYPE_NETWORK; -	static DeclareMemType MTYPE_PHYSICS; -	static DeclareMemType MTYPE_INTERESTLIST; - -	static DeclareMemType MTYPE_IMAGEBASE; -	static DeclareMemType MTYPE_IMAGERAW; -	static DeclareMemType MTYPE_IMAGEFORMATTED; -	 -	static DeclareMemType MTYPE_APPFMTIMAGE; -	static DeclareMemType MTYPE_APPRAWIMAGE; -	static DeclareMemType MTYPE_APPAUXRAWIMAGE; -	 -	static DeclareMemType MTYPE_DRAWABLE; -	 -	static DeclareMemType MTYPE_OBJECT; -	static DeclareMemType MTYPE_OBJECT_PROCESS_UPDATE; -	static DeclareMemType MTYPE_OBJECT_PROCESS_UPDATE_CORE; - -	static DeclareMemType MTYPE_DISPLAY; -	static DeclareMemType MTYPE_DISPLAY_UPDATE; -	static DeclareMemType MTYPE_DISPLAY_UPDATE_CAMERA; -	static DeclareMemType MTYPE_DISPLAY_UPDATE_GEOM; -	static DeclareMemType MTYPE_DISPLAY_SWAP; -	static DeclareMemType MTYPE_DISPLAY_UPDATE_HUD; -	static DeclareMemType MTYPE_DISPLAY_GEN_REFLECTION; -	static DeclareMemType MTYPE_DISPLAY_IMAGE_UPDATE; -	static DeclareMemType MTYPE_DISPLAY_STATE_SORT; -	static DeclareMemType MTYPE_DISPLAY_SKY; -	static DeclareMemType MTYPE_DISPLAY_RENDER_GEOM; -	static DeclareMemType MTYPE_DISPLAY_RENDER_FLUSH; -	static DeclareMemType MTYPE_DISPLAY_RENDER_UI; -	static DeclareMemType MTYPE_DISPLAY_RENDER_ATTACHMENTS; - -	static DeclareMemType MTYPE_VERTEX_DATA; -	static DeclareMemType MTYPE_VERTEX_CONSTRUCTOR; -	static DeclareMemType MTYPE_VERTEX_DESTRUCTOR; -	static DeclareMemType MTYPE_VERTEX_CREATE_VERTICES; -	static DeclareMemType MTYPE_VERTEX_CREATE_INDICES; -	static DeclareMemType MTYPE_VERTEX_DESTROY_BUFFER;	 -	static DeclareMemType MTYPE_VERTEX_DESTROY_INDICES; -	static DeclareMemType MTYPE_VERTEX_UPDATE_VERTS; -	static DeclareMemType MTYPE_VERTEX_UPDATE_INDICES; -	static DeclareMemType MTYPE_VERTEX_ALLOCATE_BUFFER; -	static DeclareMemType MTYPE_VERTEX_RESIZE_BUFFER; -	static DeclareMemType MTYPE_VERTEX_MAP_BUFFER; -	static DeclareMemType MTYPE_VERTEX_MAP_BUFFER_VERTICES; -	static DeclareMemType MTYPE_VERTEX_MAP_BUFFER_INDICES; -	static DeclareMemType MTYPE_VERTEX_UNMAP_BUFFER; -	static DeclareMemType MTYPE_VERTEX_SET_STRIDE; -	static DeclareMemType MTYPE_VERTEX_SET_BUFFER; -	static DeclareMemType MTYPE_VERTEX_SETUP_VERTEX_BUFFER; -	static DeclareMemType MTYPE_VERTEX_CLEANUP_CLASS; - -	static DeclareMemType MTYPE_SPACE_PARTITION; - -	static DeclareMemType MTYPE_PIPELINE; -	static DeclareMemType MTYPE_PIPELINE_INIT; -	static DeclareMemType MTYPE_PIPELINE_CREATE_BUFFERS; -	static DeclareMemType MTYPE_PIPELINE_RESTORE_GL; -	static DeclareMemType MTYPE_PIPELINE_UNLOAD_SHADERS; -	static DeclareMemType MTYPE_PIPELINE_LIGHTING_DETAIL; -	static DeclareMemType MTYPE_PIPELINE_GET_POOL_TYPE; -	static DeclareMemType MTYPE_PIPELINE_ADD_POOL; -	static DeclareMemType MTYPE_PIPELINE_ALLOCATE_DRAWABLE; -	static DeclareMemType MTYPE_PIPELINE_ADD_OBJECT; -	static DeclareMemType MTYPE_PIPELINE_CREATE_OBJECTS; -	static DeclareMemType MTYPE_PIPELINE_UPDATE_MOVE; -	static DeclareMemType MTYPE_PIPELINE_UPDATE_GEOM; -	static DeclareMemType MTYPE_PIPELINE_MARK_VISIBLE; -	static DeclareMemType MTYPE_PIPELINE_MARK_MOVED; -	static DeclareMemType MTYPE_PIPELINE_MARK_SHIFT; -	static DeclareMemType MTYPE_PIPELINE_SHIFT_OBJECTS; -	static DeclareMemType MTYPE_PIPELINE_MARK_TEXTURED; -	static DeclareMemType MTYPE_PIPELINE_MARK_REBUILD; -	static DeclareMemType MTYPE_PIPELINE_UPDATE_CULL; -	static DeclareMemType MTYPE_PIPELINE_STATE_SORT; -	static DeclareMemType MTYPE_PIPELINE_POST_SORT; -	 -	static DeclareMemType MTYPE_PIPELINE_RENDER_HUD_ELS; -	static DeclareMemType MTYPE_PIPELINE_RENDER_HL; -	static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM; -	static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM_DEFFERRED; -	static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM_POST_DEF; -	static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM_SHADOW; -	static DeclareMemType MTYPE_PIPELINE_RENDER_SELECT; -	static DeclareMemType MTYPE_PIPELINE_REBUILD_POOLS; -	static DeclareMemType MTYPE_PIPELINE_QUICK_LOOKUP; -	static DeclareMemType MTYPE_PIPELINE_RENDER_OBJECTS; -	static DeclareMemType MTYPE_PIPELINE_GENERATE_IMPOSTOR; -	static DeclareMemType MTYPE_PIPELINE_RENDER_BLOOM; - -	static DeclareMemType MTYPE_UPKEEP_POOLS; - -	static DeclareMemType MTYPE_AVATAR; -	static DeclareMemType MTYPE_AVATAR_MESH; -	static DeclareMemType MTYPE_PARTICLES; -	static DeclareMemType MTYPE_REGIONS; - -	static DeclareMemType MTYPE_INVENTORY; -	static DeclareMemType MTYPE_INVENTORY_DRAW; -	static DeclareMemType MTYPE_INVENTORY_BUILD_NEW_VIEWS; -	static DeclareMemType MTYPE_INVENTORY_DO_FOLDER; -	static DeclareMemType MTYPE_INVENTORY_POST_BUILD; -	static DeclareMemType MTYPE_INVENTORY_FROM_XML; -	static DeclareMemType MTYPE_INVENTORY_CREATE_NEW_ITEM; -	static DeclareMemType MTYPE_INVENTORY_VIEW_INIT; -	static DeclareMemType MTYPE_INVENTORY_VIEW_SHOW; -	static DeclareMemType MTYPE_INVENTORY_VIEW_TOGGLE; - -	static DeclareMemType MTYPE_ANIMATION; -	static DeclareMemType MTYPE_VOLUME; -	static DeclareMemType MTYPE_PRIMITIVE; -	 -	static DeclareMemType MTYPE_SCRIPT; -	static DeclareMemType MTYPE_SCRIPT_RUN; -	static DeclareMemType MTYPE_SCRIPT_BYTECODE; -	 -	static DeclareMemType MTYPE_IO_PUMP; -	static DeclareMemType MTYPE_IO_TCP; -	static DeclareMemType MTYPE_IO_BUFFER; -	static DeclareMemType MTYPE_IO_HTTP_SERVER; -	static DeclareMemType MTYPE_IO_SD_SERVER; -	static DeclareMemType MTYPE_IO_SD_CLIENT; -	static DeclareMemType MTYPE_IO_URL_REQUEST; - -	static DeclareMemType MTYPE_DIRECTX_INIT; - -	static DeclareMemType MTYPE_TEMP1; -	static DeclareMemType MTYPE_TEMP2; -	static DeclareMemType MTYPE_TEMP3; -	static DeclareMemType MTYPE_TEMP4; -	static DeclareMemType MTYPE_TEMP5; -	static DeclareMemType MTYPE_TEMP6; -	static DeclareMemType MTYPE_TEMP7; -	static DeclareMemType MTYPE_TEMP8; -	static DeclareMemType MTYPE_TEMP9; - -	static DeclareMemType MTYPE_OTHER; // Special; used by display code - -	S32 mTypeIndex; -}; - -//---------------------------------------------------------------------------- - -#endif - diff --git a/indra/llcommon/llstat.cpp b/indra/llcommon/llstat.cpp index b82d52797e..3678c8e1c1 100644 --- a/indra/llcommon/llstat.cpp +++ b/indra/llcommon/llstat.cpp @@ -37,736 +37,30 @@  // statics -S32	            LLPerfBlock::sStatsFlags = LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS;       // Control what is being recorded -LLPerfBlock::stat_map_t    LLPerfBlock::sStatMap;    // Map full path string to LLStatTime objects, tracks all active objects -std::string        LLPerfBlock::sCurrentStatPath = "";    // Something like "/total_time/physics/physics step" - -//------------------------------------------------------------------------ -// Live config file to trigger stats logging -static const char    STATS_CONFIG_FILE_NAME[]            = "/dev/shm/simperf/simperf_proc_config.llsd"; -static const F32    STATS_CONFIG_REFRESH_RATE            = 5.0;        // seconds - -class LLStatsConfigFile : public LLLiveFile -{ -public: -    LLStatsConfigFile() -        : LLLiveFile(filename(), STATS_CONFIG_REFRESH_RATE), -        mChanged(false), mStatsp(NULL) { } - -    static std::string filename(); -     -protected: -    /* virtual */ bool loadFile(); - -public: -    void init(LLPerfStats* statsp); -    static LLStatsConfigFile& instance(); -        // return the singleton stats config file - -    bool mChanged; - -protected: -    LLPerfStats*    mStatsp; -}; - -std::string LLStatsConfigFile::filename() -{ -    return STATS_CONFIG_FILE_NAME; -} - -void LLStatsConfigFile::init(LLPerfStats* statsp) -{ -    mStatsp = statsp; -} - -LLStatsConfigFile& LLStatsConfigFile::instance() -{ -    static LLStatsConfigFile the_file; -    return the_file; -} - - -/* virtual */ -// Load and parse the stats configuration file -bool LLStatsConfigFile::loadFile() -{ -    if (!mStatsp) -    { -        llwarns << "Tries to load performance configure file without initializing LPerfStats" << llendl; -        return false; -    } -    mChanged = true; -     -    LLSD stats_config; -    { -        llifstream file(filename().c_str()); -        if (file.is_open()) -        { -            LLSDSerialize::fromXML(stats_config, file); -            if (stats_config.isUndefined()) -            { -                llinfos << "Performance statistics configuration file ill-formed, not recording statistics" << llendl; -                mStatsp->setReportPerformanceDuration( 0.f ); -                return false; -            } -        } -        else  -        {    // File went away, turn off stats if it was on -            if ( mStatsp->frameStatsIsRunning() ) -            { -                llinfos << "Performance statistics configuration file deleted, not recording statistics" << llendl; -                mStatsp->setReportPerformanceDuration( 0.f ); -            } -            return true; -        } -    } - -    F32 duration = 0.f; -    F32 interval = 0.f; -	S32 flags = LLPerfBlock::LLSTATS_BASIC_STATS; - -    const char * w = "duration"; -    if (stats_config.has(w)) -    { -        duration = (F32)stats_config[w].asReal(); -    }  -    w = "interval"; -    if (stats_config.has(w)) -    { -        interval = (F32)stats_config[w].asReal(); -    }  -    w = "flags"; -    if (stats_config.has(w)) -    { -		flags = (S32)stats_config[w].asInteger(); -		if (flags == LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS && -			duration > 0) -		{   // No flags passed in, but have a duration, so reset to basic stats -			flags = LLPerfBlock::LLSTATS_BASIC_STATS; -		} -    }  - -    mStatsp->setReportPerformanceDuration( duration, flags ); -    mStatsp->setReportPerformanceInterval( interval ); - -    if ( duration > 0 ) -    { -        if ( interval == 0.f ) -        { -            llinfos << "Recording performance stats every frame for " << duration << " sec" << llendl; -        } -        else -        { -            llinfos << "Recording performance stats every " << interval << " seconds for " << duration << " seconds" << llendl; -        } -    } -    else -    { -        llinfos << "Performance stats recording turned off" << llendl; -    } -	return true; -} - - -//------------------------------------------------------------------------ - -LLPerfStats::LLPerfStats(const std::string& process_name, S32 process_pid) :  -    mFrameStatsFileFailure(FALSE), -    mSkipFirstFrameStats(FALSE), -    mProcessName(process_name), -    mProcessPID(process_pid), -    mReportPerformanceStatInterval(1.f), -    mReportPerformanceStatEnd(0.0)  -{ } - -LLPerfStats::~LLPerfStats() -{ -    LLPerfBlock::clearDynamicStats(); -    mFrameStatsFile.close(); -} - -void LLPerfStats::init() -{ -    // Initialize the stats config file instance. -    (void) LLStatsConfigFile::instance().init(this); -    (void) LLStatsConfigFile::instance().checkAndReload(); -} - -// Open file for statistics -void    LLPerfStats::openPerfStatsFile() -{ -    if ( !mFrameStatsFile -        && !mFrameStatsFileFailure ) -    { -        std::string stats_file = llformat("/dev/shm/simperf/%s_proc.%d.llsd", mProcessName.c_str(), mProcessPID); -        mFrameStatsFile.close(); -        mFrameStatsFile.clear(); -        mFrameStatsFile.open(stats_file, llofstream::out); -        if ( mFrameStatsFile.fail() ) -        { -            llinfos << "Error opening statistics log file " << stats_file << llendl; -            mFrameStatsFileFailure = TRUE; -        } -        else -        { -            LLSD process_info = LLSD::emptyMap(); -            process_info["name"] = mProcessName; -            process_info["pid"] = (LLSD::Integer) mProcessPID; -            process_info["stat_rate"] = (LLSD::Integer) mReportPerformanceStatInterval; -            // Add process-specific info. -            addProcessHeaderInfo(process_info); - -            mFrameStatsFile << LLSDNotationStreamer(process_info) << std::endl;  -        } -    } -} - -// Dump out performance metrics over some time interval -void LLPerfStats::dumpIntervalPerformanceStats() -{ -    // Ensure output file is OK -    openPerfStatsFile(); - -    if ( mFrameStatsFile ) -    { -        LLSD stats = LLSD::emptyMap(); - -        LLStatAccum::TimeScale scale; -        if ( getReportPerformanceInterval() == 0.f ) -        { -            scale = LLStatAccum::SCALE_PER_FRAME; -        } -        else if ( getReportPerformanceInterval() < 0.5f ) -        { -            scale = LLStatAccum::SCALE_100MS; -        } -        else -        { -            scale = LLStatAccum::SCALE_SECOND; -        } - -        // Write LLSD into log -        stats["utc_time"] = (LLSD::String) LLError::utcTime(); -        stats["timestamp"] = U64_to_str((totalTime() / 1000) + (gUTCOffset * 1000));    // milliseconds since epoch -        stats["frame_number"] = (LLSD::Integer) LLFrameTimer::getFrameCount(); - -        // Add process-specific frame info. -        addProcessFrameInfo(stats, scale); -        LLPerfBlock::addStatsToLLSDandReset( stats, scale ); - -        mFrameStatsFile << LLSDNotationStreamer(stats) << std::endl;  -    } -} - -// Set length of performance stat recording.   -// If turning stats on, caller must provide flags -void    LLPerfStats::setReportPerformanceDuration( F32 seconds, S32 flags /* = LLSTATS_NO_OPTIONAL_STATS */ ) -{  -	if ( seconds <= 0.f ) -	{ -		mReportPerformanceStatEnd = 0.0; -		LLPerfBlock::setStatsFlags(LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS);		// Make sure all recording is off -		mFrameStatsFile.close(); -		LLPerfBlock::clearDynamicStats(); -	} -	else -	{ -		mReportPerformanceStatEnd = LLFrameTimer::getElapsedSeconds() + ((F64) seconds); -		// Clear failure flag to try and create the log file once -		mFrameStatsFileFailure = FALSE; -		mSkipFirstFrameStats = TRUE;		// Skip the first report (at the end of this frame) -		LLPerfBlock::setStatsFlags(flags); -	} -} - -void LLPerfStats::updatePerFrameStats() -{ -    (void) LLStatsConfigFile::instance().checkAndReload(); -	static LLFrameTimer performance_stats_timer; -	if ( frameStatsIsRunning() ) -	{ -		if ( mReportPerformanceStatInterval == 0 ) -		{	// Record info every frame -			if ( mSkipFirstFrameStats ) -			{	// Skip the first time - was started this frame -				mSkipFirstFrameStats = FALSE; -			} -			else -			{ -				dumpIntervalPerformanceStats(); -			} -		} -		else -		{ -			performance_stats_timer.setTimerExpirySec( getReportPerformanceInterval() ); -			if (performance_stats_timer.checkExpirationAndReset( mReportPerformanceStatInterval )) -			{ -				dumpIntervalPerformanceStats(); -			} -		} -		 -		if ( LLFrameTimer::getElapsedSeconds() > mReportPerformanceStatEnd ) -		{	// Reached end of time, clear it to stop reporting -			setReportPerformanceDuration(0.f);			// Don't set mReportPerformanceStatEnd directly	 -            llinfos << "Recording performance stats completed" << llendl; -		} -	} -} - -  //------------------------------------------------------------------------ - -U64 LLStatAccum::sScaleTimes[NUM_SCALES] = -{ -	USEC_PER_SEC / 10,				// 100 millisec -	USEC_PER_SEC * 1,				// seconds -	USEC_PER_SEC * 60,				// minutes -#if ENABLE_LONG_TIME_STATS -	// enable these when more time scales are desired -	USEC_PER_SEC * 60*60,			// hours -	USEC_PER_SEC * 24*60*60,		// days -	USEC_PER_SEC * 7*24*60*60,		// weeks -#endif -}; - - - -LLStatAccum::LLStatAccum(bool useFrameTimer) -	: mUseFrameTimer(useFrameTimer), -	  mRunning(FALSE), -	  mLastTime(0), -	  mLastSampleValue(0.0), -	  mLastSampleValid(FALSE) -{ -} - -LLStatAccum::~LLStatAccum() -{ -} - - - -void LLStatAccum::reset(U64 when) -{ -	mRunning = TRUE; -	mLastTime = when; - -	for (int i = 0; i < NUM_SCALES; ++i) -	{ -		mBuckets[i].accum = 0.0; -		mBuckets[i].endTime = when + sScaleTimes[i]; -		mBuckets[i].lastValid = false; -	} -} - -void LLStatAccum::sum(F64 value) -{ -	sum(value, getCurrentUsecs()); -} - -void LLStatAccum::sum(F64 value, U64 when) -{ -	if (!mRunning) -	{ -		reset(when); -		return; -	} -	if (when < mLastTime) -	{ -		// This happens a LOT on some dual core systems. -		lldebugs << "LLStatAccum::sum clock has gone backwards from " -			<< mLastTime << " to " << when << ", resetting" << llendl; - -		reset(when); -		return; -	} - -	// how long is this value for -	U64 timeSpan = when - mLastTime; - -	for (int i = 0; i < NUM_SCALES; ++i) -	{ -		Bucket& bucket = mBuckets[i]; - -		if (when < bucket.endTime) -		{ -			bucket.accum += value; -		} -		else -		{ -			U64 timeScale = sScaleTimes[i]; - -			U64 timeLeft = when - bucket.endTime; -				// how much time is left after filling this bucket -			 -			if (timeLeft < timeScale) -			{ -				F64 valueLeft = value * timeLeft / timeSpan; - -				bucket.lastValid = true; -				bucket.lastAccum = bucket.accum + (value - valueLeft); -				bucket.accum = valueLeft; -				bucket.endTime += timeScale; -			} -			else -			{ -				U64 timeTail = timeLeft % timeScale; - -				bucket.lastValid = true; -				bucket.lastAccum = value * timeScale / timeSpan; -				bucket.accum = value * timeTail / timeSpan; -				bucket.endTime += (timeLeft - timeTail) + timeScale; -			} -		} -	} - -	mLastTime = when; -} - - -F32 LLStatAccum::meanValue(TimeScale scale) const -{ -	if (!mRunning) -	{ -		return 0.0; -	} -	if ( scale == SCALE_PER_FRAME ) -	{	// Per-frame not supported here -		scale = SCALE_100MS; -	} - -	if (scale < 0 || scale >= NUM_SCALES) -	{ -		llwarns << "llStatAccum::meanValue called for unsupported scale: " -			<< scale << llendl; -		return 0.0; -	} - -	const Bucket& bucket = mBuckets[scale]; - -	F64 value = bucket.accum; -	U64 timeLeft = bucket.endTime - mLastTime; -	U64 scaleTime = sScaleTimes[scale]; - -	if (bucket.lastValid) -	{ -		value += bucket.lastAccum * timeLeft / scaleTime; -	} -	else if (timeLeft < scaleTime) -	{ -		value *= scaleTime / (scaleTime - timeLeft); -	} -	else -	{ -		value = 0.0; -	} - -	return (F32)(value / scaleTime); -} - - -U64 LLStatAccum::getCurrentUsecs() const -{ -	if (mUseFrameTimer) -	{ -		return LLFrameTimer::getTotalTime(); -	} -	else -	{ -		return totalTime(); -	} -} - - -// ------------------------------------------------------------------------ - -LLStatRate::LLStatRate(bool use_frame_timer) -	: LLStatAccum(use_frame_timer) -{ -} - -void LLStatRate::count(U32 value) -{ -	sum((F64)value * sScaleTimes[SCALE_SECOND]); -} - - -void LLStatRate::mark() - {  -	// Effectively the same as count(1), but sets mLastSampleValue -	U64 when = getCurrentUsecs(); - -	if ( mRunning  -		 && (when > mLastTime) ) -	{	// Set mLastSampleValue to the time from the last mark() -		F64 duration = ((F64)(when - mLastTime)) / sScaleTimes[SCALE_SECOND]; -		if ( duration > 0.0 ) -		{ -			mLastSampleValue = 1.0 / duration; -		} -		else -		{ -			mLastSampleValue = 0.0; -		} -	} - -	sum( (F64) sScaleTimes[SCALE_SECOND], when); - } - - -// ------------------------------------------------------------------------ - - -LLStatMeasure::LLStatMeasure(bool use_frame_timer) -	: LLStatAccum(use_frame_timer) -{ -} - -void LLStatMeasure::sample(F64 value) -{ -	U64 when = getCurrentUsecs(); - -	if (mLastSampleValid) -	{ -		F64 avgValue = (value + mLastSampleValue) / 2.0; -		F64 interval = (F64)(when - mLastTime); - -		sum(avgValue * interval, when); -	} -	else -	{ -		reset(when); -	} - -	mLastSampleValid = TRUE; -	mLastSampleValue = value; -} - - -// ------------------------------------------------------------------------ - -LLStatTime::LLStatTime(const std::string & key) -	: LLStatAccum(false), -	  mFrameNumber(LLFrameTimer::getFrameCount()), -	  mTotalTimeInFrame(0), -	  mKey(key) -#if LL_DEBUG -	  , mRunning(FALSE) -#endif -{ -} - -void LLStatTime::start() -{ -	// Reset frame accumluation if the frame number has changed -	U32 frame_number = LLFrameTimer::getFrameCount(); -	if ( frame_number != mFrameNumber ) -	{ -		mFrameNumber = frame_number; -		mTotalTimeInFrame = 0; -	} - -	sum(0.0); - -#if LL_DEBUG -	// Shouldn't be running already -	llassert( !mRunning ); -	mRunning = TRUE; -#endif -} - -void LLStatTime::stop() -{ -	U64 end_time = getCurrentUsecs(); -	U64 duration = end_time - mLastTime; -	sum(F64(duration), end_time); -	//llinfos << "mTotalTimeInFrame incremented from  " << mTotalTimeInFrame << " to " << (mTotalTimeInFrame + duration) << llendl;  -	mTotalTimeInFrame += duration; - -#if LL_DEBUG -	mRunning = FALSE; -#endif -} - -/* virtual */ F32 LLStatTime::meanValue(TimeScale scale) const -{ -    if ( LLStatAccum::SCALE_PER_FRAME == scale ) -    { -        return (F32)mTotalTimeInFrame; -    } -    else -    { -        return LLStatAccum::meanValue(scale); -    } -} - - -// ------------------------------------------------------------------------ - - -// Use this constructor for pre-defined LLStatTime objects -LLPerfBlock::LLPerfBlock(LLStatTime* stat ) : mPredefinedStat(stat), mDynamicStat(NULL) -{ -    if (mPredefinedStat) -    { -        // If dynamic stats are turned on, this will create a separate entry in the stat map. -        initDynamicStat(mPredefinedStat->mKey); - -        // Start predefined stats.  These stats are not part of the stat map. -        mPredefinedStat->start(); -    } -} - -// Use this constructor for normal, optional LLPerfBlock time slices -LLPerfBlock::LLPerfBlock( const char* key ) : mPredefinedStat(NULL), mDynamicStat(NULL) -{ -    if ((sStatsFlags & LLSTATS_BASIC_STATS) == 0) -	{	// These are off unless the base set is enabled -		return; -	} - -	initDynamicStat(key); -} - -	 -// Use this constructor for dynamically created LLPerfBlock time slices -// that are only enabled by specific control flags -LLPerfBlock::LLPerfBlock( const char* key1, const char* key2, S32 flags ) : mPredefinedStat(NULL), mDynamicStat(NULL) -{ -    if ((sStatsFlags & flags) == 0) -	{ -		return; -	} - -    if (NULL == key2 || strlen(key2) == 0) -    { -        initDynamicStat(key1); -    } -    else -    { -        std::ostringstream key; -        key << key1 << "_" << key2; -        initDynamicStat(key.str()); -    } -} - -// Set up the result data map if dynamic stats are enabled -void LLPerfBlock::initDynamicStat(const std::string& key) -{ -    // Early exit if dynamic stats aren't enabled. -    if (sStatsFlags == LLSTATS_NO_OPTIONAL_STATS)  -		return; - -    mLastPath = sCurrentStatPath;		// Save and restore current path -    sCurrentStatPath += "/" + key;		// Add key to current path - -    // See if the LLStatTime object already exists -    stat_map_t::iterator iter = sStatMap.find(sCurrentStatPath); -    if ( iter == sStatMap.end() ) -    { -        // StatEntry object doesn't exist, so create it -        mDynamicStat = new StatEntry( key ); -        sStatMap[ sCurrentStatPath ] = mDynamicStat;	// Set the entry for this path -    } -    else -    { -        // Found this path in the map, use the object there -        mDynamicStat = (*iter).second;		// Get StatEntry for the current path -    } - -    if (mDynamicStat) -    { -        mDynamicStat->mStat.start(); -        mDynamicStat->mCount++; -    } -    else -    { -        llwarns << "Initialized NULL dynamic stat at '" << sCurrentStatPath << "'" << llendl; -       sCurrentStatPath = mLastPath; -    } -} - - -// Destructor does the time accounting -LLPerfBlock::~LLPerfBlock() -{ -    if (mPredefinedStat) mPredefinedStat->stop(); -    if (mDynamicStat) -    { -        mDynamicStat->mStat.stop(); -        sCurrentStatPath = mLastPath;	// Restore the path in case sStatsEnabled changed during this block -    } -} - - -// Clear the map of any dynamic stats.  Static routine -void LLPerfBlock::clearDynamicStats() -{ -    std::for_each(sStatMap.begin(), sStatMap.end(), DeletePairedPointer()); -    sStatMap.clear(); -} - -// static - Extract the stat info into LLSD -void LLPerfBlock::addStatsToLLSDandReset( LLSD & stats, -										  LLStatAccum::TimeScale scale ) -{ -    // If we aren't in per-frame scale, we need to go from second to microsecond. -    U32 scale_adjustment = 1; -    if (LLStatAccum::SCALE_PER_FRAME != scale) -    { -        scale_adjustment = USEC_PER_SEC; -    } -	stat_map_t::iterator iter = sStatMap.begin(); -	for ( ; iter != sStatMap.end(); ++iter ) -	{	// Put the entry into LLSD "/full/path/to/stat/" = microsecond total time -		const std::string & stats_full_path = (*iter).first; - -		StatEntry * stat = (*iter).second; -		if (stat) -		{ -            if (stat->mCount > 0) -            { -                stats[stats_full_path] = LLSD::emptyMap(); -                stats[stats_full_path]["us"] = (LLSD::Integer) (scale_adjustment * stat->mStat.meanValue(scale)); -                if (stat->mCount > 1) -                { -                    stats[stats_full_path]["count"] = (LLSD::Integer) stat->mCount; -                } -                stat->mCount = 0; -            } -		} -		else -		{	// Shouldn't have a NULL pointer in the map. -            llwarns << "Unexpected NULL dynamic stat at '" << stats_full_path << "'" << llendl; -		} -	}	 -} - - -// ------------------------------------------------------------------------ -  LLTimer LLStat::sTimer;  LLFrameTimer LLStat::sFrameTimer; -void LLStat::init() +void LLStat::reset()  { -	llassert(mNumBins > 0);  	mNumValues = 0;  	mLastValue = 0.f; -	mLastTime = 0.f; -	mCurBin = (mNumBins-1); +	delete[] mBins; +	mBins      = new ValueEntry[mNumBins]; +	mCurBin = mNumBins-1;  	mNextBin = 0; -	mBins      = new F32[mNumBins]; -	mBeginTime = new F64[mNumBins]; -	mTime      = new F64[mNumBins]; -	mDT        = new F32[mNumBins]; -	for (U32 i = 0; i < mNumBins; i++) -	{ -		mBins[i]      = 0.f; -		mBeginTime[i] = 0.0; -		mTime[i]      = 0.0; -		mDT[i]        = 0.f; -	} +} + +LLStat::LLStat(std::string name, S32 num_bins, BOOL use_frame_timer) +:	mUseFrameTimer(use_frame_timer), +	mNumBins(num_bins), +	mName(name), +	mBins(NULL) +{ +	llassert(mNumBins > 0); +	mLastTime  = 0.f; + +	reset();  	if (!mName.empty())  	{ @@ -783,27 +77,10 @@ LLStat::stat_map_t& LLStat::getStatList()  	return stat_list;  } -LLStat::LLStat(const U32 num_bins, const BOOL use_frame_timer) -	: mUseFrameTimer(use_frame_timer), -	  mNumBins(num_bins) -{ -	init(); -} - -LLStat::LLStat(std::string name, U32 num_bins, BOOL use_frame_timer) -	: mUseFrameTimer(use_frame_timer), -	  mNumBins(num_bins), -	  mName(name) -{ -	init(); -}  LLStat::~LLStat()  {  	delete[] mBins; -	delete[] mBeginTime; -	delete[] mTime; -	delete[] mDT;  	if (!mName.empty())  	{ @@ -815,76 +92,15 @@ LLStat::~LLStat()  	}  } -void LLStat::reset() -{ -	U32 i; - -	mNumValues = 0; -	mLastValue = 0.f; -	mCurBin = (mNumBins-1); -	delete[] mBins; -	delete[] mBeginTime; -	delete[] mTime; -	delete[] mDT; -	mBins      = new F32[mNumBins]; -	mBeginTime = new F64[mNumBins]; -	mTime      = new F64[mNumBins]; -	mDT        = new F32[mNumBins]; -	for (i = 0; i < mNumBins; i++) -	{ -		mBins[i]      = 0.f; -		mBeginTime[i] = 0.0; -		mTime[i]      = 0.0; -		mDT[i]        = 0.f; -	} -} - -void LLStat::setBeginTime(const F64 time) -{ -	mBeginTime[mNextBin] = time; -} - -void LLStat::addValueTime(const F64 time, const F32 value) -{ -	if (mNumValues < mNumBins) -	{ -		mNumValues++; -	} - -	// Increment the bin counters. -	mCurBin++; -	if ((U32)mCurBin == mNumBins) -	{ -		mCurBin = 0; -	} -	mNextBin++; -	if ((U32)mNextBin == mNumBins) -	{ -		mNextBin = 0; -	} - -	mBins[mCurBin] = value; -	mTime[mCurBin] = time; -	mDT[mCurBin] = (F32)(mTime[mCurBin] - mBeginTime[mCurBin]); -	//this value is used to prime the min/max calls -	mLastTime = mTime[mCurBin]; -	mLastValue = value; - -	// Set the begin time for the next stat segment. -	mBeginTime[mNextBin] = mTime[mCurBin]; -	mTime[mNextBin] = mTime[mCurBin]; -	mDT[mNextBin] = 0.f; -} -  void LLStat::start()  {  	if (mUseFrameTimer)  	{ -		mBeginTime[mNextBin] = sFrameTimer.getElapsedSeconds(); +		mBins[mNextBin].mBeginTime = sFrameTimer.getElapsedSeconds();  	}  	else  	{ -		mBeginTime[mNextBin] = sTimer.getElapsedTimeF64(); +		mBins[mNextBin].mBeginTime = sTimer.getElapsedTimeF64();  	}  } @@ -897,41 +113,41 @@ void LLStat::addValue(const F32 value)  	// Increment the bin counters.  	mCurBin++; -	if ((U32)mCurBin == mNumBins) +	if (mCurBin >= mNumBins)  	{  		mCurBin = 0;  	}  	mNextBin++; -	if ((U32)mNextBin == mNumBins) +	if (mNextBin >= mNumBins)  	{  		mNextBin = 0;  	} -	mBins[mCurBin] = value; +	mBins[mCurBin].mValue = value;  	if (mUseFrameTimer)  	{ -		mTime[mCurBin] = sFrameTimer.getElapsedSeconds(); +		mBins[mCurBin].mTime = sFrameTimer.getElapsedSeconds();  	}  	else  	{ -		mTime[mCurBin] = sTimer.getElapsedTimeF64(); +		mBins[mCurBin].mTime = sTimer.getElapsedTimeF64();  	} -	mDT[mCurBin] = (F32)(mTime[mCurBin] - mBeginTime[mCurBin]); +	mBins[mCurBin].mDT = (F32)(mBins[mCurBin].mTime - mBins[mCurBin].mBeginTime);  	//this value is used to prime the min/max calls -	mLastTime = mTime[mCurBin]; +	mLastTime = mBins[mCurBin].mTime;  	mLastValue = value;  	// Set the begin time for the next stat segment. -	mBeginTime[mNextBin] = mTime[mCurBin]; -	mTime[mNextBin] = mTime[mCurBin]; -	mDT[mNextBin] = 0.f; +	mBins[mNextBin].mBeginTime = mBins[mCurBin].mTime; +	mBins[mNextBin].mTime = mBins[mCurBin].mTime; +	mBins[mNextBin].mDT = 0.f;  }  F32 LLStat::getMax() const  { -	U32 i; +	S32 i;  	F32 current_max = mLastValue;  	if (mNumBins == 0)  	{ @@ -942,13 +158,13 @@ F32 LLStat::getMax() const  		for (i = 0; (i < mNumBins) && (i < mNumValues); i++)  		{  			// Skip the bin we're currently filling. -			if (i == (U32)mNextBin) +			if (i == mNextBin)  			{  				continue;  			} -			if (mBins[i] > current_max) +			if (mBins[i].mValue > current_max)  			{ -				current_max = mBins[i]; +				current_max = mBins[i].mValue;  			}  		}  	} @@ -957,17 +173,17 @@ F32 LLStat::getMax() const  F32 LLStat::getMean() const  { -	U32 i; +	S32 i;  	F32 current_mean = 0.f; -	U32 samples = 0; +	S32 samples = 0;  	for (i = 0; (i < mNumBins) && (i < mNumValues); i++)  	{  		// Skip the bin we're currently filling. -		if (i == (U32)mNextBin) +		if (i == mNextBin)  		{  			continue;  		} -		current_mean += mBins[i]; +		current_mean += mBins[i].mValue;  		samples++;  	} @@ -985,7 +201,7 @@ F32 LLStat::getMean() const  F32 LLStat::getMin() const  { -	U32 i; +	S32 i;  	F32 current_min = mLastValue;  	if (mNumBins == 0) @@ -997,53 +213,19 @@ F32 LLStat::getMin() const  		for (i = 0; (i < mNumBins) && (i < mNumValues); i++)  		{  			// Skip the bin we're currently filling. -			if (i == (U32)mNextBin) +			if (i == mNextBin)  			{  				continue;  			} -			if (mBins[i] < current_min) +			if (mBins[i].mValue < current_min)  			{ -				current_min = mBins[i]; +				current_min = mBins[i].mValue;  			}  		}  	}  	return current_min;  } -F32 LLStat::getSum() const -{ -	U32 i; -	F32 sum = 0.f; -	for (i = 0; (i < mNumBins) && (i < mNumValues); i++) -	{ -		// Skip the bin we're currently filling. -		if (i == (U32)mNextBin) -		{ -			continue; -		} -		sum += mBins[i]; -	} - -	return sum; -} - -F32 LLStat::getSumDuration() const -{ -	U32 i; -	F32 sum = 0.f; -	for (i = 0; (i < mNumBins) && (i < mNumValues); i++) -	{ -		// Skip the bin we're currently filling. -		if (i == (U32)mNextBin) -		{ -			continue; -		} -		sum += mDT[i]; -	} - -	return sum; -} -  F32 LLStat::getPrev(S32 age) const  {  	S32 bin; @@ -1059,7 +241,7 @@ F32 LLStat::getPrev(S32 age) const  		// Bogus for bin we're currently working on.  		return 0.f;  	} -	return mBins[bin]; +	return mBins[bin].mValue;  }  F32 LLStat::getPrevPerSec(S32 age) const @@ -1077,107 +259,34 @@ F32 LLStat::getPrevPerSec(S32 age) const  		// Bogus for bin we're currently working on.  		return 0.f;  	} -	return mBins[bin] / mDT[bin]; -} - -F64 LLStat::getPrevBeginTime(S32 age) const -{ -	S32 bin; -	bin = mCurBin - age; - -	while (bin < 0) -	{ -		bin += mNumBins; -	} - -	if (bin == mNextBin) -	{ -		// Bogus for bin we're currently working on. -		return 0.f; -	} - -	return mBeginTime[bin]; -} - -F64 LLStat::getPrevTime(S32 age) const -{ -	S32 bin; -	bin = mCurBin - age; - -	while (bin < 0) -	{ -		bin += mNumBins; -	} - -	if (bin == mNextBin) -	{ -		// Bogus for bin we're currently working on. -		return 0.f; -	} - -	return mTime[bin]; -} - -F32 LLStat::getBin(S32 bin) const -{ -	return mBins[bin]; -} - -F32 LLStat::getBinPerSec(S32 bin) const -{ -	return mBins[bin] / mDT[bin]; -} - -F64 LLStat::getBinBeginTime(S32 bin) const -{ -	return mBeginTime[bin]; -} - -F64 LLStat::getBinTime(S32 bin) const -{ -	return mTime[bin]; +	return mBins[bin].mValue / mBins[bin].mDT;  }  F32 LLStat::getCurrent() const  { -	return mBins[mCurBin]; +	return mBins[mCurBin].mValue;  }  F32 LLStat::getCurrentPerSec() const  { -	return mBins[mCurBin] / mDT[mCurBin]; -} - -F64 LLStat::getCurrentBeginTime() const -{ -	return mBeginTime[mCurBin]; -} - -F64 LLStat::getCurrentTime() const -{ -	return mTime[mCurBin]; -} - -F32 LLStat::getCurrentDuration() const -{ -	return mDT[mCurBin]; +	return mBins[mCurBin].mValue / mBins[mCurBin].mDT;  }  F32 LLStat::getMeanPerSec() const  { -	U32 i; +	S32 i;  	F32 value = 0.f;  	F32 dt    = 0.f;  	for (i = 0; (i < mNumBins) && (i < mNumValues); i++)  	{  		// Skip the bin we're currently filling. -		if (i == (U32)mNextBin) +		if (i == mNextBin)  		{  			continue;  		} -		value += mBins[i]; -		dt    += mDT[i]; +		value += mBins[i].mValue; +		dt    += mBins[i].mDT;  	}  	if (dt > 0.f) @@ -1193,14 +302,14 @@ F32 LLStat::getMeanPerSec() const  F32 LLStat::getMeanDuration() const  {  	F32 dur = 0.0f; -	U32 count = 0; -	for (U32 i=0; (i < mNumBins) && (i < mNumValues); i++) +	S32 count = 0; +	for (S32 i=0; (i < mNumBins) && (i < mNumValues); i++)  	{ -		if (i == (U32)mNextBin) +		if (i == mNextBin)  		{  			continue;  		} -		dur += mDT[i]; +		dur += mBins[i].mDT;  		count++;  	} @@ -1217,46 +326,45 @@ F32 LLStat::getMeanDuration() const  F32 LLStat::getMaxPerSec() const  { -	U32 i;  	F32 value;  	if (mNextBin != 0)  	{ -		value = mBins[0]/mDT[0]; +		value = mBins[0].mValue/mBins[0].mDT;  	}  	else if (mNumValues > 0)  	{ -		value = mBins[1]/mDT[1]; +		value = mBins[1].mValue/mBins[1].mDT;  	}  	else  	{  		value = 0.f;  	} -	for (i = 0; (i < mNumBins) && (i < mNumValues); i++) +	for (S32 i = 0; (i < mNumBins) && (i < mNumValues); i++)  	{  		// Skip the bin we're currently filling. -		if (i == (U32)mNextBin) +		if (i == mNextBin)  		{  			continue;  		} -		value = llmax(value, mBins[i]/mDT[i]); +		value = llmax(value, mBins[i].mValue/mBins[i].mDT);  	}  	return value;  }  F32 LLStat::getMinPerSec() const  { -	U32 i; +	S32 i;  	F32 value;  	if (mNextBin != 0)  	{ -		value = mBins[0]/mDT[0]; +		value = mBins[0].mValue/mBins[0].mDT;  	}  	else if (mNumValues > 0)  	{ -		value = mBins[1]/mDT[1]; +		value = mBins[1].mValue/mBins[0].mDT;  	}  	else  	{ @@ -1266,25 +374,15 @@ F32 LLStat::getMinPerSec() const  	for (i = 0; (i < mNumBins) && (i < mNumValues); i++)  	{  		// Skip the bin we're currently filling. -		if (i == (U32)mNextBin) +		if (i == mNextBin)  		{  			continue;  		} -		value = llmin(value, mBins[i]/mDT[i]); +		value = llmin(value, mBins[i].mValue/mBins[i].mDT);  	}  	return value;  } -F32 LLStat::getMinDuration() const -{ -	F32 dur = 0.0f; -	for (U32 i=0; (i < mNumBins) && (i < mNumValues); i++) -	{ -		dur = llmin(dur, mDT[i]); -	} -	return dur; -} -  U32 LLStat::getNumValues() const  {  	return mNumValues; @@ -1295,11 +393,6 @@ S32 LLStat::getNumBins() const  	return mNumBins;  } -S32 LLStat::getCurBin() const -{ -	return mCurBin; -} -  S32 LLStat::getNextBin() const  {  	return mNextBin; diff --git a/indra/llcommon/llstat.h b/indra/llcommon/llstat.h index 1a8404cc07..38377a010b 100644 --- a/indra/llcommon/llstat.h +++ b/indra/llcommon/llstat.h @@ -27,294 +27,46 @@  #ifndef LL_LLSTAT_H  #define LL_LLSTAT_H -#include <deque>  #include <map>  #include "lltimer.h"  #include "llframetimer.h" -#include "llfile.h"  class	LLSD; -// Set this if longer stats are needed -#define ENABLE_LONG_TIME_STATS	0 - -// -// Accumulates statistics for an arbitrary length of time. -// Does this by maintaining a chain of accumulators, each one -// accumulation the results of the parent.  Can scale to arbitrary -// amounts of time with very low memory cost. -// - -class LL_COMMON_API LLStatAccum -{ -protected: -	LLStatAccum(bool use_frame_timer); -	virtual ~LLStatAccum(); - -public: -	enum TimeScale { -		SCALE_100MS, -		SCALE_SECOND, -		SCALE_MINUTE, -#if ENABLE_LONG_TIME_STATS -		SCALE_HOUR, -		SCALE_DAY, -		SCALE_WEEK, -#endif -		NUM_SCALES,			// Use to size storage arrays -		SCALE_PER_FRAME		// For latest frame information - should be after NUM_SCALES since this doesn't go into the time buckets -	}; - -	static U64 sScaleTimes[NUM_SCALES]; - -	virtual F32 meanValue(TimeScale scale) const; -		// see the subclasses for the specific meaning of value - -	F32 meanValueOverLast100ms()  const { return meanValue(SCALE_100MS);  } -	F32 meanValueOverLastSecond() const	{ return meanValue(SCALE_SECOND); } -	F32 meanValueOverLastMinute() const	{ return meanValue(SCALE_MINUTE); } - -	void reset(U64 when); - -	void sum(F64 value); -	void sum(F64 value, U64 when); - -	U64 getCurrentUsecs() const; -		// Get current microseconds based on timer type - -	BOOL	mUseFrameTimer; -	BOOL	mRunning; - -	U64		mLastTime; -	 -	struct Bucket -	{ -		Bucket() : -			accum(0.0), -			endTime(0), -			lastValid(false), -			lastAccum(0.0) -		{} - -		F64	accum; -		U64	endTime; - -		bool	lastValid; -		F64	lastAccum; -	}; - -	Bucket	mBuckets[NUM_SCALES]; - -	BOOL 	mLastSampleValid; -	F64 	mLastSampleValue; -}; - -class LL_COMMON_API LLStatMeasure : public LLStatAccum -	// gathers statistics about things that are measured -	// ex.: tempature, time dilation -{ -public: -	LLStatMeasure(bool use_frame_timer = true); - -	void sample(F64); -	void sample(S32 v) { sample((F64)v); } -	void sample(U32 v) { sample((F64)v); } -	void sample(S64 v) { sample((F64)v); } -	void sample(U64 v) { sample((F64)v); } -}; - - -class LL_COMMON_API LLStatRate : public LLStatAccum -	// gathers statistics about things that can be counted over time -	// ex.: LSL instructions executed, messages sent, simulator frames completed -	// renders it in terms of rate of thing per second -{ -public: -	LLStatRate(bool use_frame_timer = true); - -	void count(U32); -		// used to note that n items have occured -	 -	void mark(); -		// used for counting the rate thorugh a point in the code -}; - - -class LL_COMMON_API LLStatTime : public LLStatAccum -	// gathers statistics about time spent in a block of code -	// measure average duration per second in the block -{ -public: -	LLStatTime( const std::string & key = "undefined" ); - -	U32		mFrameNumber;		// Current frame number -	U64		mTotalTimeInFrame;	// Total time (microseconds) accumulated during the last frame - -	void	setKey( const std::string & key )		{ mKey = key;	}; - -	virtual F32 meanValue(TimeScale scale) const; - -private: -	void start();				// Start and stop measuring time block -	void stop(); - -	std::string		mKey;		// Tag representing this time block - -#if LL_DEBUG -	BOOL			mRunning;	// TRUE if start() has been called -#endif - -	friend class LLPerfBlock; -}; - -// ---------------------------------------------------------------------------- - - -// Use this class on the stack to record statistics about an area of code -class LL_COMMON_API LLPerfBlock -{ -public: -    struct StatEntry -    { -            StatEntry(const std::string& key) : mStat(LLStatTime(key)), mCount(0) {} -            LLStatTime  mStat; -            U32         mCount; -    }; -    typedef std::map<std::string, StatEntry*>		stat_map_t; - -	// Use this constructor for pre-defined LLStatTime objects -	LLPerfBlock(LLStatTime* stat); - -	// Use this constructor for normal, optional LLPerfBlock time slices -	LLPerfBlock( const char* key ); - -	// Use this constructor for dynamically created LLPerfBlock time slices -	// that are only enabled by specific control flags -	LLPerfBlock( const char* key1, const char* key2, S32 flags = LLSTATS_BASIC_STATS ); - -	~LLPerfBlock(); - -	enum -	{	// Stats bitfield flags -		LLSTATS_NO_OPTIONAL_STATS	= 0x00,		// No optional stats gathering, just pre-defined LLStatTime objects -		LLSTATS_BASIC_STATS			= 0x01,		// Gather basic optional runtime stats -		LLSTATS_SCRIPT_FUNCTIONS	= 0x02,		// Include LSL function calls -	}; -	static void setStatsFlags( S32 flags )	{ sStatsFlags = flags;	}; -	static S32  getStatsFlags()				{ return sStatsFlags;	}; - -	static void clearDynamicStats();		// Reset maps to clear out dynamic objects -	static void addStatsToLLSDandReset( LLSD & stats,		// Get current information and clear time bin -										LLStatAccum::TimeScale scale ); - -private: -	// Initialize dynamically created LLStatTime objects -    void initDynamicStat(const std::string& key); - -	std::string				mLastPath;				// Save sCurrentStatPath when this is called -	LLStatTime * 			mPredefinedStat;		// LLStatTime object to get data -	StatEntry *				mDynamicStat;   		// StatEntryobject to get data - -	static S32				sStatsFlags;			// Control what is being recorded -    static stat_map_t		sStatMap;				// Map full path string to LLStatTime objects -	static std::string		sCurrentStatPath;		// Something like "frame/physics/physics step" -}; - -// ---------------------------------------------------------------------------- - -class LL_COMMON_API LLPerfStats -{ -public: -    LLPerfStats(const std::string& process_name = "unknown", S32 process_pid = 0); -    virtual ~LLPerfStats(); - -    virtual void init();    // Reset and start all stat timers -    virtual void updatePerFrameStats(); -    // Override these function to add process-specific information to the performance log header and per-frame logging. -    virtual void addProcessHeaderInfo(LLSD& info) { /* not implemented */ } -    virtual void addProcessFrameInfo(LLSD& info, LLStatAccum::TimeScale scale) { /* not implemented */ } - -    // High-resolution frame stats -    BOOL    frameStatsIsRunning()                                { return (mReportPerformanceStatEnd > 0.);        }; -    F32     getReportPerformanceInterval() const                { return mReportPerformanceStatInterval;        }; -    void    setReportPerformanceInterval( F32 interval )        { mReportPerformanceStatInterval = interval;    }; -    void    setReportPerformanceDuration( F32 seconds, S32 flags = LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS ); -    void    setProcessName(const std::string& process_name) { mProcessName = process_name; } -    void    setProcessPID(S32 process_pid) { mProcessPID = process_pid; } - -protected: -    void    openPerfStatsFile();                    // Open file for high resolution metrics logging -    void    dumpIntervalPerformanceStats(); - -    llofstream      mFrameStatsFile;            // File for per-frame stats -    BOOL            mFrameStatsFileFailure;        // Flag to prevent repeat opening attempts -    BOOL            mSkipFirstFrameStats;        // Flag to skip one (partial) frame report -    std::string     mProcessName; -    S32             mProcessPID; - -private: -    F32 mReportPerformanceStatInterval;    // Seconds between performance stats -    F64 mReportPerformanceStatEnd;        // End time (seconds) for performance stats -}; -  // ----------------------------------------------------------------------------  class LL_COMMON_API LLStat  {  private:  	typedef std::multimap<std::string, LLStat*> stat_map_t; -	void init();  	static stat_map_t& getStatList();  public: -	LLStat(U32 num_bins = 32, BOOL use_frame_timer = FALSE); -	LLStat(std::string name, U32 num_bins = 32, BOOL use_frame_timer = FALSE); +	LLStat(std::string name = std::string(), S32 num_bins = 32, BOOL use_frame_timer = FALSE);  	~LLStat(); -	void reset(); -  	void start();	// Start the timer for the current "frame", otherwise uses the time tracked from  					// the last addValue +	void reset();  	void addValue(const F32 value = 1.f); // Adds the current value being tracked, and tracks the DT.  	void addValue(const S32 value) { addValue((F32)value); }  	void addValue(const U32 value) { addValue((F32)value); } -	void setBeginTime(const F64 time); -	void addValueTime(const F64 time, const F32 value = 1.f); -	 -	S32 getCurBin() const;  	S32 getNextBin() const; -	F32 getCurrent() const; -	F32 getCurrentPerSec() const; -	F64 getCurrentBeginTime() const; -	F64 getCurrentTime() const; -	F32 getCurrentDuration() const; -	  	F32 getPrev(S32 age) const;				// Age is how many "addValues" previously - zero is current  	F32 getPrevPerSec(S32 age) const;		// Age is how many "addValues" previously - zero is current -	F64 getPrevBeginTime(S32 age) const; -	F64 getPrevTime(S32 age) const; -	 -	F32 getBin(S32 bin) const; -	F32 getBinPerSec(S32 bin) const; -	F64 getBinBeginTime(S32 bin) const; -	F64 getBinTime(S32 bin) const; - -	F32 getMax() const; -	F32 getMaxPerSec() const; +	F32 getCurrent() const; +	F32 getCurrentPerSec() const; +	F32 getMin() const; +	F32 getMinPerSec() const;  	F32 getMean() const;  	F32 getMeanPerSec() const;  	F32 getMeanDuration() const; - -	F32 getMin() const; -	F32 getMinPerSec() const; -	F32 getMinDuration() const; - -	F32 getSum() const; -	F32 getSumDuration() const; +	F32 getMax() const; +	F32 getMaxPerSec() const;  	U32 getNumValues() const;  	S32 getNumBins() const; @@ -326,10 +78,21 @@ private:  	U32 mNumBins;  	F32 mLastValue;  	F64 mLastTime; -	F32 *mBins; -	F64 *mBeginTime; -	F64 *mTime; -	F32 *mDT; + +	struct ValueEntry +	{ +		ValueEntry() +		:	mValue(0.f), +			mBeginTime(0.0), +			mTime(0.0), +			mDT(0.f) +		{} +		F32 mValue; +		F64 mBeginTime; +		F64 mTime; +		F32 mDT; +	}; +	ValueEntry* mBins;  	S32 mCurBin;  	S32 mNextBin; diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index db8c9c85ab..0aaa50d231 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -44,10 +44,16 @@  #include "llmd5.h"  #include "llstring.h"  #include "lltimer.h" +#include "llthread.h"  const LLUUID LLUUID::null;  const LLTransactionID LLTransactionID::tnull; +// static  +LLMutex * LLUUID::mMutex = NULL; + + +  /*  NOT DONE YET!!! @@ -734,6 +740,7 @@ void LLUUID::getCurrentTime(uuid_time_t *timestamp)        getSystemTime(&time_last);        uuids_this_tick = uuids_per_tick;        init = TRUE; +	  mMutex = new LLMutex(NULL);     }     uuid_time_t time_now = {0,0}; @@ -785,6 +792,7 @@ void LLUUID::generate()  #endif  	if (!has_init)   	{ +		has_init = 1;  		if (getNodeID(node_id) <= 0)   		{  			get_random_bytes(node_id, 6); @@ -806,18 +814,24 @@ void LLUUID::generate()  #else  		clock_seq = (U16)ll_rand(65536);  #endif -		has_init = 1;  	}  	// get current time  	getCurrentTime(×tamp); +	U16 our_clock_seq = clock_seq; -	// if clock went backward change clockseq -	if (cmpTime(×tamp, &time_last) == -1) { +	// if clock hasn't changed or went backward, change clockseq +	if (cmpTime(×tamp, &time_last) != 1)  +	{ +		LLMutexLock	lock(mMutex);  		clock_seq = (clock_seq + 1) & 0x3FFF; -		if (clock_seq == 0) clock_seq++; +		if (clock_seq == 0)  +			clock_seq++; +		our_clock_seq = clock_seq;	// Ensure we're using a different clock_seq value from previous time  	} +    time_last = timestamp; +  	memcpy(mData+10, node_id, 6);		/* Flawfinder: ignore */  	U32 tmp;  	tmp = timestamp.low; @@ -839,7 +853,8 @@ void LLUUID::generate()  	tmp >>= 8;  	mData[6] = (unsigned char) tmp; -	tmp = clock_seq; +	tmp = our_clock_seq; +  	mData[9] = (unsigned char) tmp;  	tmp >>= 8;  	mData[8] = (unsigned char) tmp; @@ -849,8 +864,6 @@ void LLUUID::generate()  	md5_uuid.update(mData,16);  	md5_uuid.finalize();  	md5_uuid.raw_digest(mData); - -    time_last = timestamp;  }  void LLUUID::generate(const std::string& hash_string) @@ -864,8 +877,14 @@ U32 LLUUID::getRandomSeed()     static unsigned char seed[16];		/* Flawfinder: ignore */     getNodeID(&seed[0]); -   seed[6]='\0'; -   seed[7]='\0'; + +   // Incorporate the pid into the seed to prevent +   // processes that start on the same host at the same +   // time from generating the same seed. +   pid_t pid = LLApp::getPid(); + +   seed[6]=(unsigned char)(pid >> 8); +   seed[7]=(unsigned char)(pid);     getSystemTime((uuid_time_t *)(&seed[8]));     LLMD5 md5_seed; diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h index 0b9e7d0cd0..7889828c85 100644 --- a/indra/llcommon/lluuid.h +++ b/indra/llcommon/lluuid.h @@ -31,6 +31,8 @@  #include "stdtypes.h"  #include "llpreprocessor.h" +class LLMutex; +  const S32 UUID_BYTES = 16;  const S32 UUID_WORDS = 4;  const S32 UUID_STR_LENGTH = 37;	// actually wrong, should be 36 and use size below @@ -118,6 +120,7 @@ public:  	static BOOL validate(const std::string& in_string); // Validate that the UUID string is legal.  	static const LLUUID null; +	static LLMutex * mMutex;  	static U32 getRandomSeed();  	static S32 getNodeID(unsigned char * node_id); diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h deleted file mode 100644 index 8585af0a29..0000000000 --- a/indra/llcommon/llversionviewer.h +++ /dev/null @@ -1,41 +0,0 @@ -/**  - * @file llversionviewer.h - * @brief - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLVERSIONVIEWER_H -#define LL_LLVERSIONVIEWER_H - -const S32 LL_VERSION_MAJOR = 3; -const S32 LL_VERSION_MINOR = 4; -const S32 LL_VERSION_PATCH = 4; -const S32 LL_VERSION_BUILD = 0; - -const char * const LL_CHANNEL = "Second Life Developer"; - -#if LL_DARWIN -const char * const LL_VERSION_BUNDLE_ID = "com.secondlife.indra.viewer"; -#endif - -#endif | 
