Skip to content

Commit 80cdae8

Browse files
tunniclmJulien Gilli
authored and
Julien Gilli
committed
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: nodejs/node-v0.x-archive#25268 Reviewed-By: Michael Dawson <[email protected]> Reviewed-By: Julien Gilli <[email protected]>
1 parent e1cc263 commit 80cdae8

10 files changed

+40
-22
lines changed

deps/v8/src/base/platform/platform-posix.cc

+2-3
Original file line numberDiff line numberDiff line change
@@ -268,9 +268,8 @@ size_t OS::AllocateAlignment() {
268268
}
269269

270270

271-
void OS::Sleep(int milliseconds) {
272-
useconds_t ms = static_cast<useconds_t>(milliseconds);
273-
usleep(1000 * ms);
271+
void OS::Sleep(TimeDelta interval) {
272+
usleep(static_cast<useconds_t>(interval.InMicroseconds()));
274273
}
275274

276275

deps/v8/src/base/platform/platform-win32.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -821,8 +821,8 @@ void OS::Guard(void* address, const size_t size) {
821821
}
822822

823823

824-
void OS::Sleep(int milliseconds) {
825-
::Sleep(milliseconds);
824+
void OS::Sleep(TimeDelta interval) {
825+
::Sleep(static_cast<DWORD>(interval.InMilliseconds()));
826826
}
827827

828828

deps/v8/src/base/platform/platform.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,8 @@ class OS {
227227
// Get the Alignment guaranteed by Allocate().
228228
static size_t AllocateAlignment();
229229

230-
// Sleep for a number of milliseconds.
231-
static void Sleep(const int milliseconds);
230+
// Sleep for a specified time interval.
231+
static void Sleep(TimeDelta interval);
232232

233233
// Abort the current process.
234234
static void Abort();

deps/v8/src/cpu-profiler.cc

+21-5
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,32 @@ ProfilerEventsProcessor::SampleProcessingResult
108108

109109
void ProfilerEventsProcessor::Run() {
110110
while (running_) {
111-
base::ElapsedTimer timer;
112-
timer.Start();
113-
// Keep processing existing events until we need to do next sample.
111+
base::TimeTicks nextSampleTime =
112+
base::TimeTicks::HighResolutionNow() + period_;
113+
base::TimeTicks now;
114+
SampleProcessingResult result;
115+
// Keep processing existing events until we need to do next sample
116+
// or the ticks buffer is empty.
114117
do {
115-
if (FoundSampleForNextCodeEvent == ProcessOneSample()) {
118+
result = ProcessOneSample();
119+
if (result == FoundSampleForNextCodeEvent) {
116120
// All ticks of the current last_processed_code_event_id_ are
117121
// processed, proceed to the next code event.
118122
ProcessCodeEvent();
119123
}
120-
} while (!timer.HasExpired(period_));
124+
now = base::TimeTicks::HighResolutionNow();
125+
} while (result != NoSamplesInQueue && now < nextSampleTime);
126+
127+
if (nextSampleTime > now) {
128+
#if V8_OS_WIN
129+
// Do not use Sleep on Windows as it is very imprecise.
130+
// Could be up to 16ms jitter, which is unacceptable for the purpose.
131+
while (base::TimeTicks::HighResolutionNow() < nextSampleTime) {
132+
}
133+
#else
134+
base::OS::Sleep(nextSampleTime - now);
135+
#endif
136+
}
121137

122138
// Schedule next sample. sampler_ is NULL in tests.
123139
if (sampler_) sampler_->DoSample();

deps/v8/src/optimizing-compiler-thread.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ void OptimizingCompilerThread::Run() {
4848
TimerEventScope<TimerEventRecompileConcurrent> timer(isolate_);
4949

5050
if (FLAG_concurrent_recompilation_delay != 0) {
51-
base::OS::Sleep(FLAG_concurrent_recompilation_delay);
51+
base::OS::Sleep(base::TimeDelta::FromMilliseconds(
52+
FLAG_concurrent_recompilation_delay));
5253
}
5354

5455
switch (static_cast<StopFlag>(base::Acquire_Load(&stop_thread_))) {

deps/v8/src/runtime.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -8641,7 +8641,7 @@ RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
86418641
sync_with_compiler_thread) {
86428642
while (function->IsInOptimizationQueue()) {
86438643
isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
8644-
base::OS::Sleep(50);
8644+
base::OS::Sleep(base::TimeDelta::FromMilliseconds(50));
86458645
}
86468646
}
86478647
if (FLAG_always_opt) {

deps/v8/src/sampler.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ class SamplerThread : public base::Thread {
550550
sampler->DoSample();
551551
}
552552
}
553-
base::OS::Sleep(interval_);
553+
base::OS::Sleep(base::TimeDelta::FromMilliseconds(interval_));
554554
}
555555
}
556556

deps/v8/test/cctest/test-api.cc

+6-4
Original file line numberDiff line numberDiff line change
@@ -15166,10 +15166,12 @@ class RegExpInterruptionThread : public v8::base::Thread {
1516615166
for (regexp_interruption_data.loop_count = 0;
1516715167
regexp_interruption_data.loop_count < 7;
1516815168
regexp_interruption_data.loop_count++) {
15169-
v8::base::OS::Sleep(50); // Wait a bit before requesting GC.
15169+
// Wait a bit before requesting GC.
15170+
v8::base::OS::Sleep(v8::base::TimeDelta::FromMilliseconds(50));
1517015171
reinterpret_cast<i::Isolate*>(isolate_)->stack_guard()->RequestGC();
1517115172
}
15172-
v8::base::OS::Sleep(50); // Wait a bit before terminating.
15173+
// Wait a bit before terminating.
15174+
v8::base::OS::Sleep(v8::base::TimeDelta::FromMilliseconds(50));
1517315175
v8::V8::TerminateExecution(isolate_);
1517415176
}
1517515177

@@ -21516,7 +21518,7 @@ class ThreadInterruptTest {
2151621518
struct sigaction action;
2151721519

2151821520
// Ensure that we'll enter waiting condition
21519-
v8::base::OS::Sleep(100);
21521+
v8::base::OS::Sleep(v8::base::TimeDelta::FromMilliseconds(100));
2152021522

2152121523
// Setup signal handler
2152221524
memset(&action, 0, sizeof(action));
@@ -21527,7 +21529,7 @@ class ThreadInterruptTest {
2152721529
kill(getpid(), SIGCHLD);
2152821530

2152921531
// Ensure that if wait has returned because of error
21530-
v8::base::OS::Sleep(100);
21532+
v8::base::OS::Sleep(v8::base::TimeDelta::FromMilliseconds(100));
2153121533

2153221534
// Set value and signal semaphore
2153321535
test_->sem_value_ = 1;

deps/v8/test/cctest/test-cpu-profiler.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ class TestApiCallbacks {
793793
double start = v8::base::OS::TimeCurrentMillis();
794794
double duration = 0;
795795
while (duration < min_duration_ms_) {
796-
v8::base::OS::Sleep(1);
796+
v8::base::OS::Sleep(v8::base::TimeDelta::FromMilliseconds(1));
797797
duration = v8::base::OS::TimeCurrentMillis() - start;
798798
}
799799
}

deps/v8/test/cctest/test-log.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ class LoopingJsThread : public LoopingThread {
186186
"var j; for (var i=0; i<10000; ++i) { j = Math.sin(i); }");
187187
}
188188
context.Dispose();
189-
i::OS::Sleep(1);
189+
i::OS::Sleep(v8::base::TimeDelta::FromMilliseconds(1));
190190
}
191191
}
192192
};
@@ -206,7 +206,7 @@ class LoopingNonJsThread : public LoopingThread {
206206
SignalRunning();
207207
while (IsRunning()) {
208208
i = std::sin(i);
209-
i::OS::Sleep(1);
209+
i::OS::Sleep(v8::base::TimeDelta::FromMilliseconds(1));
210210
}
211211
}
212212
};

0 commit comments

Comments
 (0)