Bug 1476775 - Proof of concept: Discard samples that are older than 20 seconds.
MozReview-Commit-ID: 693hds9Edss
--- a/tools/profiler/core/ProfileBuffer.h
+++ b/tools/profiler/core/ProfileBuffer.h
@@ -92,16 +92,18 @@ public:
// Find (via |aLastSample|) the most recent sample for the thread denoted by
// |aThreadId| and clone it, patching in the current time as appropriate.
// Mutate |aLastSample| to point to the newly inserted sample.
// Returns whether duplication was successful.
bool DuplicateLastSample(int aThreadId,
const mozilla::TimeStamp& aProcessStartTime,
mozilla::Maybe<uint64_t>& aLastSample);
+ void DiscardSamplesBeforeTime(double aTime);
+
void AddStoredMarker(ProfilerMarker* aStoredMarker);
// The following method is not signal safe!
void DeleteExpiredStoredMarkers();
// Access an entry in the buffer.
ProfileBufferEntry& GetEntry(uint64_t aPosition) const
{
--- a/tools/profiler/core/ProfileBufferEntry.cpp
+++ b/tools/profiler/core/ProfileBufferEntry.cpp
@@ -1258,11 +1258,58 @@ ProfileBuffer::DuplicateLastSample(int a
break;
}
}
e.Next();
}
return true;
}
+void
+ProfileBuffer::DiscardSamplesBeforeTime(double aTime)
+{
+ uint64_t resetRangeStartTo = mRangeStart;
+
+ EntryGetter e(*this);
+ for (;;) {
+ // This block skips entries until we find the start of the next sample.
+ // This is useful in three situations.
+ //
+ // - The circular buffer overwrites old entries, so when we start parsing
+ // we might be in the middle of a sample, and we must skip forward to the
+ // start of the next sample.
+ //
+ // - We skip samples that don't have an appropriate ThreadId or Time.
+ //
+ // - We skip range Pause, Resume, CollectionStart, Marker, and CollectionEnd
+ // entries between samples.
+ while (e.Has()) {
+ if (e.Get().IsThreadId()) {
+ break;
+ } else {
+ e.Next();
+ }
+ }
+
+ if (!e.Has()) {
+ break;
+ }
+
+ MOZ_RELEASE_ASSERT(e.Get().IsThreadId());
+ uint64_t sampleStartPos = e.CurPos();
+ e.Next();
+
+ if (e.Has() && e.Get().IsTime()) {
+ double sampleTime = e.Get().u.mDouble;
+
+ if (sampleTime >= aTime) {
+ resetRangeStartTo = sampleStartPos;
+ break;
+ }
+ }
+ }
+
+ mRangeStart = resetRangeStartTo;
+}
+
// END ProfileBuffer
////////////////////////////////////////////////////////////////////////
--- a/tools/profiler/core/platform.cpp
+++ b/tools/profiler/core/platform.cpp
@@ -2220,16 +2220,17 @@ SamplerThread::Run()
// should poke it to give it a chance to print those statistics. This
// involves doing I/O (fprintf, __android_log_print, etc.) and so
// can't safely be done from the critical section inside
// SuspendAndSampleAndResumeThread, which is why it is done here.
CorePS::Lul(lock)->MaybeShowStats();
#endif
}
+ ActivePS::Buffer(lock).DiscardSamplesBeforeTime((TimeStamp::Now() - TimeDuration::FromSeconds(20) - CorePS::ProcessStartTime()).ToMilliseconds());
ActivePS::EnsureAdequateBufferCapacity(lock);
}
// gPSMutex is not held after this point.
// Calculate how long a sleep to request. After the sleep, measure how
// long we actually slept and take the difference into account when
// calculating the sleep interval for the next iteration. This is an
// attempt to keep "to schedule" in the presence of inaccuracy of the