tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ProfiledThreadData.h (4501B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef ProfiledThreadData_h
      8 #define ProfiledThreadData_h
      9 
     10 #include "BaseProfilingStack.h"
     11 #include "platform.h"
     12 #include "ProfileBufferEntry.h"
     13 #include "ThreadInfo.h"
     14 
     15 #include "mozilla/RefPtr.h"
     16 #include "mozilla/TimeStamp.h"
     17 
     18 #include <string>
     19 
     20 namespace mozilla {
     21 namespace baseprofiler {
     22 
     23 class ProfileBuffer;
     24 
     25 // This class contains information about a thread that is only relevant while
     26 // the profiler is running, for any threads (both alive and dead) whose thread
     27 // name matches the "thread filter" in the current profiler run.
     28 // ProfiledThreadData objects may be kept alive even after the thread is
     29 // unregistered, as long as there is still data for that thread in the profiler
     30 // buffer.
     31 //
     32 // Accesses to this class are protected by the profiler state lock.
     33 //
     34 // Created as soon as the following are true for the thread:
     35 //  - The profiler is running, and
     36 //  - the thread matches the profiler's thread filter, and
     37 //  - the thread is registered with the profiler.
     38 // So it gets created in response to either (1) the profiler being started (for
     39 // an existing registered thread) or (2) the thread being registered (if the
     40 // profiler is already running).
     41 //
     42 // The thread may be unregistered during the lifetime of ProfiledThreadData.
     43 // If that happens, NotifyUnregistered() is called.
     44 //
     45 // This class is the right place to store buffer positions. Profiler buffer
     46 // positions become invalid if the profiler buffer is destroyed, which happens
     47 // when the profiler is stopped.
     48 class ProfiledThreadData final {
     49 public:
     50  explicit ProfiledThreadData(ThreadInfo* aThreadInfo);
     51  ~ProfiledThreadData();
     52 
     53  void NotifyUnregistered(uint64_t aBufferPosition) {
     54    mLastSample = Nothing();
     55    MOZ_ASSERT(!mBufferPositionWhenReceivedJSContext,
     56               "JSContext should have been cleared before the thread was "
     57               "unregistered");
     58    mUnregisterTime = TimeStamp::Now();
     59    mBufferPositionWhenUnregistered = Some(aBufferPosition);
     60  }
     61  Maybe<uint64_t> BufferPositionWhenUnregistered() {
     62    return mBufferPositionWhenUnregistered;
     63  }
     64 
     65  Maybe<uint64_t>& LastSample() { return mLastSample; }
     66 
     67  void StreamJSON(const ProfileBuffer& aBuffer, SpliceableJSONWriter& aWriter,
     68                  const std::string& aProcessName,
     69                  const std::string& aETLDplus1,
     70                  const TimeStamp& aProcessStartTime, double aSinceTime);
     71 
     72  const RefPtr<ThreadInfo> Info() const { return mThreadInfo; }
     73 
     74  void NotifyReceivedJSContext(uint64_t aCurrentBufferPosition) {
     75    mBufferPositionWhenReceivedJSContext = Some(aCurrentBufferPosition);
     76  }
     77 
     78 private:
     79  // Group A:
     80  // The following fields are interesting for the entire lifetime of a
     81  // ProfiledThreadData object.
     82 
     83  // This thread's thread info.
     84  const RefPtr<ThreadInfo> mThreadInfo;
     85 
     86  // Group B:
     87  // The following fields are only used while this thread is alive and
     88  // registered. They become Nothing() once the thread is unregistered.
     89 
     90  // When sampling, this holds the position in ActivePS::mBuffer of the most
     91  // recent sample for this thread, or Nothing() if there is no sample for this
     92  // thread in the buffer.
     93  Maybe<uint64_t> mLastSample;
     94 
     95  // Only non-Nothing() if the thread currently has a JSContext.
     96  Maybe<uint64_t> mBufferPositionWhenReceivedJSContext;
     97 
     98  // Group C:
     99  // The following fields are only used once this thread has been unregistered.
    100 
    101  Maybe<uint64_t> mBufferPositionWhenUnregistered;
    102  TimeStamp mUnregisterTime;
    103 };
    104 
    105 // Stream all samples and markers from aBuffer with the given aThreadId (or 0
    106 // for everything, which is assumed to be a single backtrace sample.)
    107 // Returns the thread id of the output sample(s), or 0 if none was present.
    108 BaseProfilerThreadId StreamSamplesAndMarkers(
    109    const char* aName, BaseProfilerThreadId aThreadId,
    110    const ProfileBuffer& aBuffer, SpliceableJSONWriter& aWriter,
    111    const std::string& aProcessName, const std::string& aETLDplus1,
    112    const TimeStamp& aProcessStartTime, const TimeStamp& aRegisterTime,
    113    const TimeStamp& aUnregisterTime, double aSinceTime,
    114    UniqueStacks& aUniqueStacks);
    115 
    116 }  // namespace baseprofiler
    117 }  // namespace mozilla
    118 
    119 #endif  // ProfiledThreadData_h