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() {
}
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_;
}
......
......@@ -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);
......
......@@ -626,9 +626,9 @@ class Ticker: public Sampler {
}
void ClearProfiler() {
DecreaseProfilingDepth();
profiler_ = NULL;
if (IsActive()) Stop();
DecreaseProfilingDepth();
}
private:
......
......@@ -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() {
......
......@@ -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);
}
......
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