From 7fc915b701f31002a85cf76aa2963f9b67f4a766 Mon Sep 17 00:00:00 2001 From: "yurys@chromium.org" Date: Thu, 29 Aug 2013 14:03:38 +0000 Subject: [PATCH] Do not start sampler thread when CpuProfiler is active 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 | 37 +++----------------------- src/cpu-profiler.h | 2 -- src/log.cc | 2 +- src/sampler.cc | 75 ++++++++++++++++++++++++++++++++++------------------- src/sampler.h | 7 +++-- 5 files changed, 57 insertions(+), 66 deletions(-) diff --git a/src/cpu-profiler.cc b/src/cpu-profiler.cc index 74d1f03..34bebb8 100644 --- a/src/cpu-profiler.cc +++ b/src/cpu-profiler.cc @@ -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(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_; } diff --git a/src/cpu-profiler.h b/src/cpu-profiler.h index e3d38ba..a6eccff 100644 --- a/src/cpu-profiler.h +++ b/src/cpu-profiler.h @@ -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); diff --git a/src/log.cc b/src/log.cc index 2852025..158d652 100644 --- a/src/log.cc +++ b/src/log.cc @@ -626,9 +626,9 @@ class Ticker: public Sampler { } void ClearProfiler() { - DecreaseProfilingDepth(); profiler_ = NULL; if (IsActive()) Stop(); + DecreaseProfilingDepth(); } private: diff --git a/src/sampler.cc b/src/sampler.cc index 85597e5..0aaa1e9 100644 --- a/src/sampler.cc +++ b/src/sampler.cc @@ -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 lock_guard(mutex_); + if (++client_count_ == 1) Install(); + } + + static void DecreaseSamplerCount() { + LockGuard 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() { diff --git a/src/sampler.h b/src/sampler.h index cd65b12..b17a2ed 100644 --- a/src/sampler.h +++ b/src/sampler.h @@ -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); } -- 2.7.4