summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/llinstancetracker.cpp16
-rw-r--r--indra/llcommon/llinstancetracker.h30
-rw-r--r--indra/llcommon/lltracerecording.cpp136
-rw-r--r--indra/llcommon/lltracerecording.h28
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