Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1387)

Unified Diff: src/platform-linux.cc

Issue 12321046: Send SIGPROF signals on the profiler event processor thread (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Fixed typo: Profler->Profiler Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/platform-freebsd.cc ('k') | src/platform-macos.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/platform-linux.cc
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index 0359b2d79e98d59f8ea8f1f5d7970607b581bc44..f571b990217b569b9ee1beeb95ce1e21d62c0920 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -1127,29 +1127,27 @@ static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
}
-class Sampler::PlatformData : public Malloced {
+class CpuProfilerSignalHandler {
public:
- PlatformData() : vm_tid_(GetThreadID()) {}
-
- int vm_tid() const { return vm_tid_; }
-
- private:
- const int vm_tid_;
-};
-
-
-class SignalSender : public Thread {
- public:
- static const int kSignalSenderStackSize = 64 * KB;
-
- explicit SignalSender(int interval)
- : Thread(Thread::Options("SignalSender", kSignalSenderStackSize)),
- vm_tgid_(getpid()),
- interval_(interval) {}
-
static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); }
static void TearDown() { delete mutex_; }
+ static bool RegisterProfilingSampler() {
+ ScopedLock lock(mutex_);
+ if (!profiling_samplers_count_) InstallSignalHandler();
+ ++profiling_samplers_count_;
+ return signal_handler_installed_;
+ }
+
+ static void UnregisterProfilingSampler() {
+ ScopedLock lock(mutex_);
+ ASSERT(profiling_samplers_count_ > 0);
+ if (!profiling_samplers_count_) return;
+ if (profiling_samplers_count_ == 1) RestoreSignalHandler();
+ --profiling_samplers_count_;
+ }
+
+ private:
static void InstallSignalHandler() {
struct sigaction sa;
sa.sa_sigaction = ProfilerSignalHandler;
@@ -1166,6 +1164,61 @@ class SignalSender : public Thread {
}
}
+ // Protects the process wide state below.
+ static Mutex* mutex_;
+ static int profiling_samplers_count_;
+ static bool signal_handler_installed_;
+ static struct sigaction old_signal_handler_;
+};
+
+
+Mutex* CpuProfilerSignalHandler::mutex_ = NULL;
+int CpuProfilerSignalHandler::profiling_samplers_count_ = 0;
+bool CpuProfilerSignalHandler::signal_handler_installed_ = false;
+struct sigaction CpuProfilerSignalHandler::old_signal_handler_;
+
+
+class Sampler::PlatformData : public Malloced {
+ public:
+ PlatformData()
+ : vm_tgid_(getpid()),
+ vm_tid_(GetThreadID()),
+ signal_handler_installed_(false) {}
+
+ void set_signal_handler_installed(bool value) {
+ signal_handler_installed_ = value;
+ }
+
+ void SendProfilingSignal() {
+ if (!signal_handler_installed_) return;
+ // Glibc doesn't provide a wrapper for tgkill(2).
+#if defined(ANDROID)
+ syscall(__NR_tgkill, vm_tgid_, vm_tid_, SIGPROF);
+#else
+ int result = syscall(SYS_tgkill, vm_tgid_, vm_tid_, SIGPROF);
+ USE(result);
+ ASSERT(result == 0);
+#endif
+ }
+
+ private:
+ const int vm_tgid_;
+ const int vm_tid_;
+ bool signal_handler_installed_;
+};
+
+
+class SignalSender : public Thread {
+ public:
+ static const int kSignalSenderStackSize = 64 * KB;
+
+ explicit SignalSender(int interval)
+ : Thread(Thread::Options("SignalSender", kSignalSenderStackSize)),
+ interval_(interval) {}
+
+ static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); }
+ static void TearDown() { delete mutex_; }
+
static void AddActiveSampler(Sampler* sampler) {
ScopedLock lock(mutex_);
SamplerRegistry::AddActiveSampler(sampler);
@@ -1186,7 +1239,6 @@ class SignalSender : public Thread {
RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
delete instance_;
instance_ = NULL;
- RestoreSignalHandler();
}
}
@@ -1198,10 +1250,8 @@ class SignalSender : public Thread {
// When CPU profiling is enabled both JavaScript and C++ code is
// profiled. We must not suspend.
if (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS) {
- if (!signal_handler_installed_) InstallSignalHandler();
SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this);
} else {
- if (signal_handler_installed_) RestoreSignalHandler();
if (RuntimeProfiler::WaitForSomeIsolateToEnterJS()) continue;
}
Sleep(); // TODO(svenpanne) Figure out if OS:Sleep(interval_) is enough.
@@ -1210,20 +1260,7 @@ class SignalSender : public Thread {
static void DoCpuProfile(Sampler* sampler, void* raw_sender) {
if (!sampler->IsProfiling()) return;
- SignalSender* sender = reinterpret_cast<SignalSender*>(raw_sender);
- sender->SendProfilingSignal(sampler->platform_data()->vm_tid());
- }
-
- void SendProfilingSignal(int tid) {
- if (!signal_handler_installed_) return;
- // Glibc doesn't provide a wrapper for tgkill(2).
-#if defined(ANDROID)
- syscall(__NR_tgkill, vm_tgid_, tid, SIGPROF);
-#else
- int result = syscall(SYS_tgkill, vm_tgid_, tid, SIGPROF);
- USE(result);
- ASSERT(result == 0);
-#endif
+ sampler->DoSample();
}
void Sleep() {
@@ -1247,13 +1284,11 @@ class SignalSender : public Thread {
#endif // ANDROID
}
- const int vm_tgid_;
const int interval_;
// Protects the process wide state below.
static Mutex* mutex_;
static SignalSender* instance_;
- static bool signal_handler_installed_;
static struct sigaction old_signal_handler_;
private:
@@ -1264,7 +1299,6 @@ class SignalSender : public Thread {
Mutex* SignalSender::mutex_ = NULL;
SignalSender* SignalSender::instance_ = NULL;
struct sigaction SignalSender::old_signal_handler_;
-bool SignalSender::signal_handler_installed_ = false;
void OS::SetUp() {
@@ -1292,10 +1326,12 @@ void OS::SetUp() {
}
#endif
SignalSender::SetUp();
+ CpuProfilerSignalHandler::SetUp();
}
void OS::TearDown() {
+ CpuProfilerSignalHandler::TearDown();
SignalSender::TearDown();
delete limit_mutex;
}
@@ -1305,6 +1341,7 @@ Sampler::Sampler(Isolate* isolate, int interval)
: isolate_(isolate),
interval_(interval),
profiling_(false),
+ has_processing_thread_(false),
active_(false),
samples_taken_(0) {
data_ = new PlatformData;
@@ -1331,4 +1368,26 @@ void Sampler::Stop() {
}
+bool Sampler::CanSampleOnProfilerEventsProcessorThread() {
+ return true;
+}
+
+
+void Sampler::DoSample() {
+ platform_data()->SendProfilingSignal();
+}
+
+
+void Sampler::StartProfiling() {
+ platform_data()->set_signal_handler_installed(
+ CpuProfilerSignalHandler::RegisterProfilingSampler());
+}
+
+
+void Sampler::StopProfiling() {
+ CpuProfilerSignalHandler::UnregisterProfilingSampler();
+ platform_data()->set_signal_handler_installed(false);
+}
+
+
} } // namespace v8::internal
« no previous file with comments | « src/platform-freebsd.cc ('k') | src/platform-macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698