summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorRichard Linden <none@none>2012-11-05 16:10:57 -0800
committerRichard Linden <none@none>2012-11-05 16:10:57 -0800
commit0007114cf5a60779319ab8cbd0a23a0d462b8010 (patch)
tree6bfeb603c3c28f89d1d424abb005741bff7b597a /indra
parentf8eaee753174d0cab4e4edcf795f422706d6f302 (diff)
SH-3499 WIP Ensure asset stats output is correct
fixed copy behavior of recordings and accumulator buffers
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/llinitparam.cpp2
-rw-r--r--indra/llcommon/llinitparam.h81
-rw-r--r--indra/llcommon/llpredicate.h90
-rw-r--r--indra/llcommon/lltrace.h15
-rw-r--r--indra/llcommon/lltracerecording.cpp3
-rw-r--r--indra/llcommon/lltracerecording.h29
-rw-r--r--indra/llcommon/lltracethreadrecorder.cpp5
-rw-r--r--indra/newview/llappviewer.cpp2
-rwxr-xr-xindra/newview/llviewerassetstats.cpp36
-rwxr-xr-xindra/newview/llviewerassetstats.h41
-rwxr-xr-xindra/newview/tests/llviewerassetstats_test.cpp5
11 files changed, 111 insertions, 198 deletions
diff --git a/indra/llcommon/llinitparam.cpp b/indra/llcommon/llinitparam.cpp
index d20fc03227..32d4eec607 100644
--- a/indra/llcommon/llinitparam.cpp
+++ b/indra/llcommon/llinitparam.cpp
@@ -35,7 +35,7 @@ namespace LLInitParam
predicate_rule_t default_parse_rules()
{
- return ll_make_predicate(PROVIDED) && !ll_make_predicate(EMPTY) && !ll_make_predicate(HAS_DEFAULT_VALUE);
+ return ll_make_predicate(PROVIDED) && !ll_make_predicate(EMPTY);
}
//
diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index 6177cc7d12..3d4e4331c0 100644
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -919,17 +919,8 @@ namespace LLInitParam
predicate.set(HAS_DEFAULT_VALUE);
}
- if (typed_param.isValid())
- {
- predicate.set(VALID, true);
- predicate.set(PROVIDED, typed_param.anyProvided());
- }
- else
- {
- predicate.set(VALID, false);
- predicate.set(PROVIDED, false);
- }
-
+ predicate.set(VALID, typed_param.isValid());
+ predicate.set(PROVIDED, typed_param.anyProvided());
predicate.set(EMPTY, false);
if (!predicate_rule.check(predicate)) return false;
@@ -1014,15 +1005,15 @@ namespace LLInitParam
};
// parameter that is a block
- template <typename T, typename NAME_VALUE_LOOKUP>
- class TypedParam<T, NAME_VALUE_LOOKUP, false, true>
+ template <typename BLOCK_T, typename NAME_VALUE_LOOKUP>
+ class TypedParam<BLOCK_T, NAME_VALUE_LOOKUP, false, true>
: public Param,
- public ParamValue<T, NAME_VALUE_LOOKUP>
+ public ParamValue<BLOCK_T, NAME_VALUE_LOOKUP>
{
public:
- typedef ParamValue<T, NAME_VALUE_LOOKUP> param_value_t;
+ typedef ParamValue<BLOCK_T, NAME_VALUE_LOOKUP> param_value_t;
typedef typename param_value_t::value_assignment_t value_assignment_t;
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, true> self_t;
+ typedef TypedParam<BLOCK_T, NAME_VALUE_LOOKUP, false, true> self_t;
typedef NAME_VALUE_LOOKUP name_value_lookup_t;
using param_value_t::operator();
@@ -1081,16 +1072,8 @@ namespace LLInitParam
LLPredicate::Value<ESerializePredicates> predicate;
- if (typed_param.isValid())
- {
- predicate.set(VALID, true);
- predicate.set(PROVIDED, typed_param.anyProvided());
- }
- else
- {
- predicate.set(VALID, false);
- predicate.set(PROVIDED, false);
- }
+ predicate.set(VALID, typed_param.isValid());
+ predicate.set(PROVIDED, typed_param.anyProvided());
if (!predicate_rule.check(predicate)) return false;
@@ -1187,13 +1170,13 @@ namespace LLInitParam
};
// container of non-block parameters
- template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
- class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false>
+ template <typename MULTI_VALUE_T, typename NAME_VALUE_LOOKUP>
+ class TypedParam<MULTI_VALUE_T, NAME_VALUE_LOOKUP, true, false>
: public Param
{
public:
- typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false> self_t;
- typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP> param_value_t;
+ typedef TypedParam<MULTI_VALUE_T, NAME_VALUE_LOOKUP, true, false> self_t;
+ typedef ParamValue<MULTI_VALUE_T, NAME_VALUE_LOOKUP> param_value_t;
typedef typename std::vector<param_value_t> container_t;
typedef const container_t& value_assignment_t;
@@ -1280,18 +1263,8 @@ namespace LLInitParam
LLPredicate::Value<ESerializePredicates> predicate;
predicate.set(REQUIRED, typed_param.mMinCount > 0);
-
- if (typed_param.isValid())
- {
- predicate.set(VALID, true);
- predicate.set(PROVIDED, typed_param.anyProvided());
- }
- else
- {
- predicate.set(VALID, false);
- predicate.set(PROVIDED, false);
- }
-
+ predicate.set(VALID, typed_param.isValid());
+ predicate.set(PROVIDED, typed_param.anyProvided());
predicate.set(EMPTY, typed_param.mValues.empty());
if (!predicate_rule.check(predicate)) return false;
@@ -1345,7 +1318,7 @@ namespace LLInitParam
static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
{
- parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL);
+ parser.inspectValue<MULTI_VALUE_T>(name_stack, min_count, max_count, NULL);
if (name_value_lookup_t::getPossibleValues())
{
parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
@@ -1437,13 +1410,13 @@ namespace LLInitParam
};
// container of block parameters
- template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
- class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true>
+ template <typename MULTI_BLOCK_T, typename NAME_VALUE_LOOKUP>
+ class TypedParam<MULTI_BLOCK_T, NAME_VALUE_LOOKUP, true, true>
: public Param
{
public:
- typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true> self_t;
- typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP> param_value_t;
+ typedef TypedParam<MULTI_BLOCK_T, NAME_VALUE_LOOKUP, true, true> self_t;
+ typedef ParamValue<MULTI_BLOCK_T, NAME_VALUE_LOOKUP> param_value_t;
typedef typename std::vector<param_value_t> container_t;
typedef const container_t& value_assignment_t;
typedef typename param_value_t::value_t value_t;
@@ -1548,17 +1521,9 @@ namespace LLInitParam
LLPredicate::Value<ESerializePredicates> predicate;
predicate.set(REQUIRED, typed_param.mMinCount > 0);
-
- if (typed_param.isValid())
- {
- predicate.set(VALID, true);
- predicate.set(PROVIDED, typed_param.anyProvided());
- }
- else
- {
- predicate.set(VALID, false);
- predicate.set(PROVIDED, false);
- }
+ predicate.set(VALID, typed_param.isValid());
+ predicate.set(PROVIDED, typed_param.anyProvided());
+ predicate.set(EMPTY, typed_param.mValues.empty());
if (!predicate_rule.check(predicate)) return false;
diff --git a/indra/llcommon/llpredicate.h b/indra/llcommon/llpredicate.h
index 6c9e5fc145..a0e970a799 100644
--- a/indra/llcommon/llpredicate.h
+++ b/indra/llcommon/llpredicate.h
@@ -76,41 +76,31 @@ namespace LLPredicate
void set(ENUM e, bool value = true)
{
llassert(0 <= e && e < cMaxEnum);
- mPredicateFlags = modifyPredicate(0x1 << (S32)e, cPredicateFlagsFromEnum[e], value, mPredicateFlags);
- }
-
- void set(const Value other, bool value)
- {
- predicate_flag_t predicate_flags_to_set = other.mPredicateFlags;
- predicate_flag_t cumulative_flags = 0;
- while(predicate_flags_to_set)
- {
- predicate_flag_t next_flags = clearLSB(predicate_flags_to_set);
- predicate_flag_t lsb_flag = predicate_flags_to_set ^ next_flags;
-
- predicate_flag_t mask = 0;
- predicate_flag_t cur_flags = mPredicateFlags;
- for (S32 i = 0; i < cMaxEnum; i++)
- {
- if (cPredicateFlagsFromEnum[i] & lsb_flag)
- {
- mask |= cPredicateFlagsFromEnum[i];
- cur_flags = modifyPredicate(0x1 << (0x1 << i ), cPredicateFlagsFromEnum[i], !value, cur_flags);
- }
- }
-
- cumulative_flags |= modifyPredicate(lsb_flag, mask, value, cur_flags);
-
- predicate_flags_to_set = next_flags;
+ predicate_flag_t flags_to_modify;
+ predicate_flag_t mask = cPredicateFlagsFromEnum[e];
+ if (value)
+ { // add predicate "e" to flags that don't contain it already
+ flags_to_modify = (mPredicateFlags & ~mask);
+ // clear flags not containing e
+ mPredicateFlags &= mask;
+ // add back flags shifted to contain e
+ mPredicateFlags |= flags_to_modify << (0x1 << e);
+ }
+ else
+ { // remove predicate "e" from flags that contain it
+ flags_to_modify = (mPredicateFlags & mask);
+ // clear flags containing e
+ mPredicateFlags &= ~mask;
+ // add back flags shifted to not contain e
+ mPredicateFlags |= flags_to_modify >> (0x1 << e);
}
- mPredicateFlags = cumulative_flags;
}
- void forget(const Value value)
+ void forget(ENUM e)
{
- set(value, true);
+ set(e, true);
U32 flags_with_predicate = mPredicateFlags;
- set(value, false);
+ set(e, false);
// ambiguous value is result of adding and removing predicate at the same time!
mPredicateFlags |= flags_with_predicate;
}
@@ -131,38 +121,6 @@ namespace LLPredicate
}
private:
-
- predicate_flag_t clearLSB(predicate_flag_t value)
- {
- return value & (value - 1);
- }
-
- predicate_flag_t modifyPredicate(predicate_flag_t predicate_flag, predicate_flag_t mask, predicate_flag_t value, bool set)
- {
- llassert(clearLSB(predicate_flag) == 0);
- predicate_flag_t flags_to_modify;
-
- if (set)
- {
- flags_to_modify = (mPredicateFlags & ~mask);
- // clear flags not containing predicate to be added
- value &= mask;
- // shift flags, in effect adding predicate
- flags_to_modify *= predicate_flag;
- }
- else
- {
- flags_to_modify = mPredicateFlags & mask;
- // clear flags containing predicate to be removed
- value &= ~mask;
- // shift flags, in effect removing predicate
- flags_to_modify /= predicate_flag;
- }
- // put modified flags back
- value |= flags_to_modify;
- return value;
- }
-
predicate_flag_t mPredicateFlags;
};
@@ -181,14 +139,14 @@ namespace LLPredicate
Rule()
{}
- void require(const Value<ENUM> value)
+ void require(ENUM e)
{
- mRule.set(value, require);
+ mRule.set(e, require);
}
- void allow(const Value<ENUM> value)
+ void allow(ENUM e)
{
- mRule.forget(value);
+ mRule.forget(e);
}
bool check(const Value<ENUM> value) const
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index 735c45754c..8ad391e6e5 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -38,9 +38,9 @@
#include <list>
-#define TOKEN_PASTE_ACTUAL(x, y) x##y
-#define TOKEN_PASTE(x, y) TOKEN_PASTE_ACTUAL(x, y)
-#define RECORD_BLOCK_TIME(block_timer) LLTrace::BlockTimer::Recorder TOKEN_PASTE(block_time_recorder, __COUNTER__)(block_timer);
+#define LL_TOKEN_PASTE_ACTUAL(x, y) x##y
+#define LL_TOKEN_PASTE(x, y) LL_TOKEN_PASTE_ACTUAL(x, y)
+#define LL_RECORD_BLOCK_TIME(block_timer) LLTrace::BlockTimer::Recorder LL_TOKEN_PASTE(block_time_recorder, __COUNTER__)(block_timer);
namespace LLTrace
{
@@ -93,13 +93,16 @@ namespace LLTrace
public:
- // copying an accumulator buffer does not copy the actual contents, but simply initializes the buffer size
- // to be identical to the other buffer
AccumulatorBuffer(const AccumulatorBuffer& other = getDefaultBuffer())
: mStorageSize(other.mStorageSize),
mStorage(new ACCUMULATOR[other.mStorageSize]),
mNextStorageSlot(other.mNextStorageSlot)
- {}
+ {
+ for (S32 i = 0; i < mNextStorageSlot; i++)
+ {
+ mStorage[i] = other.mStorage[i];
+ }
+ }
~AccumulatorBuffer()
{
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index a8e1a5eec9..9cdd89c223 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -52,9 +52,8 @@ Recording::~Recording()
void Recording::update()
{
if (isStarted())
-{
+ {
LLTrace::get_thread_recorder()->update(this);
- mElapsedSeconds = 0.0;
mSamplingTimer.reset();
}
}
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index 3a786c1357..e994949150 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -53,16 +53,20 @@ public:
void restart();
void reset();
- bool isStarted() { return mPlayState == STARTED; }
- bool isPaused() { return mPlayState == PAUSED; }
- bool isStopped() { return mPlayState == STOPPED; }
- EPlayState getPlayState() { return mPlayState; }
+ bool isStarted() const { return mPlayState == STARTED; }
+ bool isPaused() const { return mPlayState == PAUSED; }
+ bool isStopped() const { return mPlayState == STOPPED; }
+ EPlayState getPlayState() const { return mPlayState; }
protected:
LLStopWatchControlsMixinCommon()
: mPlayState(STOPPED)
{}
+ // derived classes can call this from their constructor in order
+ // to enforce invariants
+ void forceState(EPlayState state) { mPlayState = state; }
+
private:
// trigger data accumulation (without reset)
virtual void handleStart() = 0;
@@ -102,6 +106,23 @@ namespace LLTrace
public:
Recording();
+ Recording(const Recording& other)
+ {
+ mSamplingTimer = other.mSamplingTimer;
+ mElapsedSeconds = other.mElapsedSeconds;
+ mCountsFloat = other.mCountsFloat;
+ mMeasurementsFloat = other.mMeasurementsFloat;
+ mCounts = other.mCounts;
+ mMeasurements = other.mMeasurements;
+ mStackTimers = other.mStackTimers;
+
+ if (other.isStarted())
+ {
+ handleStart();
+ }
+
+ forceState(other.getPlayState());
+ }
~Recording();
void makePrimary();
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
index 0feb3ab7af..af66a69492 100644
--- a/indra/llcommon/lltracethreadrecorder.cpp
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -86,6 +86,11 @@ std::list<ThreadRecorder::ActiveRecording>::iterator ThreadRecorder::update( Rec
}
}
+ if (it == end_it)
+ {
+ llerrs << "Recording not active on this thread" << llendl;
+ }
+
return it;
}
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 2d090f0f74..838a982cb4 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -5244,6 +5244,8 @@ void LLAppViewer::metricsSend(bool enable_reporting)
// Make a copy of the main stats to send into another thread.
// Receiving thread takes ownership.
LLViewerAssetStats * main_stats(new LLViewerAssetStats(*gViewerAssetStats));
+
+ main_stats->updateStats();
// Send a report request into 'thread1' to get the rest of the data
// and provide some additional parameters while here.
diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp
index df43c4b344..000d061bec 100755
--- a/indra/newview/llviewerassetstats.cpp
+++ b/indra/newview/llviewerassetstats.cpp
@@ -246,9 +246,11 @@ LLViewerAssetStats::LLViewerAssetStats()
LLViewerAssetStats::LLViewerAssetStats(const LLViewerAssetStats & src)
: mRegionHandle(src.mRegionHandle),
mPhaseStats(src.mPhaseStats),
- mAvatarRezStates(src.mAvatarRezStates),
- mRegionRecordings(src.mRegionRecordings)
+ mAvatarRezStates(src.mAvatarRezStates)
{
+ src.mCurRecording->update();
+ mRegionRecordings = src.mRegionRecordings;
+
mCurRecording = &mRegionRecordings[mRegionHandle];
}
@@ -294,14 +296,17 @@ void LLViewerAssetStats::recordAvatarStats()
mPhaseStats["cloud-or-gray"] = LLViewerStats::PhaseMap::getPhaseStats("cloud-or-gray");
}
-void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)
+void LLViewerAssetStats::updateStats()
{
- using namespace LLViewerAssetStatsFF;
-
- if (mCurRecording)
+ if (mCurRecording && mCurRecording->isStarted())
{
mCurRecording->update();
}
+}
+
+void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)
+{
+ using namespace LLViewerAssetStatsFF;
stats.regions.setProvided();
@@ -463,25 +468,6 @@ LLSD LLViewerAssetStats::asLLSD(bool compact_output)
namespace LLViewerAssetStatsFF
{
-//
-// Target thread is elaborated in the function name. This could
-// have been something 'templatey' like specializations iterated
-// over a set of constants but with so few, this is clearer I think.
-//
-// As for the threads themselves... rather than do fine-grained
-// locking as we gather statistics, this code creates a collector
-// for each thread, allocated and run independently. Logging
-// happens at relatively infrequent intervals and at that time
-// the data is sent to a single thread to be aggregated into
-// a single entity with locks, thread safety and other niceties.
-//
-// A particularly fussy implementation would distribute the
-// per-thread pointers across separate cache lines. But that should
-// be beyond current requirements.
-//
-
-// 'main' thread - initial program thread
-
void set_region(LLViewerAssetStats::region_handle_t region_handle)
{
if (! gViewerAssetStats)
diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h
index f1ce3aeaa2..835df89149 100755
--- a/indra/newview/llviewerassetstats.h
+++ b/indra/newview/llviewerassetstats.h
@@ -192,43 +192,12 @@ public:
// Avatar-related statistics
void recordAvatarStats();
+ // gather latest metrics data
+ // call from main thread
+ void updateStats();
+
// Retrieve current metrics for all visited regions (NULL region UUID/handle excluded)
- // Returned LLSD is structured as follows:
- //
- // &stats_group = {
- // enqueued : int,
- // dequeued : int,
- // resp_count : int,
- // resp_min : float,
- // resp_max : float,
- // resp_mean : float
- // }
- //
- // &mmm_group = {
- // count : int,
- // min : float,
- // max : float,
- // mean : float
- // }
- //
- // {
- // duration: int
- // regions: {
- // $: { // Keys are strings of the region's handle in hex
- // duration: : int,
- // fps: : &mmm_group,
- // get_texture_temp_http : &stats_group,
- // get_texture_temp_udp : &stats_group,
- // get_texture_non_temp_http : &stats_group,
- // get_texture_non_temp_udp : &stats_group,
- // get_wearable_udp : &stats_group,
- // get_sound_udp : &stats_group,
- // get_gesture_udp : &stats_group,
- // get_other : &stats_group
- // }
- // }
- // }
- //
+ // Uses AssetStats structure seen above
void getStats(AssetStats& stats, bool compact_output);
LLSD asLLSD(bool compact_output);
diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp
index 26a76eda2c..1f299abe41 100755
--- a/indra/newview/tests/llviewerassetstats_test.cpp
+++ b/indra/newview/tests/llviewerassetstats_test.cpp
@@ -340,6 +340,7 @@ namespace tut
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false);
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false);
+ gViewerAssetStats->updateStats();
LLSD sd = gViewerAssetStats->asLLSD(false);
ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));
ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
@@ -377,6 +378,7 @@ namespace tut
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false);
LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false);
+ gViewerAssetStats->updateStats();
LLSD sd = gViewerAssetStats->asLLSD(false);
ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));
ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
@@ -422,6 +424,7 @@ namespace tut
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
+ gViewerAssetStats->updateStats();
LLSD sd = gViewerAssetStats->asLLSD(false);
// std::cout << sd << std::endl;
@@ -496,6 +499,7 @@ namespace tut
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
+ gViewerAssetStats->updateStats();
LLSD sd = gViewerAssetStats->asLLSD(false);
ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar"));
@@ -563,6 +567,7 @@ namespace tut
LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+ gViewerAssetStats->updateStats();
LLSD sd = gViewerAssetStats->asLLSD(false);
ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));
ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));