Do not start sampler thread when CpuProfiler is active
authoryurys@chromium.org <yurys@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 29 Aug 2013 14:03:38 +0000 (14:03 +0000)
committeryurys@chromium.org <yurys@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 29 Aug 2013 14:03:38 +0000 (14:03 +0000)
Now that CpuProfiler sends does sampling on the profile event processing thread there is no need to launch sampler thread. The latter is used only for --prof profiler.

BUG=v8:2814
R=bmeurer@chromium.org, svenpanne@chromium.org

Review URL: https://codereview.chromium.org/23011029

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16430 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/cpu-profiler.cc
src/cpu-profiler.h
src/log.cc
src/sampler.cc
src/sampler.h

index 74d1f03..34bebb8 100644 (file)
@@ -139,24 +139,9 @@ void ProfilerEventsProcessor::ProcessEventsAndDoSample() {
 }
 
 
-void ProfilerEventsProcessor::ProcessEventsAndYield() {
-  // Process ticks until we have any.
-  if (ProcessTicks()) {
-    // All ticks of the current dequeue_order are processed,
-    // proceed to the next code event.
-    ProcessCodeEvent();
-  }
-  YieldCPU();
-}
-
-
 void ProfilerEventsProcessor::Run() {
   while (running_) {
-    if (Sampler::CanSampleOnProfilerEventsProcessorThread()) {
-      ProcessEventsAndDoSample();
-    } else {
-      ProcessEventsAndYield();
-    }
+    ProcessEventsAndDoSample();
   }
 
   // Process remaining tick events.
@@ -382,7 +367,6 @@ CpuProfiler::CpuProfiler(Isolate* isolate)
       next_profile_uid_(1),
       generator_(NULL),
       processor_(NULL),
-      need_to_stop_sampler_(false),
       is_profiling_(false) {
 }
 
@@ -396,7 +380,6 @@ CpuProfiler::CpuProfiler(Isolate* isolate,
       next_profile_uid_(1),
       generator_(test_generator),
       processor_(test_processor),
-      need_to_stop_sampler_(false),
       is_profiling_(false) {
 }
 
@@ -447,14 +430,8 @@ void CpuProfiler::StartProcessorIfNotStarted() {
     logger->LogAccessorCallbacks();
     LogBuiltins();
     // Enable stack sampling.
-    if (Sampler::CanSampleOnProfilerEventsProcessorThread()) {
-      sampler->SetHasProcessingThread(true);
-    }
+    sampler->SetHasProcessingThread(true);
     sampler->IncreaseProfilingDepth();
-    if (!sampler->IsActive()) {
-      sampler->Start();
-      need_to_stop_sampler_ = true;
-    }
     processor_->StartSynchronously();
   }
 }
@@ -487,20 +464,14 @@ void CpuProfiler::StopProcessorIfLastProfile(const char* title) {
 void CpuProfiler::StopProcessor() {
   Logger* logger = isolate_->logger();
   Sampler* sampler = reinterpret_cast<Sampler*>(logger->ticker_);
-  sampler->DecreaseProfilingDepth();
   is_profiling_ = false;
   processor_->StopSynchronously();
   delete processor_;
   delete generator_;
   processor_ = NULL;
   generator_ = NULL;
-  if (Sampler::CanSampleOnProfilerEventsProcessorThread()) {
-    sampler->SetHasProcessingThread(false);
-  }
-  if (need_to_stop_sampler_) {
-    sampler->Stop();
-    need_to_stop_sampler_ = false;
-  }
+  sampler->SetHasProcessingThread(false);
+  sampler->DecreaseProfilingDepth();
   logger->is_logging_ = saved_is_logging_;
 }
 
index e3d38ba..a6eccff 100644 (file)
@@ -163,7 +163,6 @@ class ProfilerEventsProcessor : public Thread {
   bool ProcessTicks();
 
   void ProcessEventsAndDoSample();
-  void ProcessEventsAndYield();
 
   ProfileGenerator* generator_;
   Sampler* sampler_;
@@ -266,7 +265,6 @@ class CpuProfiler : public CodeEventListener {
   ProfileGenerator* generator_;
   ProfilerEventsProcessor* processor_;
   bool saved_is_logging_;
-  bool need_to_stop_sampler_;
   bool is_profiling_;
 
   DISALLOW_COPY_AND_ASSIGN(CpuProfiler);
index 2852025..158d652 100644 (file)
@@ -626,9 +626,9 @@ class Ticker: public Sampler {
   }
 
   void ClearProfiler() {
-    DecreaseProfilingDepth();
     profiler_ = NULL;
     if (IsActive()) Stop();
+    DecreaseProfilingDepth();
   }
 
  private:
index 85597e5..0aaa1e9 100644 (file)
@@ -248,8 +248,25 @@ class SimulatorHelper {
 
 class SignalHandler : public AllStatic {
  public:
-  static inline void EnsureInstalled() {
-    if (signal_handler_installed_) return;
+  static void SetUp() { if (!mutex_) mutex_ = new Mutex(); }
+  static void TearDown() { delete mutex_; }
+
+  static void IncreaseSamplerCount() {
+    LockGuard<Mutex> lock_guard(mutex_);
+    if (++client_count_ == 1) Install();
+  }
+
+  static void DecreaseSamplerCount() {
+    LockGuard<Mutex> lock_guard(mutex_);
+    if (--client_count_ == 0) Restore();
+  }
+
+  static bool Installed() {
+    return signal_handler_installed_;
+  }
+
+ private:
+  static void Install() {
     struct sigaction sa;
     sa.sa_sigaction = &HandleProfilerSignal;
     sigemptyset(&sa.sa_mask);
@@ -258,23 +275,24 @@ class SignalHandler : public AllStatic {
         (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0);
   }
 
-  static inline void Restore() {
+  static void Restore() {
     if (signal_handler_installed_) {
       sigaction(SIGPROF, &old_signal_handler_, 0);
       signal_handler_installed_ = false;
     }
   }
 
-  static inline bool Installed() {
-    return signal_handler_installed_;
-  }
-
- private:
   static void HandleProfilerSignal(int signal, siginfo_t* info, void* context);
+  // Protects the process wide state below.
+  static Mutex* mutex_;
+  static int client_count_;
   static bool signal_handler_installed_;
   static struct sigaction old_signal_handler_;
 };
 
+
+Mutex* SignalHandler::mutex_ = NULL;
+int SignalHandler::client_count_ = 0;
 struct sigaction SignalHandler::old_signal_handler_;
 bool SignalHandler::signal_handler_installed_ = false;
 
@@ -299,7 +317,7 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
   }
 
   Sampler* sampler = isolate->logger()->sampler();
-  if (sampler == NULL || !sampler->IsActive()) return;
+  if (sampler == NULL) return;
 
   RegisterState state;
 
@@ -436,9 +454,6 @@ class SamplerThread : public Thread {
     ASSERT(instance_->interval_ == sampler->interval());
     instance_->active_samplers_.Add(sampler);
 
-#if defined(USE_SIGNALS)
-    SignalHandler::EnsureInstalled();
-#endif
     if (need_to_start) instance_->StartSynchronously();
   }
 
@@ -457,9 +472,6 @@ class SamplerThread : public Thread {
       if (instance_->active_samplers_.is_empty()) {
         instance_to_remove = instance_;
         instance_ = NULL;
-#if defined(USE_SIGNALS)
-        SignalHandler::Restore();
-#endif
       }
     }
 
@@ -548,12 +560,18 @@ DISABLE_ASAN void TickSample::Init(Isolate* isolate,
 
 
 void Sampler::SetUp() {
+#if defined(USE_SIGNALS)
+  SignalHandler::SetUp();
+#endif
   SamplerThread::SetUp();
 }
 
 
 void Sampler::TearDown() {
   SamplerThread::TearDown();
+#if defined(USE_SIGNALS)
+  SignalHandler::TearDown();
+#endif
 }
 
 
@@ -589,6 +607,22 @@ void Sampler::Stop() {
 }
 
 
+void Sampler::IncreaseProfilingDepth() {
+  NoBarrier_AtomicIncrement(&profiling_, 1);
+#if defined(USE_SIGNALS)
+  SignalHandler::IncreaseSamplerCount();
+#endif
+}
+
+
+void Sampler::DecreaseProfilingDepth() {
+#if defined(USE_SIGNALS)
+  SignalHandler::DecreaseSamplerCount();
+#endif
+  NoBarrier_AtomicIncrement(&profiling_, -1);
+}
+
+
 void Sampler::SampleStack(const RegisterState& state) {
   TickSample* sample = isolate_->cpu_profiler()->StartTickSample();
   TickSample sample_obj;
@@ -606,17 +640,6 @@ void Sampler::SampleStack(const RegisterState& state) {
 }
 
 
-bool Sampler::CanSampleOnProfilerEventsProcessorThread() {
-#if defined(USE_SIGNALS)
-  return true;
-#elif V8_OS_WIN || V8_OS_CYGWIN
-  return true;
-#else
-  return false;
-#endif
-}
-
-
 #if defined(USE_SIGNALS)
 
 void Sampler::DoSample() {
index cd65b12..b17a2ed 100644 (file)
@@ -99,16 +99,15 @@ class Sampler {
     return NoBarrier_Load(&profiling_) > 0 &&
         !NoBarrier_Load(&has_processing_thread_);
   }
-  void IncreaseProfilingDepth() { NoBarrier_AtomicIncrement(&profiling_, 1); }
-  void DecreaseProfilingDepth() { NoBarrier_AtomicIncrement(&profiling_, -1); }
+  void IncreaseProfilingDepth();
+  void DecreaseProfilingDepth();
 
   // Whether the sampler is running (that is, consumes resources).
   bool IsActive() const { return NoBarrier_Load(&active_); }
 
+  void DoSample();
   // If true next sample must be initiated on the profiler event processor
   // thread right after latest sample is processed.
-  static bool CanSampleOnProfilerEventsProcessorThread();
-  void DoSample();
   void SetHasProcessingThread(bool value) {
     NoBarrier_Store(&has_processing_thread_, value);
   }