diff options
| -rw-r--r-- | indra/llcommon/llinstancetracker.h | 10 | ||||
| -rw-r--r-- | indra/llcommon/lltracerecording.cpp | 136 | ||||
| -rw-r--r-- | indra/llcommon/lltracerecording.h | 28 | 
3 files changed, 170 insertions, 4 deletions
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 596bea548d..a79ddd088d 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -67,6 +67,7 @@ protected:  /// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup  /// If KEY is not provided, then instances are stored in a simple set  /// @NOTE: see explicit specialization below for default KEY==void case +/// @NOTE: this class is not thread-safe unless used as read-only  template<typename T, typename KEY = void>  class LLInstanceTracker : public LLInstanceTrackerBase  { @@ -120,13 +121,13 @@ public:  		typedef boost::iterator_facade<key_iter, KEY, boost::forward_traversal_tag> super_t;  		key_iter(typename InstanceMap::iterator it) -			:	mIterator(it) +		:	mIterator(it)  		{  			getStatic().incrementDepth();  		}  		key_iter(const key_iter& other) -			:	mIterator(other.mIterator) +		:	mIterator(other.mIterator)  		{  			getStatic().incrementDepth();  		} @@ -171,7 +172,10 @@ public:  		return instance_iter(getMap_().end());  	} -	static S32 instanceCount() { return getMap_().size(); } +	static S32 instanceCount()  +	{  +		return getMap_().size();  +	}  	static key_iter beginKeys()  	{ diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index 21156b4d61..2917c217d7 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -396,6 +396,76 @@ void PeriodicRecording::nextPeriod()  	}  } + +void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other ) +{ +	if (other.mRecordingPeriods.size() < 2) return; + +	EPlayState play_state = getPlayState(); +	pause(); + +	EPlayState other_play_state = other.getPlayState(); +	other.pause(); + +	if (mAutoResize) +	{ +		// copy everything after current period of other recording to end of buffer +		// this will only apply if other recording is using a fixed circular buffer +		if (other.mCurPeriod < other.mRecordingPeriods.size() - 1) +		{ +			std::copy(	other.mRecordingPeriods.begin() + other.mCurPeriod + 1, +						other.mRecordingPeriods.end(), +						std::back_inserter(mRecordingPeriods)); +		} + +		// copy everything from beginning of other recording's buffer up to, but not including +		// current period +		std::copy(	other.mRecordingPeriods.begin(), +					other.mRecordingPeriods.begin() + other.mCurPeriod, +					std::back_inserter(mRecordingPeriods)); + +		mCurPeriod = mRecordingPeriods.size() - 1; +	} +	else +	{ +		size_t num_to_copy = llmin(	mRecordingPeriods.size(), other.mRecordingPeriods.size() ); +		std::vector<Recording>::iterator src_it = other.mRecordingPeriods.begin()  +													+ (	(other.mCurPeriod + 1)									// cur period +															+ (other.mRecordingPeriods.size() - num_to_copy)	// minus room for copy +														% other.mRecordingPeriods.size()); +		std::vector<Recording>::iterator dest_it = mRecordingPeriods.begin() + ((mCurPeriod + 1) % mRecordingPeriods.size()); + +		for(S32 i = 0; i < num_to_copy; i++) +		{ +			*dest_it = *src_it; + +			if (++src_it == other.mRecordingPeriods.end()) +			{ +				src_it = other.mRecordingPeriods.begin(); +			} + +			if (++dest_it == mRecordingPeriods.end()) +			{ +				dest_it = mRecordingPeriods.begin(); +			} +		} +		 +		mCurPeriod = (mCurPeriod + num_to_copy) % mRecordingPeriods.size(); +	} + +	// if copying from periodic recording that wasn't active advance our period to the next available one +	// otherwise continue recording on top of the last period of data received from the other recording +	if (other_play_state != STARTED) +	{ +		nextPeriod(); +	} + +	setPlayState(play_state); +	other.setPlayState(other_play_state); +} + + +  void PeriodicRecording::start()  {  	getCurRecording().start(); @@ -503,6 +573,72 @@ void ExtendableRecording::splitFrom(ExtendableRecording& other)  	mPotentialRecording.splitFrom(other.mPotentialRecording);  } +/////////////////////////////////////////////////////////////////////// +// ExtendablePeriodicRecording +/////////////////////////////////////////////////////////////////////// + +void ExtendablePeriodicRecording::extend() +{ +	// stop recording to get latest data +	mPotentialRecording.stop(); +	// push the data back to accepted recording +	mAcceptedRecording.appendPeriodicRecording(mPotentialRecording); +	// flush data, so we can start from scratch +	mPotentialRecording.reset(); +	// go back to play state we were in initially +	mPotentialRecording.setPlayState(getPlayState()); +} + +void ExtendablePeriodicRecording::start() +{ +	LLStopWatchControlsMixin<ExtendablePeriodicRecording>::start(); +	mPotentialRecording.start(); +} + +void ExtendablePeriodicRecording::stop() +{ +	LLStopWatchControlsMixin<ExtendablePeriodicRecording>::stop(); +	mPotentialRecording.stop(); +} + +void ExtendablePeriodicRecording::pause() +{ +	LLStopWatchControlsMixin<ExtendablePeriodicRecording>::pause(); +	mPotentialRecording.pause(); +} + +void ExtendablePeriodicRecording::resume() +{ +	LLStopWatchControlsMixin<ExtendablePeriodicRecording>::resume(); +	mPotentialRecording.resume(); +} + +void ExtendablePeriodicRecording::restart() +{ +	LLStopWatchControlsMixin<ExtendablePeriodicRecording>::restart(); +	mAcceptedRecording.reset(); +	mPotentialRecording.restart(); +} + +void ExtendablePeriodicRecording::reset() +{ +	LLStopWatchControlsMixin<ExtendablePeriodicRecording>::reset(); +	mAcceptedRecording.reset(); +	mPotentialRecording.reset(); +} + +void ExtendablePeriodicRecording::splitTo(ExtendablePeriodicRecording& other) +{ +	LLStopWatchControlsMixin<ExtendablePeriodicRecording>::splitTo(other); +	mPotentialRecording.splitTo(other.mPotentialRecording); +} + +void ExtendablePeriodicRecording::splitFrom(ExtendablePeriodicRecording& other) +{ +	LLStopWatchControlsMixin<ExtendablePeriodicRecording>::splitFrom(other); +	mPotentialRecording.splitFrom(other.mPotentialRecording); +} +  PeriodicRecording& get_frame_recording()  {  	static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(1000, PeriodicRecording::STARTED)); diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index 7c4113dbf0..23b031b49b 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -254,6 +254,8 @@ namespace LLTrace  		void nextPeriod();  		U32 getNumPeriods() { return mRecordingPeriods.size(); } +		void appendPeriodicRecording(PeriodicRecording& other); +  		Recording& getLastRecording()  		{  			U32 num_periods = mRecordingPeriods.size(); @@ -424,6 +426,7 @@ namespace LLTrace  		void extend();  		Recording& getAcceptedRecording() { return mAcceptedRecording; } +		const Recording& getAcceptedRecording() const {return mAcceptedRecording;}  		// implementation for LLStopWatchControlsMixin  		/*virtual*/ void start(); @@ -435,11 +438,34 @@ namespace LLTrace  		/*virtual*/ void splitTo(ExtendableRecording& other);  		/*virtual*/ void splitFrom(ExtendableRecording& other); -		const Recording& getAcceptedRecording() const {return mAcceptedRecording;}  	private:  		Recording mAcceptedRecording;  		Recording mPotentialRecording;  	}; + +	class ExtendablePeriodicRecording +	:	public LLStopWatchControlsMixin<ExtendablePeriodicRecording> +	{ +	public: +		void extend(); + +		PeriodicRecording& getAcceptedRecording() { return mAcceptedRecording; } +		const PeriodicRecording& getAcceptedRecording() const {return mAcceptedRecording;} + +		// implementation for LLStopWatchControlsMixin +		/*virtual*/ void start(); +		/*virtual*/ void stop(); +		/*virtual*/ void pause(); +		/*virtual*/ void resume(); +		/*virtual*/ void restart(); +		/*virtual*/ void reset(); +		/*virtual*/ void splitTo(ExtendablePeriodicRecording& other); +		/*virtual*/ void splitFrom(ExtendablePeriodicRecording& other); + +	private: +		PeriodicRecording mAcceptedRecording; +		PeriodicRecording mPotentialRecording; +	};  }  #endif // LL_LLTRACERECORDING_H  | 
