@@ -13,6 +13,7 @@ using v8::Isolate;
1313using v8::Object;
1414using v8::Platform;
1515using v8::Task;
16+ using v8::TaskPriority;
1617
1718namespace {
1819
@@ -22,8 +23,31 @@ struct PlatformWorkerData {
2223 ConditionVariable* platform_workers_ready;
2324 int * pending_platform_workers;
2425 int id;
26+ PlatformDebugLogLevel debug_log_level;
2527};
2628
29+ const char * GetTaskPriorityName (TaskPriority priority) {
30+ switch (priority) {
31+ case TaskPriority::kUserBlocking :
32+ return " UserBlocking" ;
33+ case TaskPriority::kUserVisible :
34+ return " UserVisible" ;
35+ case TaskPriority::kBestEffort :
36+ return " BestEffort" ;
37+ default :
38+ return " Unknown" ;
39+ }
40+ }
41+
42+ static void PrintSourceLocation (const v8::SourceLocation& location) {
43+ auto loc = location.ToString ();
44+ if (!loc.empty ()) {
45+ fprintf (stderr, " %s\n " , loc.c_str ());
46+ } else {
47+ fprintf (stderr, " <no location>\n " );
48+ }
49+ }
50+
2751static void PlatformWorkerThread (void * data) {
2852 uv_thread_setname (" V8Worker" );
2953 std::unique_ptr<PlatformWorkerData>
@@ -40,8 +64,18 @@ static void PlatformWorkerThread(void* data) {
4064 worker_data->platform_workers_ready ->Signal (lock);
4165 }
4266
67+ bool debug_log_enabled =
68+ worker_data->debug_log_level != PlatformDebugLogLevel::kNone ;
69+ int id = worker_data->id ;
4370 while (std::unique_ptr<Task> task =
4471 pending_worker_tasks->Lock ().BlockingPop ()) {
72+ if (debug_log_enabled) {
73+ fprintf (stderr,
74+ " \n PlatformWorkerThread %d running task %p\n " ,
75+ id,
76+ task.get ());
77+ fflush (stderr);
78+ }
4579 task->Run ();
4680 pending_worker_tasks->Lock ().NotifyOfCompletion ();
4781 }
@@ -75,6 +109,12 @@ class WorkerThreadsTaskRunner::DelayedTaskScheduler {
75109
76110 void PostDelayedTask (std::unique_ptr<Task> task, double delay_in_seconds) {
77111 auto locked = tasks_.Lock ();
112+
113+ // The delayed task scheuler is on is own thread with its own loop that
114+ // runs the timers for the scheduled tasks to pop the original task back
115+ // into the the worker task queue. This first pushes the tasks that
116+ // schedules the timers into the local task queue that will be flushed
117+ // by the local event loop.
78118 locked.Push (std::make_unique<ScheduleTask>(
79119 this , std::move (task), delay_in_seconds));
80120 uv_async_send (&flush_tasks_);
@@ -109,6 +149,9 @@ class WorkerThreadsTaskRunner::DelayedTaskScheduler {
109149 while (!tasks_to_run.empty ()) {
110150 std::unique_ptr<Task> task = std::move (tasks_to_run.front ());
111151 tasks_to_run.pop ();
152+ // This runs either the ScheduleTasks that scheduels the timers to
153+ // pop the tasks back into the worker task runner queue, or the
154+ // or the StopTasks to stop the timers and drop all the pending tasks.
112155 task->Run ();
113156 }
114157 }
@@ -136,9 +179,9 @@ class WorkerThreadsTaskRunner::DelayedTaskScheduler {
136179 ScheduleTask (DelayedTaskScheduler* scheduler,
137180 std::unique_ptr<Task> task,
138181 double delay_in_seconds)
139- : scheduler_(scheduler),
140- task_ (std::move(task)),
141- delay_in_seconds_(delay_in_seconds) {}
182+ : scheduler_(scheduler),
183+ task_ (std::move(task)),
184+ delay_in_seconds_(delay_in_seconds) {}
142185
143186 void Run () override {
144187 uint64_t delay_millis = llround (delay_in_seconds_ * 1000 );
@@ -173,15 +216,21 @@ class WorkerThreadsTaskRunner::DelayedTaskScheduler {
173216 }
174217
175218 uv_sem_t ready_;
219+ // Task queue in the worker thread task runner, we push the delayed task back
220+ // to it when the timer expires.
176221 TaskQueue<Task>* pending_worker_tasks_;
177222
223+ // Locally scheduled tasks to be poped into the worker task runner queue.
224+ // It is flushed whenever the next closest timer expires.
178225 TaskQueue<Task> tasks_;
179226 uv_loop_t loop_;
180227 uv_async_t flush_tasks_;
181228 std::unordered_set<uv_timer_t *> timers_;
182229};
183230
184- WorkerThreadsTaskRunner::WorkerThreadsTaskRunner (int thread_pool_size) {
231+ WorkerThreadsTaskRunner::WorkerThreadsTaskRunner (
232+ int thread_pool_size, PlatformDebugLogLevel debug_log_level)
233+ : debug_log_level_(debug_log_level) {
185234 Mutex platform_workers_mutex;
186235 ConditionVariable platform_workers_ready;
187236
@@ -193,10 +242,13 @@ WorkerThreadsTaskRunner::WorkerThreadsTaskRunner(int thread_pool_size) {
193242 threads_.push_back (delayed_task_scheduler_->Start ());
194243
195244 for (int i = 0 ; i < thread_pool_size; i++) {
196- PlatformWorkerData* worker_data = new PlatformWorkerData{
197- &pending_worker_tasks_, &platform_workers_mutex,
198- &platform_workers_ready, &pending_platform_workers, i
199- };
245+ PlatformWorkerData* worker_data =
246+ new PlatformWorkerData{&pending_worker_tasks_,
247+ &platform_workers_mutex,
248+ &platform_workers_ready,
249+ &pending_platform_workers,
250+ i,
251+ debug_log_level_};
200252 std::unique_ptr<uv_thread_t > t { new uv_thread_t () };
201253 if (uv_thread_create (t.get (), PlatformWorkerThread,
202254 worker_data) != 0 ) {
@@ -238,8 +290,8 @@ int WorkerThreadsTaskRunner::NumberOfWorkerThreads() const {
238290}
239291
240292PerIsolatePlatformData::PerIsolatePlatformData (
241- Isolate* isolate, uv_loop_t * loop)
242- : isolate_(isolate), loop_(loop) {
293+ Isolate* isolate, uv_loop_t * loop, PlatformDebugLogLevel debug_log_level )
294+ : isolate_(isolate), loop_(loop), debug_log_level_(debug_log_level ) {
243295 flush_tasks_ = new uv_async_t ();
244296 CHECK_EQ (0 , uv_async_init (loop, flush_tasks_, FlushTasks));
245297 flush_tasks_->data = static_cast <void *>(this );
@@ -267,6 +319,15 @@ void PerIsolatePlatformData::PostTaskImpl(std::unique_ptr<Task> task,
267319 // the foreground task runner is being cleaned up by Shutdown(). In that
268320 // case, make sure we wait until the shutdown is completed (which leads
269321 // to flush_tasks_ == nullptr, and the task will be discarded).
322+ if (debug_log_level_ != PlatformDebugLogLevel::kNone ) {
323+ fprintf (stderr, " \n PerIsolatePlatformData::PostTaskImpl %p" , task.get ());
324+ PrintSourceLocation (location);
325+ if (debug_log_level_ == PlatformDebugLogLevel::kVerbose ) {
326+ DumpNativeBacktrace (stderr);
327+ }
328+ fflush (stderr);
329+ }
330+
270331 auto locked = foreground_tasks_.Lock ();
271332 if (flush_tasks_ == nullptr ) return ;
272333 locked.Push (std::move (task));
@@ -277,6 +338,18 @@ void PerIsolatePlatformData::PostDelayedTaskImpl(
277338 std::unique_ptr<Task> task,
278339 double delay_in_seconds,
279340 const v8::SourceLocation& location) {
341+ if (debug_log_level_ != PlatformDebugLogLevel::kNone ) {
342+ fprintf (stderr,
343+ " \n PerIsolatePlatformData::PostDelayedTaskImpl %p %f" ,
344+ task.get (),
345+ delay_in_seconds);
346+ PrintSourceLocation (location);
347+ if (debug_log_level_ == PlatformDebugLogLevel::kVerbose ) {
348+ DumpNativeBacktrace (stderr);
349+ }
350+ fflush (stderr);
351+ }
352+
280353 auto locked = foreground_delayed_tasks_.Lock ();
281354 if (flush_tasks_ == nullptr ) return ;
282355 std::unique_ptr<DelayedTask> delayed (new DelayedTask ());
@@ -346,6 +419,16 @@ void PerIsolatePlatformData::DecreaseHandleCount() {
346419NodePlatform::NodePlatform (int thread_pool_size,
347420 v8::TracingController* tracing_controller,
348421 v8::PageAllocator* page_allocator) {
422+ if (per_process::enabled_debug_list.enabled (
423+ DebugCategory::PLATFORM_VERBOSE)) {
424+ debug_log_level_ = PlatformDebugLogLevel::kVerbose ;
425+ } else if (per_process::enabled_debug_list.enabled (
426+ DebugCategory::PLATFORM_MINIMAL)) {
427+ debug_log_level_ = PlatformDebugLogLevel::kMinimal ;
428+ } else {
429+ debug_log_level_ = PlatformDebugLogLevel::kNone ;
430+ }
431+
349432 if (tracing_controller != nullptr ) {
350433 tracing_controller_ = tracing_controller;
351434 } else {
@@ -362,8 +445,8 @@ NodePlatform::NodePlatform(int thread_pool_size,
362445 DCHECK_EQ (GetTracingController (), tracing_controller_);
363446
364447 thread_pool_size = GetActualThreadPoolSize (thread_pool_size);
365- worker_thread_task_runner_ =
366- std::make_shared<WorkerThreadsTaskRunner>( thread_pool_size);
448+ worker_thread_task_runner_ = std::make_shared<WorkerThreadsTaskRunner>(
449+ thread_pool_size, debug_log_level_ );
367450}
368451
369452NodePlatform::~NodePlatform () {
@@ -372,7 +455,8 @@ NodePlatform::~NodePlatform() {
372455
373456void NodePlatform::RegisterIsolate (Isolate* isolate, uv_loop_t * loop) {
374457 Mutex::ScopedLock lock (per_isolate_mutex_);
375- auto delegate = std::make_shared<PerIsolatePlatformData>(isolate, loop);
458+ auto delegate =
459+ std::make_shared<PerIsolatePlatformData>(isolate, loop, debug_log_level_);
376460 IsolatePlatformDelegate* ptr = delegate.get ();
377461 auto insertion = per_isolate_.emplace (
378462 isolate,
@@ -527,6 +611,17 @@ void NodePlatform::PostTaskOnWorkerThreadImpl(
527611 v8::TaskPriority priority,
528612 std::unique_ptr<v8::Task> task,
529613 const v8::SourceLocation& location) {
614+ if (debug_log_level_ != PlatformDebugLogLevel::kNone ) {
615+ fprintf (stderr,
616+ " \n NodePlatform::PostTaskOnWorkerThreadImpl %s %p" ,
617+ GetTaskPriorityName (priority),
618+ task.get ());
619+ PrintSourceLocation (location);
620+ if (debug_log_level_ == PlatformDebugLogLevel::kVerbose ) {
621+ DumpNativeBacktrace (stderr);
622+ }
623+ fflush (stderr);
624+ }
530625 worker_thread_task_runner_->PostTask (std::move (task));
531626}
532627
@@ -535,6 +630,18 @@ void NodePlatform::PostDelayedTaskOnWorkerThreadImpl(
535630 std::unique_ptr<v8::Task> task,
536631 double delay_in_seconds,
537632 const v8::SourceLocation& location) {
633+ if (debug_log_level_ != PlatformDebugLogLevel::kNone ) {
634+ fprintf (stderr,
635+ " \n NodePlatform::PostDelayedTaskOnWorkerThreadImpl %s %p %f" ,
636+ GetTaskPriorityName (priority),
637+ task.get (),
638+ delay_in_seconds);
639+ PrintSourceLocation (location);
640+ if (debug_log_level_ == PlatformDebugLogLevel::kVerbose ) {
641+ DumpNativeBacktrace (stderr);
642+ }
643+ fflush (stderr);
644+ }
538645 worker_thread_task_runner_->PostDelayedTask (std::move (task),
539646 delay_in_seconds);
540647}
@@ -564,6 +671,17 @@ std::unique_ptr<v8::JobHandle> NodePlatform::CreateJobImpl(
564671 v8::TaskPriority priority,
565672 std::unique_ptr<v8::JobTask> job_task,
566673 const v8::SourceLocation& location) {
674+ if (debug_log_level_ != PlatformDebugLogLevel::kNone ) {
675+ fprintf (stderr,
676+ " \n NodePlatform::CreateJobImpl %s %p" ,
677+ GetTaskPriorityName (priority),
678+ job_task.get ());
679+ PrintSourceLocation (location);
680+ if (debug_log_level_ == PlatformDebugLogLevel::kVerbose ) {
681+ DumpNativeBacktrace (stderr);
682+ }
683+ fflush (stderr);
684+ }
567685 return v8::platform::NewDefaultJobHandle (
568686 this , priority, std::move (job_task), NumberOfWorkerThreads ());
569687}
0 commit comments