Bug 1339327 (part 2) - Tweak platform-*.cc files. r=mstange.
authorNicholas Nethercote <nnethercote@mozilla.com>
Wed, 15 Feb 2017 14:26:22 +1100
changeset 342944 bc1c0da509e47dcd9907badd5c9fde1a3356f95f
parent 342943 5da29c4aafb01e308dde13260adc8edf1ab2bf65
child 342945 5cb6c0a02b7e491cafef68ba782791ebdde8b878
push id31366
push usercbook@mozilla.com
push dateWed, 15 Feb 2017 11:25:19 +0000
treeherdermozilla-central@c0807d6938c1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1339327
milestone54.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 1339327 (part 2) - Tweak platform-*.cc files. r=mstange. This patch: - Improves some comments. - Adds some assertions. - Removes unnecessary differences between some Mac and Windows code. - Removes the unnecessary SamplerThread::mStackSize on Windows.
tools/profiler/core/platform-linux.cc
tools/profiler/core/platform-macos.cc
tools/profiler/core/platform-win32.cc
--- a/tools/profiler/core/platform-linux.cc
+++ b/tools/profiler/core/platform-linux.cc
@@ -21,16 +21,18 @@
 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 // AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 // SUCH DAMAGE.
 
+// This file is used for both Linux and Android.
+
 /*
 # vim: sw=2
 */
 #include <stdio.h>
 #include <math.h>
 
 #include <pthread.h>
 #include <semaphore.h>
@@ -357,18 +359,16 @@ static void* SignalSender(void* arg) {
   return 0;
 }
 
 static void
 PlatformStart()
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
 
-  LOG("Sampler started");
-
 #if defined(USE_EHABI_STACKWALK)
   mozilla::EHABIStackWalkInit();
 #elif defined(USE_LUL_STACKWALK)
   // NOTE: this isn't thread-safe.  But we expect PlatformStart() to be
   // called only from the main thread, so this is OK in general.
   if (!sLUL) {
      sLUL_initialization_routine();
   }
--- a/tools/profiler/core/platform-macos.cc
+++ b/tools/profiler/core/platform-macos.cc
@@ -80,20 +80,19 @@ AllocPlatformData(int aThreadId)
 }
 
 void
 PlatformDataDestructor::operator()(PlatformData* aData)
 {
   delete aData;
 }
 
-// SamplerThread objects are used for creating and running threads. When the
-// Start() method is called the new thread starts running the Run() method in
-// the new thread. The SamplerThread object should not be deallocated before
-// the thread has terminated.
+// The sampler thread controls sampling and runs whenever the profiler is
+// active. It periodically runs through all registered threads, finds those
+// that should be sampled, then pauses and samples them.
 class SamplerThread
 {
 public:
   explicit SamplerThread(double interval)
     : mIntervalMicro(floor(interval * 1000 + 0.5))
   {
     if (mIntervalMicro <= 0) {
       mIntervalMicro = 1;
@@ -127,26 +126,27 @@ public:
     pthread_create(&mThread, attr_ptr, ThreadEntry, this);
     MOZ_ASSERT(mThread != kNoThread);
   }
 
   void Join() {
     pthread_join(mThread, NULL);
   }
 
-  static void AddActiveSampler() {
+  static void StartSampler() {
     MOZ_RELEASE_ASSERT(NS_IsMainThread());
+    MOZ_RELEASE_ASSERT(!mInstance);
 
     if (mInstance == NULL) {
       mInstance = new SamplerThread(gInterval);
       mInstance->Start();
     }
   }
 
-  static void RemoveActiveSampler() {
+  static void StopSampler() {
     MOZ_RELEASE_ASSERT(NS_IsMainThread());
 
     mInstance->Join();
     delete mInstance;
     mInstance = NULL;
   }
 
   void Run() {
@@ -241,49 +241,53 @@ public:
                          reinterpret_cast<natural_t*>(&state),
                          &count) == KERN_SUCCESS) {
       sample->pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip));
       sample->sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp));
       sample->fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp));
       sample->timestamp = mozilla::TimeStamp::Now();
       sample->threadInfo = aThreadInfo;
 
+#undef REGISTER_FIELD
+
       Tick(sample);
     }
     thread_resume(profiled_thread);
   }
 
 private:
   pthread_t mThread;
 
   int mIntervalMicro;
 
   static SamplerThread* mInstance;
 
   DISALLOW_COPY_AND_ASSIGN(SamplerThread);
 };
 
-#undef REGISTER_FIELD
-
 SamplerThread* SamplerThread::mInstance = NULL;
 
 static void
 PlatformStart()
 {
+  MOZ_RELEASE_ASSERT(NS_IsMainThread());
+
   MOZ_ASSERT(!gIsActive);
   gIsActive = true;
-  SamplerThread::AddActiveSampler();
+  SamplerThread::StartSampler();
 }
 
 static void
 PlatformStop()
 {
+  MOZ_RELEASE_ASSERT(NS_IsMainThread());
+
   MOZ_ASSERT(gIsActive);
   gIsActive = false;
-  SamplerThread::RemoveActiveSampler();
+  SamplerThread::StopSampler();
 }
 
 /* static */ Thread::tid_t
 Thread::GetCurrentId()
 {
   return gettid();
 }
 
--- a/tools/profiler/core/platform-win32.cc
+++ b/tools/profiler/core/platform-win32.cc
@@ -79,28 +79,24 @@ PlatformDataDestructor::operator()(Platf
 uintptr_t
 GetThreadHandle(PlatformData* aData)
 {
   return (uintptr_t) aData->profiled_thread();
 }
 
 static const HANDLE kNoThread = INVALID_HANDLE_VALUE;
 
-// SamplerThread objects are used for creating and running threads. When the
-// Start() method is called the new thread starts running the Run() method in
-// the new thread. The SamplerThread object should not be deallocated before
-// the thread has terminated.
+// The sampler thread controls sampling and runs whenever the profiler is
+// active. It periodically runs through all registered threads, finds those
+// that should be sampled, then pauses and samples them.
 class SamplerThread
 {
  public:
-  // Initialize a Win32 thread object. The thread has an invalid thread
-  // handle until it is started.
   explicit SamplerThread(double interval)
-    : mStackSize(0)
-    , mThread(kNoThread)
+    : mThread(kNoThread)
     , mInterval(interval)
   {
     mInterval = floor(interval + 0.5);
     if (mInterval <= 0) {
       mInterval = 1;
     }
   }
 
@@ -118,38 +114,35 @@ class SamplerThread
   }
 
   // Create a new thread. It is important to use _beginthreadex() instead of
   // the Win32 function CreateThread(), because the CreateThread() does not
   // initialize thread-specific structures in the C runtime library.
   void Start() {
     mThread = reinterpret_cast<HANDLE>(
         _beginthreadex(NULL,
-                       static_cast<unsigned>(mStackSize),
+                       /* stack_size */ 0,
                        ThreadEntry,
                        this,
-                       0,
+                       /* initflag */ 0,
                        (unsigned int*) &mThreadId));
   }
 
   void Join() {
     if (mThreadId != Thread::GetCurrentId()) {
       WaitForSingleObject(mThread, INFINITE);
     }
   }
 
   static void StartSampler() {
     MOZ_RELEASE_ASSERT(NS_IsMainThread());
+    MOZ_RELEASE_ASSERT(!mInstance);
 
-    if (mInstance == NULL) {
-      mInstance = new SamplerThread(gInterval);
-      mInstance->Start();
-    } else {
-      MOZ_ASSERT(mInstance->mInterval == gInterval);
-    }
+    mInstance = new SamplerThread(gInterval);
+    mInstance->Start();
   }
 
   static void StopSampler() {
     MOZ_RELEASE_ASSERT(NS_IsMainThread());
 
     mInstance->Join();
     delete mInstance;
     mInstance = NULL;
@@ -281,41 +274,44 @@ class SamplerThread
     sample->context = &context;
 
     Tick(sample);
 
     ResumeThread(profiled_thread);
   }
 
 private:
-  int mStackSize;
   HANDLE mThread;
   Thread::tid_t mThreadId;
 
   int mInterval; // units: ms
 
   // Protects the process wide state below.
   static SamplerThread* mInstance;
 
   DISALLOW_COPY_AND_ASSIGN(SamplerThread);
 };
 
 SamplerThread* SamplerThread::mInstance = NULL;
 
 static void
 PlatformStart()
 {
+  MOZ_RELEASE_ASSERT(NS_IsMainThread());
+
   MOZ_ASSERT(!gIsActive);
   gIsActive = true;
   SamplerThread::StartSampler();
 }
 
 static void
 PlatformStop()
 {
+  MOZ_RELEASE_ASSERT(NS_IsMainThread());
+
   MOZ_ASSERT(gIsActive);
   gIsActive = false;
   SamplerThread::StopSampler();
 }
 
 /* static */ Thread::tid_t
 Thread::GetCurrentId()
 {