Bug 1430850 - Part 1: Move mThreadId from ThreadInfo to RacyThreadInfo, r=mstange
authorNika Layzell <nika@thelayzells.com>
Tue, 16 Jan 2018 12:07:21 -0500
changeset 453793 b22667aec75a440032b21141698220f7f490b9ca
parent 453788 4338e5f32b4cf4f3503be8963689b17a99a515e7
child 453794 f9628da12e3fe18e911d42190706b1b462dc66c2
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1430850
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1430850 - Part 1: Move mThreadId from ThreadInfo to RacyThreadInfo, r=mstange MozReview-Commit-ID: LE6j8Fm38PK
tools/profiler/core/ThreadInfo.cpp
tools/profiler/core/ThreadInfo.h
--- a/tools/profiler/core/ThreadInfo.cpp
+++ b/tools/profiler/core/ThreadInfo.cpp
@@ -20,19 +20,18 @@
 #endif
 
 ThreadInfo::ThreadInfo(const char* aName,
                        int aThreadId,
                        bool aIsMainThread,
                        void* aStackTop)
   : mName(strdup(aName))
   , mRegisterTime(TimeStamp::Now())
-  , mThreadId(aThreadId)
   , mIsMainThread(aIsMainThread)
-  , mRacyInfo(mozilla::MakeNotNull<RacyThreadInfo*>())
+  , mRacyInfo(mozilla::MakeNotNull<RacyThreadInfo*>(aThreadId))
   , mPlatformData(AllocPlatformData(aThreadId))
   , mStackTop(aStackTop)
   , mIsBeingProfiled(false)
   , mFirstSavedStreamedSampleTime{0.0}
   , mContext(nullptr)
   , mJSSampling(INACTIVE)
   , mLastSample()
 {
@@ -255,29 +254,29 @@ ThreadInfo::FlushSamplesAndMarkers(const
   // Note that the UniqueStacks instance is persisted so that the frame-index
   // mapping is stable across JS shutdown.
   mUniqueStacks.emplace(mContext);
 
   {
     SpliceableChunkedJSONWriter b;
     b.StartBareList();
     {
-      aBuffer.StreamSamplesToJSON(b, mThreadId, /* aSinceTime = */ 0,
+      aBuffer.StreamSamplesToJSON(b, ThreadId(), /* aSinceTime = */ 0,
                                   &mFirstSavedStreamedSampleTime,
                                   mContext, *mUniqueStacks);
     }
     b.EndBareList();
     mSavedStreamedSamples = b.WriteFunc()->CopyData();
   }
 
   {
     SpliceableChunkedJSONWriter b;
     b.StartBareList();
     {
-      aBuffer.StreamMarkersToJSON(b, mThreadId, aProcessStartTime,
+      aBuffer.StreamMarkersToJSON(b, ThreadId(), aProcessStartTime,
                                   /* aSinceTime = */ 0, *mUniqueStacks);
     }
     b.EndBareList();
     mSavedStreamedMarkers = b.WriteFunc()->CopyData();
   }
 
   // Reset the buffer. Attempting to symbolicate JS samples after mContext has
   // gone away will crash.
--- a/tools/profiler/core/ThreadInfo.h
+++ b/tools/profiler/core/ThreadInfo.h
@@ -18,18 +18,19 @@
 // This class contains the info for a single thread that is accessible without
 // protection from gPSMutex in platform.cpp. Because there is no external
 // protection against data races, it must provide internal protection. Hence
 // the "Racy" prefix.
 //
 class RacyThreadInfo final : public PseudoStack
 {
 public:
-  RacyThreadInfo()
+  explicit RacyThreadInfo(int aThreadId)
     : PseudoStack()
+    , mThreadId(aThreadId)
     , mSleep(AWAKE)
   {
     MOZ_COUNT_CTOR(RacyThreadInfo);
   }
 
   ~RacyThreadInfo()
   {
     MOZ_COUNT_DTOR(RacyThreadInfo);
@@ -108,20 +109,26 @@ public:
   void SetAwake()
   {
     MOZ_ASSERT(mSleep != AWAKE);
     mSleep = AWAKE;
   }
 
   bool IsSleeping() { return mSleep != AWAKE; }
 
+  int ThreadId() const { return mThreadId; }
+
 private:
   // A list of pending markers that must be moved to the circular buffer.
   ProfilerSignalSafeLinkedList<ProfilerMarker> mPendingMarkers;
 
+  // mThreadId contains the thread ID of the current thread. It is safe to read
+  // this from multiple threads concurrently, as it will never be mutated.
+  const int mThreadId;
+
   // mSleep tracks whether the thread is sleeping, and if so, whether it has
   // been previously observed. This is used for an optimization: in some cases,
   // when a thread is asleep, we duplicate the previous sample, which is
   // cheaper than taking a new sample.
   //
   // mSleep is atomic because it is accessed from multiple threads.
   //
   // - It is written only by this thread, via setSleeping() and setAwake().
@@ -168,17 +175,20 @@ class ThreadInfo final
 {
 public:
   ThreadInfo(const char* aName, int aThreadId, bool aIsMainThread,
              void* aStackTop);
 
   ~ThreadInfo();
 
   const char* Name() const { return mName.get(); }
-  int ThreadId() const { return mThreadId; }
+
+  // This is a safe read even when the target thread is not blocked, as this
+  // thread id is never mutated.
+  int ThreadId() const { return RacyInfo()->ThreadId(); }
 
   bool IsMainThread() const { return mIsMainThread; }
 
   mozilla::NotNull<RacyThreadInfo*> RacyInfo() const { return mRacyInfo; }
 
   void StartProfiling();
   void StopProfiling();
   bool IsBeingProfiled() { return mIsBeingProfiled; }
@@ -191,17 +201,16 @@ public:
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
   ProfileBuffer::LastSample& LastSample() { return mLastSample; }
 
 private:
   mozilla::UniqueFreePtr<char> mName;
   mozilla::TimeStamp mRegisterTime;
   mozilla::TimeStamp mUnregisterTime;
-  int mThreadId;
   const bool mIsMainThread;
 
   // The thread's RacyThreadInfo. This is an owning pointer. It could be an
   // inline member, but we don't do that because RacyThreadInfo is quite large
   // (due to the PseudoStack within it), and we have ThreadInfo vectors and so
   // we'd end up wasting a lot of space in those vectors for excess elements.
   mozilla::NotNull<RacyThreadInfo*> mRacyInfo;