summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Tunnicliffe <mike.tunnicliffe@uk.ibm.com>2015-05-08 07:43:26 -0400
committerJulien Gilli <julien.gilli@joyent.com>2015-05-11 18:14:55 -0700
commit80cdae855fe349f0cf3b5c646060e4799107392f (patch)
tree8020eb1593a3db43fa5c63d85625d3c9c2dd0c0d
parente1cc263ce8bfc14681cb277863f7d19a807bf551 (diff)
downloadnode-new-80cdae855fe349f0cf3b5c646060e4799107392f.tar.gz
deps: don't busy loop in v8 cpu profiler thread
Backport 6964a9e0685fa186d9d9b7907be17505e839db1a from upstream v8. Original commit message: Make CPU profiler do not hog 100% of CPU. Tick event processor should not stay in a tight loop when there's nothing to do. It can go sleep until next sample event. LOG=N BUG=v8:3967 Committed: https://crrev.com/6964a9e0685fa186d9d9b7907be17505e839db1a Cr-Commit-Position: refs/heads/master@{#28211} Fixes #25137 Related: #9439, #8789 PR: #25268 PR-URL: https://github.com/joyent/node/pull/25268 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Julien Gilli <jgilli@fastmail.fm>
-rw-r--r--deps/v8/src/base/platform/platform-posix.cc5
-rw-r--r--deps/v8/src/base/platform/platform-win32.cc4
-rw-r--r--deps/v8/src/base/platform/platform.h4
-rw-r--r--deps/v8/src/cpu-profiler.cc26
-rw-r--r--deps/v8/src/optimizing-compiler-thread.cc3
-rw-r--r--deps/v8/src/runtime.cc2
-rw-r--r--deps/v8/src/sampler.cc2
-rw-r--r--deps/v8/test/cctest/test-api.cc10
-rw-r--r--deps/v8/test/cctest/test-cpu-profiler.cc2
-rw-r--r--deps/v8/test/cctest/test-log.cc4
10 files changed, 40 insertions, 22 deletions
diff --git a/deps/v8/src/base/platform/platform-posix.cc b/deps/v8/src/base/platform/platform-posix.cc
index 771634e24e..f3b42d0b00 100644
--- a/deps/v8/src/base/platform/platform-posix.cc
+++ b/deps/v8/src/base/platform/platform-posix.cc
@@ -268,9 +268,8 @@ size_t OS::AllocateAlignment() {
}
-void OS::Sleep(int milliseconds) {
- useconds_t ms = static_cast<useconds_t>(milliseconds);
- usleep(1000 * ms);
+void OS::Sleep(TimeDelta interval) {
+ usleep(static_cast<useconds_t>(interval.InMicroseconds()));
}
diff --git a/deps/v8/src/base/platform/platform-win32.cc b/deps/v8/src/base/platform/platform-win32.cc
index 9f106785eb..f18bb99237 100644
--- a/deps/v8/src/base/platform/platform-win32.cc
+++ b/deps/v8/src/base/platform/platform-win32.cc
@@ -821,8 +821,8 @@ void OS::Guard(void* address, const size_t size) {
}
-void OS::Sleep(int milliseconds) {
- ::Sleep(milliseconds);
+void OS::Sleep(TimeDelta interval) {
+ ::Sleep(static_cast<DWORD>(interval.InMilliseconds()));
}
diff --git a/deps/v8/src/base/platform/platform.h b/deps/v8/src/base/platform/platform.h
index 9567572d80..40ef8b85a0 100644
--- a/deps/v8/src/base/platform/platform.h
+++ b/deps/v8/src/base/platform/platform.h
@@ -227,8 +227,8 @@ class OS {
// Get the Alignment guaranteed by Allocate().
static size_t AllocateAlignment();
- // Sleep for a number of milliseconds.
- static void Sleep(const int milliseconds);
+ // Sleep for a specified time interval.
+ static void Sleep(TimeDelta interval);
// Abort the current process.
static void Abort();
diff --git a/deps/v8/src/cpu-profiler.cc b/deps/v8/src/cpu-profiler.cc
index 68a565c73a..f53afdd252 100644
--- a/deps/v8/src/cpu-profiler.cc
+++ b/deps/v8/src/cpu-profiler.cc
@@ -108,16 +108,32 @@ ProfilerEventsProcessor::SampleProcessingResult
void ProfilerEventsProcessor::Run() {
while (running_) {
- base::ElapsedTimer timer;
- timer.Start();
- // Keep processing existing events until we need to do next sample.
+ base::TimeTicks nextSampleTime =
+ base::TimeTicks::HighResolutionNow() + period_;
+ base::TimeTicks now;
+ SampleProcessingResult result;
+ // Keep processing existing events until we need to do next sample
+ // or the ticks buffer is empty.
do {
- if (FoundSampleForNextCodeEvent == ProcessOneSample()) {
+ result = ProcessOneSample();
+ if (result == FoundSampleForNextCodeEvent) {
// All ticks of the current last_processed_code_event_id_ are
// processed, proceed to the next code event.
ProcessCodeEvent();
}
- } while (!timer.HasExpired(period_));
+ now = base::TimeTicks::HighResolutionNow();
+ } while (result != NoSamplesInQueue && now < nextSampleTime);
+
+ if (nextSampleTime > now) {
+#if V8_OS_WIN
+ // Do not use Sleep on Windows as it is very imprecise.
+ // Could be up to 16ms jitter, which is unacceptable for the purpose.
+ while (base::TimeTicks::HighResolutionNow() < nextSampleTime) {
+ }
+#else
+ base::OS::Sleep(nextSampleTime - now);
+#endif
+ }
// Schedule next sample. sampler_ is NULL in tests.
if (sampler_) sampler_->DoSample();
diff --git a/deps/v8/src/optimizing-compiler-thread.cc b/deps/v8/src/optimizing-compiler-thread.cc
index 0074adbefe..c9bc538d65 100644
--- a/deps/v8/src/optimizing-compiler-thread.cc
+++ b/deps/v8/src/optimizing-compiler-thread.cc
@@ -48,7 +48,8 @@ void OptimizingCompilerThread::Run() {
TimerEventScope<TimerEventRecompileConcurrent> timer(isolate_);
if (FLAG_concurrent_recompilation_delay != 0) {
- base::OS::Sleep(FLAG_concurrent_recompilation_delay);
+ base::OS::Sleep(base::TimeDelta::FromMilliseconds(
+ FLAG_concurrent_recompilation_delay));
}
switch (static_cast<StopFlag>(base::Acquire_Load(&stop_thread_))) {
diff --git a/deps/v8/src/runtime.cc b/deps/v8/src/runtime.cc
index d29c861017..7191ac0b8a 100644
--- a/deps/v8/src/runtime.cc
+++ b/deps/v8/src/runtime.cc
@@ -8641,7 +8641,7 @@ RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
sync_with_compiler_thread) {
while (function->IsInOptimizationQueue()) {
isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
- base::OS::Sleep(50);
+ base::OS::Sleep(base::TimeDelta::FromMilliseconds(50));
}
}
if (FLAG_always_opt) {
diff --git a/deps/v8/src/sampler.cc b/deps/v8/src/sampler.cc
index 413b6be906..0be31b51b0 100644
--- a/deps/v8/src/sampler.cc
+++ b/deps/v8/src/sampler.cc
@@ -550,7 +550,7 @@ class SamplerThread : public base::Thread {
sampler->DoSample();
}
}
- base::OS::Sleep(interval_);
+ base::OS::Sleep(base::TimeDelta::FromMilliseconds(interval_));
}
}
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index 2ac657d7f9..9666a10fd7 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -15166,10 +15166,12 @@ class RegExpInterruptionThread : public v8::base::Thread {
for (regexp_interruption_data.loop_count = 0;
regexp_interruption_data.loop_count < 7;
regexp_interruption_data.loop_count++) {
- v8::base::OS::Sleep(50); // Wait a bit before requesting GC.
+ // Wait a bit before requesting GC.
+ v8::base::OS::Sleep(v8::base::TimeDelta::FromMilliseconds(50));
reinterpret_cast<i::Isolate*>(isolate_)->stack_guard()->RequestGC();
}
- v8::base::OS::Sleep(50); // Wait a bit before terminating.
+ // Wait a bit before terminating.
+ v8::base::OS::Sleep(v8::base::TimeDelta::FromMilliseconds(50));
v8::V8::TerminateExecution(isolate_);
}
@@ -21516,7 +21518,7 @@ class ThreadInterruptTest {
struct sigaction action;
// Ensure that we'll enter waiting condition
- v8::base::OS::Sleep(100);
+ v8::base::OS::Sleep(v8::base::TimeDelta::FromMilliseconds(100));
// Setup signal handler
memset(&action, 0, sizeof(action));
@@ -21527,7 +21529,7 @@ class ThreadInterruptTest {
kill(getpid(), SIGCHLD);
// Ensure that if wait has returned because of error
- v8::base::OS::Sleep(100);
+ v8::base::OS::Sleep(v8::base::TimeDelta::FromMilliseconds(100));
// Set value and signal semaphore
test_->sem_value_ = 1;
diff --git a/deps/v8/test/cctest/test-cpu-profiler.cc b/deps/v8/test/cctest/test-cpu-profiler.cc
index 6051c3fd7f..8536c9b12e 100644
--- a/deps/v8/test/cctest/test-cpu-profiler.cc
+++ b/deps/v8/test/cctest/test-cpu-profiler.cc
@@ -793,7 +793,7 @@ class TestApiCallbacks {
double start = v8::base::OS::TimeCurrentMillis();
double duration = 0;
while (duration < min_duration_ms_) {
- v8::base::OS::Sleep(1);
+ v8::base::OS::Sleep(v8::base::TimeDelta::FromMilliseconds(1));
duration = v8::base::OS::TimeCurrentMillis() - start;
}
}
diff --git a/deps/v8/test/cctest/test-log.cc b/deps/v8/test/cctest/test-log.cc
index 6800215081..0999e53877 100644
--- a/deps/v8/test/cctest/test-log.cc
+++ b/deps/v8/test/cctest/test-log.cc
@@ -186,7 +186,7 @@ class LoopingJsThread : public LoopingThread {
"var j; for (var i=0; i<10000; ++i) { j = Math.sin(i); }");
}
context.Dispose();
- i::OS::Sleep(1);
+ i::OS::Sleep(v8::base::TimeDelta::FromMilliseconds(1));
}
}
};
@@ -206,7 +206,7 @@ class LoopingNonJsThread : public LoopingThread {
SignalRunning();
while (IsRunning()) {
i = std::sin(i);
- i::OS::Sleep(1);
+ i::OS::Sleep(v8::base::TimeDelta::FromMilliseconds(1));
}
}
};