Discard samples that are older than 20 seconds. draft
authorMarkus Stange <mstange@themasta.com>
Wed, 23 May 2018 23:52:21 -0400
changeset 806066 d018fa0378807ab799cf19865b91945e2cd66357
parent 806065 e76283d9abeb527d0eba8f62120dd1295345061e
child 806067 3aded52f9ef853dc54645b81ea13e6fc2e5d2c64
push id112836
push userbmo:mstange@themasta.com
push dateFri, 08 Jun 2018 21:35:20 +0000
milestone62.0a1
Discard samples that are older than 20 seconds.
tools/profiler/core/ProfileBuffer.h
tools/profiler/core/ProfileBufferEntry.cpp
tools/profiler/core/platform.cpp
--- 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
@@ -2200,16 +2200,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