diff options
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/llinstancetracker.cpp | 16 | ||||
-rw-r--r-- | indra/llcommon/llinstancetracker.h | 30 | ||||
-rw-r--r-- | indra/llcommon/lltracerecording.cpp | 136 | ||||
-rw-r--r-- | indra/llcommon/lltracerecording.h | 28 |
4 files changed, 172 insertions, 38 deletions
diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp index 071a637cda..7ff8324fe3 100644 --- a/indra/llcommon/llinstancetracker.cpp +++ b/indra/llcommon/llinstancetracker.cpp @@ -34,22 +34,6 @@ // external library headers // other Linden headers -//static -void * & LLInstanceTrackerBase::getInstances(std::type_info const & info) -{ - typedef std::map<std::string, void *> InstancesMap; - static InstancesMap instances; - - // std::map::insert() is just what we want here. You attempt to insert a - // (key, value) pair. If the specified key doesn't yet exist, it inserts - // the pair and returns a std::pair of (iterator, true). If the specified - // key DOES exist, insert() simply returns (iterator, false). One lookup - // handles both cases. - return instances.insert(InstancesMap::value_type(info.name(), - InstancesMap::mapped_type())) - .first->second; -} - void LLInstanceTrackerBase::StaticBase::incrementDepth() { apr_atomic_inc32(&sIterationNestDepth); diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 9dd6d4a7ed..a79ddd088d 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -46,22 +46,6 @@ class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable { protected: - /// Get a process-unique void* pointer slot for the specified type_info - static void * & getInstances(std::type_info const & info); - - /// Find or create a STATICDATA instance for the specified TRACKED class. - /// STATICDATA must be default-constructible. - template<typename STATICDATA, class TRACKED> - static STATICDATA& getStatic() - { - void *& instances = getInstances(typeid(TRACKED)); - if (! instances) - { - instances = new STATICDATA; - } - return *static_cast<STATICDATA*>(instances); - } - /// It's not essential to derive your STATICDATA (for use with /// getStatic()) from StaticBase; it's just that both known /// implementations do. @@ -83,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 { @@ -92,7 +77,7 @@ class LLInstanceTracker : public LLInstanceTrackerBase { InstanceMap sMap; }; - static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); } + static StaticData& getStatic() { static StaticData sData; return sData;} static InstanceMap& getMap_() { return getStatic().sMap; } public: @@ -136,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(); } @@ -187,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() { @@ -240,7 +228,7 @@ class LLInstanceTracker<T, void> : public LLInstanceTrackerBase { InstanceSet sSet; }; - static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); } + static StaticData& getStatic() { static StaticData sData; return sData; } static InstanceSet& getSet_() { return getStatic().sSet; } public: 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 |