Commit 7fc915b7 authored by yurys@chromium.org's avatar yurys@chromium.org

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
parent dc14d6f4
...@@ -139,24 +139,9 @@ void ProfilerEventsProcessor::ProcessEventsAndDoSample() { ...@@ -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() { void ProfilerEventsProcessor::Run() {
while (running_) { while (running_) {
if (Sampler::CanSampleOnProfilerEventsProcessorThread()) { ProcessEventsAndDoSample();
ProcessEventsAndDoSample();
} else {
ProcessEventsAndYield();
}
} }
// Process remaining tick events. // Process remaining tick events.
...@@ -382,7 +367,6 @@ CpuProfiler::CpuProfiler(Isolate* isolate) ...@@ -382,7 +367,6 @@ CpuProfiler::CpuProfiler(Isolate* isolate)
next_profile_uid_(1), next_profile_uid_(1),
generator_(NULL), generator_(NULL),
processor_(NULL), processor_(NULL),
need_to_stop_sampler_(false),
is_profiling_(false) { is_profiling_(false) {
} }
...@@ -396,7 +380,6 @@ CpuProfiler::CpuProfiler(Isolate* isolate, ...@@ -396,7 +380,6 @@ CpuProfiler::CpuProfiler(Isolate* isolate,
next_profile_uid_(1), next_profile_uid_(1),
generator_(test_generator), generator_(test_generator),
processor_(test_processor), processor_(test_processor),
need_to_stop_sampler_(false),
is_profiling_(false) { is_profiling_(false) {
} }
...@@ -447,14 +430,8 @@ void CpuProfiler::StartProcessorIfNotStarted() { ...@@ -447,14 +430,8 @@ void CpuProfiler::StartProcessorIfNotStarted() {
logger->LogAccessorCallbacks(); logger->LogAccessorCallbacks();
LogBuiltins(); LogBuiltins();
// Enable stack sampling. // Enable stack sampling.
if (Sampler::CanSampleOnProfilerEventsProcessorThread()) { sampler->SetHasProcessingThread(true);
sampler->SetHasProcessingThread(true);
}
sampler->IncreaseProfilingDepth(); sampler->IncreaseProfilingDepth();
if (!sampler->IsActive()) {
sampler->Start();
need_to_stop_sampler_ = true;
}
processor_->StartSynchronously(); processor_->StartSynchronously();
} }
} }
...@@ -487,20 +464,14 @@ void CpuProfiler::StopProcessorIfLastProfile(const char* title) { ...@@ -487,20 +464,14 @@ void CpuProfiler::StopProcessorIfLastProfile(const char* title) {
void CpuProfiler::StopProcessor() { void CpuProfiler::StopProcessor() {
Logger* logger = isolate_->logger(); Logger* logger = isolate_->logger();
Sampler* sampler = reinterpret_cast<Sampler*>(logger->ticker_); Sampler* sampler = reinterpret_cast<Sampler*>(logger->ticker_);
sampler->DecreaseProfilingDepth();
is_profiling_ = false; is_profiling_ = false;
processor_->StopSynchronously(); processor_->StopSynchronously();
delete processor_; delete processor_;
delete generator_; delete generator_;
processor_ = NULL; processor_ = NULL;
generator_ = NULL; generator_ = NULL;
if (Sampler::CanSampleOnProfilerEventsProcessorThread()) { sampler->SetHasProcessingThread(false);
sampler->SetHasProcessingThread(false); sampler->DecreaseProfilingDepth();
}
if (need_to_stop_sampler_) {
sampler->Stop();
need_to_stop_sampler_ = false;
}
logger->is_logging_ = saved_is_logging_; logger->is_logging_ = saved_is_logging_;
} }
......
...@@ -163,7 +163,6 @@ class ProfilerEventsProcessor : public Thread { ...@@ -163,7 +163,6 @@ class ProfilerEventsProcessor : public Thread {
bool ProcessTicks(); bool ProcessTicks();
void ProcessEventsAndDoSample(); void ProcessEventsAndDoSample();
void ProcessEventsAndYield();
ProfileGenerator* generator_; ProfileGenerator* generator_;
Sampler* sampler_; Sampler* sampler_;
...@@ -266,7 +265,6 @@ class CpuProfiler : public CodeEventListener { ...@@ -266,7 +265,6 @@ class CpuProfiler : public CodeEventListener {
ProfileGenerator* generator_; ProfileGenerator* generator_;
ProfilerEventsProcessor* processor_; ProfilerEventsProcessor* processor_;
bool saved_is_logging_; bool saved_is_logging_;
bool need_to_stop_sampler_;
bool is_profiling_; bool is_profiling_;
DISALLOW_COPY_AND_ASSIGN(CpuProfiler); DISALLOW_COPY_AND_ASSIGN(CpuProfiler);
......
...@@ -626,9 +626,9 @@ class Ticker: public Sampler { ...@@ -626,9 +626,9 @@ class Ticker: public Sampler {
} }
void ClearProfiler() { void ClearProfiler() {
DecreaseProfilingDepth();
profiler_ = NULL; profiler_ = NULL;
if (IsActive()) Stop(); if (IsActive()) Stop();
DecreaseProfilingDepth();
} }
private: private:
......
...@@ -248,8 +248,25 @@ class SimulatorHelper { ...@@ -248,8 +248,25 @@ class SimulatorHelper {
class SignalHandler : public AllStatic { class SignalHandler : public AllStatic {
public: public:
static inline void EnsureInstalled() { static void SetUp() { if (!mutex_) mutex_ = new Mutex(); }
if (signal_handler_installed_) return; 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; struct sigaction sa;
sa.sa_sigaction = &HandleProfilerSignal; sa.sa_sigaction = &HandleProfilerSignal;
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
...@@ -258,23 +275,24 @@ class SignalHandler : public AllStatic { ...@@ -258,23 +275,24 @@ class SignalHandler : public AllStatic {
(sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0);
} }
static inline void Restore() { static void Restore() {
if (signal_handler_installed_) { if (signal_handler_installed_) {
sigaction(SIGPROF, &old_signal_handler_, 0); sigaction(SIGPROF, &old_signal_handler_, 0);
signal_handler_installed_ = false; signal_handler_installed_ = false;
} }
} }
static inline bool Installed() {
return signal_handler_installed_;
}
private:
static void HandleProfilerSignal(int signal, siginfo_t* info, void* context); 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 bool signal_handler_installed_;
static struct sigaction old_signal_handler_; static struct sigaction old_signal_handler_;
}; };
Mutex* SignalHandler::mutex_ = NULL;
int SignalHandler::client_count_ = 0;
struct sigaction SignalHandler::old_signal_handler_; struct sigaction SignalHandler::old_signal_handler_;
bool SignalHandler::signal_handler_installed_ = false; bool SignalHandler::signal_handler_installed_ = false;
...@@ -299,7 +317,7 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, ...@@ -299,7 +317,7 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
} }
Sampler* sampler = isolate->logger()->sampler(); Sampler* sampler = isolate->logger()->sampler();
if (sampler == NULL || !sampler->IsActive()) return; if (sampler == NULL) return;
RegisterState state; RegisterState state;
...@@ -436,9 +454,6 @@ class SamplerThread : public Thread { ...@@ -436,9 +454,6 @@ class SamplerThread : public Thread {
ASSERT(instance_->interval_ == sampler->interval()); ASSERT(instance_->interval_ == sampler->interval());
instance_->active_samplers_.Add(sampler); instance_->active_samplers_.Add(sampler);
#if defined(USE_SIGNALS)
SignalHandler::EnsureInstalled();
#endif
if (need_to_start) instance_->StartSynchronously(); if (need_to_start) instance_->StartSynchronously();
} }
...@@ -457,9 +472,6 @@ class SamplerThread : public Thread { ...@@ -457,9 +472,6 @@ class SamplerThread : public Thread {
if (instance_->active_samplers_.is_empty()) { if (instance_->active_samplers_.is_empty()) {
instance_to_remove = instance_; instance_to_remove = instance_;
instance_ = NULL; instance_ = NULL;
#if defined(USE_SIGNALS)
SignalHandler::Restore();
#endif
} }
} }
...@@ -548,12 +560,18 @@ DISABLE_ASAN void TickSample::Init(Isolate* isolate, ...@@ -548,12 +560,18 @@ DISABLE_ASAN void TickSample::Init(Isolate* isolate,
void Sampler::SetUp() { void Sampler::SetUp() {
#if defined(USE_SIGNALS)
SignalHandler::SetUp();
#endif
SamplerThread::SetUp(); SamplerThread::SetUp();
} }
void Sampler::TearDown() { void Sampler::TearDown() {
SamplerThread::TearDown(); SamplerThread::TearDown();
#if defined(USE_SIGNALS)
SignalHandler::TearDown();
#endif
} }
...@@ -589,6 +607,22 @@ void Sampler::Stop() { ...@@ -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) { void Sampler::SampleStack(const RegisterState& state) {
TickSample* sample = isolate_->cpu_profiler()->StartTickSample(); TickSample* sample = isolate_->cpu_profiler()->StartTickSample();
TickSample sample_obj; TickSample sample_obj;
...@@ -606,17 +640,6 @@ void Sampler::SampleStack(const RegisterState& state) { ...@@ -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) #if defined(USE_SIGNALS)
void Sampler::DoSample() { void Sampler::DoSample() {
......
...@@ -99,16 +99,15 @@ class Sampler { ...@@ -99,16 +99,15 @@ class Sampler {
return NoBarrier_Load(&profiling_) > 0 && return NoBarrier_Load(&profiling_) > 0 &&
!NoBarrier_Load(&has_processing_thread_); !NoBarrier_Load(&has_processing_thread_);
} }
void IncreaseProfilingDepth() { NoBarrier_AtomicIncrement(&profiling_, 1); } void IncreaseProfilingDepth();
void DecreaseProfilingDepth() { NoBarrier_AtomicIncrement(&profiling_, -1); } void DecreaseProfilingDepth();
// Whether the sampler is running (that is, consumes resources). // Whether the sampler is running (that is, consumes resources).
bool IsActive() const { return NoBarrier_Load(&active_); } bool IsActive() const { return NoBarrier_Load(&active_); }
void DoSample();
// If true next sample must be initiated on the profiler event processor // If true next sample must be initiated on the profiler event processor
// thread right after latest sample is processed. // thread right after latest sample is processed.
static bool CanSampleOnProfilerEventsProcessorThread();
void DoSample();
void SetHasProcessingThread(bool value) { void SetHasProcessingThread(bool value) {
NoBarrier_Store(&has_processing_thread_, value); NoBarrier_Store(&has_processing_thread_, value);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment