Bug 927979 - Register the gecko thread correctly in the profiler for FxMetro. r=bgirard
authorJim Mathies <jmathies@mozilla.com>
Tue, 22 Oct 2013 08:30:06 -0500
changeset 151559 bb65076aabd802f9d0c82ba322e5d23a5d5ff549
parent 151558 5945380e8d1d858898e0803e9022b2f5d35a52c6
child 151560 1d5adf37d61e8d4377a15eb5a2f7b5b1e0de9d92
push id25501
push userkwierso@gmail.com
push dateTue, 22 Oct 2013 21:54:21 +0000
treeherdermozilla-central@1d5adf37d61e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgirard
bugs927979
milestone27.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 927979 - Register the gecko thread correctly in the profiler for FxMetro. r=bgirard
tools/profiler/platform.cpp
widget/windows/winrt/MetroApp.cpp
--- a/tools/profiler/platform.cpp
+++ b/tools/profiler/platform.cpp
@@ -19,16 +19,17 @@
 #include "TableTicker.h"
 #include "UnwinderThread2.h"
 #include "nsIObserverService.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsDirectoryServiceDefs.h"
 #include "mozilla/Services.h"
 #include "nsThreadUtils.h"
 #include "ProfilerMarkers.h"
+#include "nsXULAppAPI.h"
 
 #if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK)
   #include "AndroidBridge.h"
 #endif
 
 mozilla::ThreadLocal<PseudoStack *> tlsPseudoStack;
 mozilla::ThreadLocal<TableTicker *> tlsTicker;
 mozilla::ThreadLocal<void *> tlsStackTop;
@@ -60,16 +61,23 @@ unsigned int sCurrentEventGeneration = 0
 std::vector<ThreadInfo*>* Sampler::sRegisteredThreads = nullptr;
 mozilla::Mutex* Sampler::sRegisteredThreadsMutex = nullptr;
 
 TableTicker* Sampler::sActiveSampler;
 
 static mozilla::StaticAutoPtr<mozilla::ProfilerIOInterposeObserver>
                                                             sInterposeObserver;
 
+// The name that identifies the gecko thread for calls to
+// profiler_register_thread. For all platform except metro
+// the thread that calls mozilla_sampler_init is considered
+// the gecko thread.  With metro the gecko thread is
+// registered later based on this thread name.
+static const char * gGeckoThreadName = "GeckoMain";
+
 void Sampler::Startup() {
   sRegisteredThreads = new std::vector<ThreadInfo*>();
   sRegisteredThreadsMutex = new mozilla::Mutex("sRegisteredThreads mutex");
 }
 
 void Sampler::Shutdown() {
   while (sRegisteredThreads->size() > 0) {
     delete sRegisteredThreads->back();
@@ -362,16 +370,23 @@ void set_tls_stack_top(void* stackTop)
   // assumes that no target has a page size smaller than 4096.
   uintptr_t stackTopR = (uintptr_t)stackTop;
   if (stackTop) {
     stackTopR = (stackTopR & ~(uintptr_t)4095) + (uintptr_t)4095;
   }
   tlsStackTop.set((void*)stackTopR);
 }
 
+bool is_main_thread_name(const char* aName) {
+  if (aName) {
+    return false;
+  }
+  return strcmp(aName, gGeckoThreadName) == 0;
+}
+
 ////////////////////////////////////////////////////////////////////////
 // BEGIN externally visible functions
 
 void mozilla_sampler_init(void* stackTop)
 {
   sInitCount++;
 
   if (stack_key_initialized)
@@ -384,17 +399,24 @@ void mozilla_sampler_init(void* stackTop
   }
   stack_key_initialized = true;
 
   Sampler::Startup();
 
   PseudoStack *stack = new PseudoStack();
   tlsPseudoStack.set(stack);
 
-  Sampler::RegisterCurrentThread("GeckoMain", stack, true, stackTop);
+  bool isMainThread = true;
+#ifdef XP_WIN
+  // For metrofx, we'll register the main thread once it's created.
+  isMainThread = !(XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Metro);
+#endif
+  Sampler::RegisterCurrentThread(isMainThread ?
+                                   gGeckoThreadName : "Application Thread",
+                                 stack, isMainThread, stackTop);
 
   // Read mode settings from MOZ_PROFILER_MODE and interval
   // settings from MOZ_PROFILER_INTERVAL and stack-scan threshhold
   // from MOZ_PROFILER_STACK_SCAN.
   read_profiler_env_vars();
 
   // Allow the profiler to be started using signals
   OS::RegisterStartHandler();
@@ -725,18 +747,18 @@ bool mozilla_sampler_register_thread(con
   // running on startup.
   if (!profiler_is_active()) {
     return false;
   }
 #endif
 
   PseudoStack* stack = new PseudoStack();
   tlsPseudoStack.set(stack);
-
-  return Sampler::RegisterCurrentThread(aName, stack, false, stackTop);
+  bool isMainThread = is_main_thread_name(aName);
+  return Sampler::RegisterCurrentThread(aName, stack, isMainThread, stackTop);
 }
 
 void mozilla_sampler_unregister_thread()
 {
   Sampler::UnregisterCurrentThread();
 
   PseudoStack *stack = tlsPseudoStack.get();
   if (!stack) {
--- a/widget/windows/winrt/MetroApp.cpp
+++ b/widget/windows/winrt/MetroApp.cpp
@@ -7,31 +7,34 @@
 #include "MetroWidget.h"
 #include "mozilla/widget/AudioSession.h"
 #include "nsIRunnable.h"
 #include "MetroUtils.h"
 #include "MetroAppShell.h"
 #include "nsICommandLineRunner.h"
 #include "FrameworkView.h"
 #include "nsAppDirectoryServiceDefs.h"
+#include "GeckoProfiler.h"
 #include <shellapi.h>
 
 using namespace ABI::Windows::ApplicationModel;
 using namespace ABI::Windows::ApplicationModel::Core;
 using namespace ABI::Windows::UI::Core;
 using namespace ABI::Windows::System;
 using namespace ABI::Windows::Foundation;
 using namespace Microsoft::WRL;
 using namespace Microsoft::WRL::Wrappers;
 
 // Metro specific XRE methods we call from here on an
 // appropriate thread.
 extern nsresult XRE_metroStartup(bool runXREMain);
 extern void XRE_metroShutdown();
 
+static const char* gGeckoThreadName = "GeckoMain";
+
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* gWindowsLog;
 #endif
 
 namespace mozilla {
 namespace widget {
 namespace winrt {
 
@@ -60,16 +63,22 @@ MetroApp::CreateView(ABI::Windows::Appli
 ////////////////////////////////////////////////////
 // MetroApp impl.
 
 void
 MetroApp::Run()
 {
   LogThread();
 
+  // Name this thread for debugging and register it with the profiler
+  // as the main gecko thread.
+  char aLocal;
+  PR_SetCurrentThreadName(gGeckoThreadName);
+  profiler_register_thread(gGeckoThreadName, &aLocal);
+
   HRESULT hr;
   hr = sCoreApp->add_Suspending(Callback<__FIEventHandler_1_Windows__CApplicationModel__CSuspendingEventArgs_t>(
     this, &MetroApp::OnSuspending).Get(), &mSuspendEvent);
   AssertHRESULT(hr);
 
   hr = sCoreApp->add_Resuming(Callback<__FIEventHandler_1_IInspectable_t>(
     this, &MetroApp::OnResuming).Get(), &mResumeEvent);
   AssertHRESULT(hr);
@@ -96,16 +105,19 @@ MetroApp::ShutdownXPCOM()
   }
 
   if (sFrameworkView) {
     sFrameworkView->ShutdownXPCOM();
   }
 
   // Shut down xpcom
   XRE_metroShutdown();
+
+  // Unhook this thread from the profiler
+  profiler_unregister_thread();
 }
 
 // Request a shutdown of the application
 void
 MetroApp::CoreExit()
 {
   LogFunction();
   HRESULT hr;