}
-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.
next_profile_uid_(1),
generator_(NULL),
processor_(NULL),
- need_to_stop_sampler_(false),
is_profiling_(false) {
}
next_profile_uid_(1),
generator_(test_generator),
processor_(test_processor),
- need_to_stop_sampler_(false),
is_profiling_(false) {
}
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();
}
}
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_;
}
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);
(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;
}
Sampler* sampler = isolate->logger()->sampler();
- if (sampler == NULL || !sampler->IsActive()) return;
+ if (sampler == NULL) return;
RegisterState state;
ASSERT(instance_->interval_ == sampler->interval());
instance_->active_samplers_.Add(sampler);
-#if defined(USE_SIGNALS)
- SignalHandler::EnsureInstalled();
-#endif
if (need_to_start) instance_->StartSynchronously();
}
if (instance_->active_samplers_.is_empty()) {
instance_to_remove = instance_;
instance_ = NULL;
-#if defined(USE_SIGNALS)
- SignalHandler::Restore();
-#endif
}
}
void Sampler::SetUp() {
+#if defined(USE_SIGNALS)
+ SignalHandler::SetUp();
+#endif
SamplerThread::SetUp();
}
void Sampler::TearDown() {
SamplerThread::TearDown();
+#if defined(USE_SIGNALS)
+ SignalHandler::TearDown();
+#endif
}
}
+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;
}
-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() {
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);
}