Commit 6964a9e0 authored by alph's avatar alph Committed by Commit bot

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

Review URL: https://codereview.chromium.org/1118533003

Cr-Commit-Position: refs/heads/master@{#28211}
parent d5e66a70
......@@ -219,9 +219,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()));
}
......
......@@ -812,8 +812,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()));
}
......
......@@ -190,8 +190,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();
......
......@@ -120,16 +120,32 @@ ProfilerEventsProcessor::SampleProcessingResult
void ProfilerEventsProcessor::Run() {
while (!!base::NoBarrier_Load(&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();
......
......@@ -63,7 +63,8 @@ class OptimizingCompileDispatcher::CompileTask : public v8::Task {
TimerEventScope<TimerEventRecompileConcurrent> timer(isolate_);
if (dispatcher->recompilation_delay_ != 0) {
base::OS::Sleep(dispatcher->recompilation_delay_);
base::OS::Sleep(base::TimeDelta::FromMilliseconds(
dispatcher->recompilation_delay_));
}
dispatcher->CompileNext(dispatcher->NextInput(true));
......
......@@ -176,7 +176,7 @@ RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
sync_with_compiler_thread) {
while (function->IsInOptimizationQueue()) {
isolate->optimizing_compile_dispatcher()->InstallOptimizedFunctions();
base::OS::Sleep(50);
base::OS::Sleep(base::TimeDelta::FromMilliseconds(50));
}
}
if (FLAG_always_opt) {
......
......@@ -558,7 +558,7 @@ class SamplerThread : public base::Thread {
sampler->DoSample();
}
}
base::OS::Sleep(interval_);
base::OS::Sleep(base::TimeDelta::FromMilliseconds(interval_));
}
}
......
......@@ -13095,10 +13095,12 @@ class RegExpInterruptionThread : public v8::base::Thread {
v8::base::NoBarrier_Load(&regexp_interruption_data.loop_count) < 7;
v8::base::NoBarrier_AtomicIncrement(
&regexp_interruption_data.loop_count, 1)) {
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_);
}
......@@ -18812,7 +18814,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));
......@@ -18823,7 +18825,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;
......
......@@ -807,7 +807,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;
}
}
......
......@@ -190,7 +190,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));
}
}
};
......@@ -210,7 +210,7 @@ class LoopingNonJsThread : public LoopingThread {
SignalRunning();
while (IsRunning()) {
i = std::sin(i);
i::OS::Sleep(1);
i::OS::Sleep(v8::base::TimeDelta::FromMilliseconds(1));
}
}
};
......
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