mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 719176. Add the ability to maintain a temporary buffer of samples. r=ehsan
This lets us make the decision about whether to discard samples later than when we record them which is important for about:jank.
This commit is contained in:
parent
534d4e8c67
commit
e8612f5cb7
@ -158,6 +158,7 @@ class Profile
|
||||
public:
|
||||
Profile(int aEntrySize)
|
||||
: mWritePos(0)
|
||||
, mLastFlushPos(0)
|
||||
, mReadPos(0)
|
||||
, mEntrySize(aEntrySize)
|
||||
{
|
||||
@ -180,6 +181,72 @@ public:
|
||||
mEntries[mReadPos] = ProfileEntry();
|
||||
mReadPos = (mReadPos + 1) % mEntrySize;
|
||||
}
|
||||
// we also need to move the flush pos to ensure we
|
||||
// do not pass it
|
||||
if (mWritePos == mLastFlushPos) {
|
||||
mLastFlushPos = (mLastFlushPos + 1) % mEntrySize;
|
||||
}
|
||||
}
|
||||
|
||||
// flush the new entries
|
||||
void flush()
|
||||
{
|
||||
mLastFlushPos = mWritePos;
|
||||
}
|
||||
|
||||
// discards all of the entries since the last flush()
|
||||
// NOTE: that if mWritePos happens to wrap around past
|
||||
// mLastFlushPos we actually only discard mWritePos - mLastFlushPos entries
|
||||
//
|
||||
// r = mReadPos
|
||||
// w = mWritePos
|
||||
// f = mLastFlushPos
|
||||
//
|
||||
// r f w
|
||||
// |-----------------------------|
|
||||
// | abcdefghijklmnopq | -> 'abcdefghijklmnopq'
|
||||
// |-----------------------------|
|
||||
//
|
||||
//
|
||||
// mWritePos and mReadPos have passed mLastFlushPos
|
||||
// f
|
||||
// w r
|
||||
// |-----------------------------|
|
||||
// |ABCDEFGHIJKLMNOPQRSqrstuvwxyz|
|
||||
// |-----------------------------|
|
||||
// w
|
||||
// r
|
||||
// |-----------------------------|
|
||||
// |ABCDEFGHIJKLMNOPQRSqrstuvwxyz| -> ''
|
||||
// |-----------------------------|
|
||||
//
|
||||
//
|
||||
// mWritePos will end up the same as mReadPos
|
||||
// r
|
||||
// w f
|
||||
// |-----------------------------|
|
||||
// |ABCDEFGHIJKLMklmnopqrstuvwxyz|
|
||||
// |-----------------------------|
|
||||
// r
|
||||
// w
|
||||
// |-----------------------------|
|
||||
// |ABCDEFGHIJKLMklmnopqrstuvwxyz| -> ''
|
||||
// |-----------------------------|
|
||||
//
|
||||
//
|
||||
// mWritePos has moved past mReadPos
|
||||
// w r f
|
||||
// |-----------------------------|
|
||||
// |ABCDEFdefghijklmnopqrstuvwxyz|
|
||||
// |-----------------------------|
|
||||
// r w
|
||||
// |-----------------------------|
|
||||
// |ABCDEFdefghijklmnopqrstuvwxyz| -> 'defghijkl'
|
||||
// |-----------------------------|
|
||||
|
||||
void erase()
|
||||
{
|
||||
mWritePos = mLastFlushPos;
|
||||
}
|
||||
|
||||
void ToString(StringBuilder &profile)
|
||||
@ -190,8 +257,9 @@ public:
|
||||
mSharedLibraryInfo = SharedLibraryInfo::GetInfoForSelf();
|
||||
}
|
||||
|
||||
//XXX: this code is not thread safe and needs to be fixed
|
||||
int oldReadPos = mReadPos;
|
||||
while (mReadPos != mWritePos) {
|
||||
while (mReadPos != mLastFlushPos) {
|
||||
profile.Append(mEntries[mReadPos].TagToString(this).c_str());
|
||||
mReadPos = (mReadPos + 1) % mEntrySize;
|
||||
}
|
||||
@ -206,8 +274,9 @@ public:
|
||||
mSharedLibraryInfo = SharedLibraryInfo::GetInfoForSelf();
|
||||
}
|
||||
|
||||
//XXX: this code is not thread safe and needs to be fixed
|
||||
int oldReadPos = mReadPos;
|
||||
while (mReadPos != mWritePos) {
|
||||
while (mReadPos != mLastFlushPos) {
|
||||
string tag = mEntries[mReadPos].TagToString(this);
|
||||
fwrite(tag.data(), 1, tag.length(), stream);
|
||||
mReadPos = (mReadPos + 1) % mEntrySize;
|
||||
@ -224,6 +293,7 @@ private:
|
||||
// for simplicity
|
||||
ProfileEntry *mEntries;
|
||||
int mWritePos; // points to the next entry we will write to
|
||||
int mLastFlushPos; // points to the next entry since the last flush()
|
||||
int mReadPos; // points to the next entry we will read to
|
||||
int mEntrySize;
|
||||
bool mNeedsSharedLibraryInfo;
|
||||
@ -252,6 +322,7 @@ class TableTicker: public Sampler {
|
||||
{
|
||||
mUseStackWalk = hasFeature(aFeatures, aFeatureCount, "stackwalk");
|
||||
mProfile.addTag(ProfileEntry('m', "Start"));
|
||||
//XXX: It's probably worth splitting the jank profiler out from the regular profiler at some point
|
||||
mJankOnly = hasFeature(aFeatures, aFeatureCount, "jank");
|
||||
}
|
||||
|
||||
@ -421,6 +492,18 @@ void doSampleStackTrace(Stack *aStack, Profile &aProfile, TickSample *sample)
|
||||
}
|
||||
}
|
||||
|
||||
/* used to keep track of the last event that we sampled during */
|
||||
unsigned int sLastSampledEventGeneration = 0;
|
||||
|
||||
/* a counter that's incremented everytime we get responsiveness event
|
||||
* note: it might also be worth tracking everytime we go around
|
||||
* the event loop */
|
||||
unsigned int sCurrentEventGeneration = 0;
|
||||
/* we don't need to worry about overflow because we only treat the
|
||||
* case of them being the same as special. i.e. we only run into
|
||||
* a problem if 2^32 events happen between samples that we need
|
||||
* to know are associated with different events */
|
||||
|
||||
void TableTicker::Tick(TickSample* sample)
|
||||
{
|
||||
// Marker(s) come before the sample
|
||||
@ -432,6 +515,16 @@ void TableTicker::Tick(TickSample* sample)
|
||||
}
|
||||
mStack->mQueueClearMarker = true;
|
||||
|
||||
// if we are on a different event we can discard any temporary samples
|
||||
// we've kept around
|
||||
if (sLastSampledEventGeneration != sCurrentEventGeneration) {
|
||||
// XXX: we also probably want to add an entry to the profile to help
|
||||
// distinguish which samples are part of the same event. That, or record
|
||||
// the event generation in each sample
|
||||
mProfile.erase();
|
||||
}
|
||||
sLastSampledEventGeneration = sCurrentEventGeneration;
|
||||
|
||||
bool recordSample = true;
|
||||
if (mJankOnly) {
|
||||
recordSample = false;
|
||||
@ -444,17 +537,18 @@ void TableTicker::Tick(TickSample* sample)
|
||||
}
|
||||
}
|
||||
|
||||
if (recordSample) {
|
||||
#if defined(USE_BACKTRACE) || defined(USE_NS_STACKWALK)
|
||||
if (mUseStackWalk) {
|
||||
doBacktrace(mProfile);
|
||||
} else {
|
||||
doSampleStackTrace(mStack, mProfile, sample);
|
||||
}
|
||||
#else
|
||||
if (mUseStackWalk) {
|
||||
doBacktrace(mProfile);
|
||||
} else {
|
||||
doSampleStackTrace(mStack, mProfile, sample);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
doSampleStackTrace(mStack, mProfile, sample);
|
||||
#endif
|
||||
|
||||
if (recordSample)
|
||||
mProfile.flush();
|
||||
|
||||
if (!mJankOnly && !sLastTracerEvent.IsNull() && sample) {
|
||||
TimeDuration delta = sample->timestamp - sLastTracerEvent;
|
||||
@ -659,6 +753,7 @@ void mozilla_sampler_responsiveness(TimeStamp aTime)
|
||||
TimeDuration delta = aTime - sLastTracerEvent;
|
||||
sResponsivenessTimes[sResponsivenessLoc++] = delta.ToMilliseconds();
|
||||
}
|
||||
sCurrentEventGeneration++;
|
||||
|
||||
sLastTracerEvent = aTime;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user