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

Side by Side Diff: third_party/WebKit/Source/core/workers/WorkerThread.cpp

Issue 2806623004: Worker: Introduce per-global-scope task scheduler (Closed)
Patch Set: remove unnecessary comments Created 3 years, 8 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 13 matching lines...) Expand all
24 * 24 *
25 */ 25 */
26 26
27 #include "core/workers/WorkerThread.h" 27 #include "core/workers/WorkerThread.h"
28 28
29 #include <limits.h> 29 #include <limits.h>
30 #include <memory> 30 #include <memory>
31 #include "bindings/core/v8/Microtask.h" 31 #include "bindings/core/v8/Microtask.h"
32 #include "bindings/core/v8/ScriptSourceCode.h" 32 #include "bindings/core/v8/ScriptSourceCode.h"
33 #include "bindings/core/v8/WorkerOrWorkletScriptController.h" 33 #include "bindings/core/v8/WorkerOrWorkletScriptController.h"
34 #include "core/dom/TaskRunnerHelper.h"
34 #include "core/inspector/ConsoleMessageStorage.h" 35 #include "core/inspector/ConsoleMessageStorage.h"
35 #include "core/inspector/InspectorTaskRunner.h" 36 #include "core/inspector/InspectorTaskRunner.h"
36 #include "core/inspector/WorkerInspectorController.h" 37 #include "core/inspector/WorkerInspectorController.h"
37 #include "core/inspector/WorkerThreadDebugger.h" 38 #include "core/inspector/WorkerThreadDebugger.h"
38 #include "core/origin_trials/OriginTrialContext.h" 39 #include "core/origin_trials/OriginTrialContext.h"
39 #include "core/probe/CoreProbes.h" 40 #include "core/probe/CoreProbes.h"
40 #include "core/workers/ThreadedWorkletGlobalScope.h" 41 #include "core/workers/ThreadedWorkletGlobalScope.h"
41 #include "core/workers/WorkerBackingThread.h" 42 #include "core/workers/WorkerBackingThread.h"
42 #include "core/workers/WorkerClients.h" 43 #include "core/workers/WorkerClients.h"
43 #include "core/workers/WorkerGlobalScope.h" 44 #include "core/workers/WorkerGlobalScope.h"
44 #include "core/workers/WorkerReportingProxy.h" 45 #include "core/workers/WorkerReportingProxy.h"
45 #include "core/workers/WorkerThreadStartupData.h" 46 #include "core/workers/WorkerThreadStartupData.h"
46 #include "platform/CrossThreadFunctional.h" 47 #include "platform/CrossThreadFunctional.h"
47 #include "platform/Histogram.h" 48 #include "platform/Histogram.h"
48 #include "platform/WaitableEvent.h" 49 #include "platform/WaitableEvent.h"
49 #include "platform/WebThreadSupportingGC.h" 50 #include "platform/WebThreadSupportingGC.h"
50 #include "platform/heap/SafePoint.h" 51 #include "platform/heap/SafePoint.h"
51 #include "platform/heap/ThreadState.h" 52 #include "platform/heap/ThreadState.h"
53 #include "platform/scheduler/child/webthread_impl_for_worker_scheduler.h"
54 #include "platform/scheduler/child/worker_global_scope_scheduler.h"
52 #include "platform/weborigin/KURL.h" 55 #include "platform/weborigin/KURL.h"
53 #include "platform/wtf/Functional.h" 56 #include "platform/wtf/Functional.h"
54 #include "platform/wtf/Noncopyable.h" 57 #include "platform/wtf/Noncopyable.h"
55 #include "platform/wtf/PtrUtil.h" 58 #include "platform/wtf/PtrUtil.h"
56 #include "platform/wtf/Threading.h" 59 #include "platform/wtf/Threading.h"
57 #include "platform/wtf/text/WTFString.h" 60 #include "platform/wtf/text/WTFString.h"
58 61
59 namespace blink { 62 namespace blink {
60 63
61 using ExitCode = WorkerThread::ExitCode; 64 using ExitCode = WorkerThread::ExitCode;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 DEFINE_THREAD_SAFE_STATIC_LOCAL( 103 DEFINE_THREAD_SAFE_STATIC_LOCAL(
101 EnumerationHistogram, exit_code_histogram, 104 EnumerationHistogram, exit_code_histogram,
102 new EnumerationHistogram("WorkerThread.ExitCode", 105 new EnumerationHistogram("WorkerThread.ExitCode",
103 static_cast<int>(ExitCode::kLastEnum))); 106 static_cast<int>(ExitCode::kLastEnum)));
104 exit_code_histogram.Count(static_cast<int>(exit_code_)); 107 exit_code_histogram.Count(static_cast<int>(exit_code_));
105 } 108 }
106 109
107 void WorkerThread::Start(std::unique_ptr<WorkerThreadStartupData> startup_data, 110 void WorkerThread::Start(std::unique_ptr<WorkerThreadStartupData> startup_data,
108 ParentFrameTaskRunners* parent_frame_task_runners) { 111 ParentFrameTaskRunners* parent_frame_task_runners) {
109 DCHECK(IsMainThread()); 112 DCHECK(IsMainThread());
110
111 if (requested_to_start_) 113 if (requested_to_start_)
112 return; 114 return;
113 115
114 requested_to_start_ = true; 116 requested_to_start_ = true;
115 parent_frame_task_runners_ = parent_frame_task_runners; 117 parent_frame_task_runners_ = parent_frame_task_runners;
118
119 // Synchronously initialize the per-global-scope scheduler to prevent someone
120 // from posting a task to the thread before the scheduler is ready.
121 WaitableEvent waitable_event;
122 GetWorkerBackingThread().BackingThread().PostTask(
123 BLINK_FROM_HERE,
124 CrossThreadBind(&WorkerThread::InitializeSchedulerOnWorkerThread,
125 CrossThreadUnretained(this),
126 CrossThreadUnretained(&waitable_event)));
127 waitable_event.Wait();
128
116 GetWorkerBackingThread().BackingThread().PostTask( 129 GetWorkerBackingThread().BackingThread().PostTask(
117 BLINK_FROM_HERE, CrossThreadBind(&WorkerThread::InitializeOnWorkerThread, 130 BLINK_FROM_HERE, CrossThreadBind(&WorkerThread::InitializeOnWorkerThread,
118 CrossThreadUnretained(this), 131 CrossThreadUnretained(this),
119 WTF::Passed(std::move(startup_data)))); 132 WTF::Passed(std::move(startup_data))));
120 } 133 }
121 134
122 void WorkerThread::Terminate() { 135 void WorkerThread::Terminate() {
123 DCHECK(IsMainThread()); 136 DCHECK(IsMainThread());
124 TerminateInternal(TerminationMode::kGraceful); 137 TerminateInternal(TerminationMode::kGraceful);
125 } 138 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 } 196 }
184 197
185 v8::Isolate* WorkerThread::GetIsolate() { 198 v8::Isolate* WorkerThread::GetIsolate() {
186 return GetWorkerBackingThread().GetIsolate(); 199 return GetWorkerBackingThread().GetIsolate();
187 } 200 }
188 201
189 bool WorkerThread::IsCurrentThread() { 202 bool WorkerThread::IsCurrentThread() {
190 return GetWorkerBackingThread().BackingThread().IsCurrentThread(); 203 return GetWorkerBackingThread().BackingThread().IsCurrentThread();
191 } 204 }
192 205
193 void WorkerThread::PostTask(const WebTraceLocation& location,
194 std::unique_ptr<WTF::Closure> task) {
195 DCHECK(IsCurrentThread());
196 if (IsInShutdown())
197 return;
198 GetWorkerBackingThread().BackingThread().PostTask(
199 location,
200 WTF::Bind(
201 &WorkerThread::PerformTaskOnWorkerThread<WTF::kSameThreadAffinity>,
202 WTF::Unretained(this), WTF::Passed(std::move(task))));
203 }
204
205 void WorkerThread::PostTask(const WebTraceLocation& location,
206 std::unique_ptr<WTF::CrossThreadClosure> task) {
207 if (IsInShutdown())
208 return;
209 GetWorkerBackingThread().BackingThread().PostTask(
210 location,
211 CrossThreadBind(
212 &WorkerThread::PerformTaskOnWorkerThread<WTF::kCrossThreadAffinity>,
213 CrossThreadUnretained(this), WTF::Passed(std::move(task))));
214 }
215
216 void WorkerThread::AppendDebuggerTask( 206 void WorkerThread::AppendDebuggerTask(
217 std::unique_ptr<CrossThreadClosure> task) { 207 std::unique_ptr<CrossThreadClosure> task) {
218 DCHECK(IsMainThread()); 208 DCHECK(IsMainThread());
219 if (IsInShutdown()) 209 if (requested_to_terminate_)
220 return; 210 return;
221 inspector_task_runner_->AppendTask(CrossThreadBind( 211 inspector_task_runner_->AppendTask(CrossThreadBind(
222 &WorkerThread::PerformDebuggerTaskOnWorkerThread, 212 &WorkerThread::PerformDebuggerTaskOnWorkerThread,
223 CrossThreadUnretained(this), WTF::Passed(std::move(task)))); 213 CrossThreadUnretained(this), WTF::Passed(std::move(task))));
224 { 214 {
225 MutexLocker lock(thread_state_mutex_); 215 MutexLocker lock(thread_state_mutex_);
226 if (GetIsolate() && thread_state_ != ThreadState::kReadyToShutdown) 216 if (GetIsolate() && thread_state_ != ThreadState::kReadyToShutdown)
227 inspector_task_runner_->InterruptAndRunAllTasksDontWait(GetIsolate()); 217 inspector_task_runner_->InterruptAndRunAllTasksDontWait(GetIsolate());
228 } 218 }
229 GetWorkerBackingThread().BackingThread().PostTask( 219 TaskRunnerHelper::Get(TaskType::kUnthrottled, this)
230 BLINK_FROM_HERE, 220 ->PostTask(BLINK_FROM_HERE,
231 CrossThreadBind(&WorkerThread::PerformDebuggerTaskDontWaitOnWorkerThread, 221 CrossThreadBind(
232 CrossThreadUnretained(this))); 222 &WorkerThread::PerformDebuggerTaskDontWaitOnWorkerThread,
223 CrossThreadUnretained(this)));
233 } 224 }
234 225
235 void WorkerThread::StartRunningDebuggerTasksOnPauseOnWorkerThread() { 226 void WorkerThread::StartRunningDebuggerTasksOnPauseOnWorkerThread() {
236 DCHECK(IsCurrentThread()); 227 DCHECK(IsCurrentThread());
237 if (worker_inspector_controller_) 228 if (worker_inspector_controller_)
238 worker_inspector_controller_->FlushProtocolNotifications(); 229 worker_inspector_controller_->FlushProtocolNotifications();
239 paused_in_debugger_ = true; 230 paused_in_debugger_ = true;
240 ThreadDebugger::IdleStarted(GetIsolate()); 231 ThreadDebugger::IdleStarted(GetIsolate());
241 std::unique_ptr<CrossThreadClosure> task; 232 std::unique_ptr<CrossThreadClosure> task;
242 do { 233 do {
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 DCHECK(IsThreadStateMutexLocked(lock)); 414 DCHECK(IsThreadStateMutexLocked(lock));
424 415
425 DCHECK(exit_code == ExitCode::kSyncForciblyTerminated || 416 DCHECK(exit_code == ExitCode::kSyncForciblyTerminated ||
426 exit_code == ExitCode::kAsyncForciblyTerminated); 417 exit_code == ExitCode::kAsyncForciblyTerminated);
427 SetExitCode(lock, exit_code); 418 SetExitCode(lock, exit_code);
428 419
429 GetIsolate()->TerminateExecution(); 420 GetIsolate()->TerminateExecution();
430 forcible_termination_task_handle_.Cancel(); 421 forcible_termination_task_handle_.Cancel();
431 } 422 }
432 423
433 bool WorkerThread::IsInShutdown() { 424 void WorkerThread::InitializeSchedulerOnWorkerThread(
434 // Check if we've started termination or shutdown sequence. Avoid acquiring 425 WaitableEvent* waitable_event) {
435 // a lock here to avoid introducing a risk of deadlock. Note that accessing 426 DCHECK(IsCurrentThread());
436 // |m_requestedToTerminate| on the main thread or |m_threadState| on the 427 DCHECK(!global_scope_scheduler_);
437 // worker thread is safe as the flag is set only on the thread. 428 scheduler::WebThreadImplForWorkerScheduler& web_thread_for_worker =
438 if (IsMainThread() && requested_to_terminate_) 429 static_cast<scheduler::WebThreadImplForWorkerScheduler&>(
439 return true; 430 GetWorkerBackingThread().BackingThread().PlatformThread());
440 if (IsCurrentThread() && thread_state_ == ThreadState::kReadyToShutdown) 431 global_scope_scheduler_ =
441 return true; 432 WTF::MakeUnique<scheduler::WorkerGlobalScopeScheduler>(
442 return false; 433 web_thread_for_worker.GetWorkerScheduler());
434 waitable_event->Signal();
443 } 435 }
444 436
445 void WorkerThread::InitializeOnWorkerThread( 437 void WorkerThread::InitializeOnWorkerThread(
446 std::unique_ptr<WorkerThreadStartupData> startup_data) { 438 std::unique_ptr<WorkerThreadStartupData> startup_data) {
447 DCHECK(IsCurrentThread()); 439 DCHECK(IsCurrentThread());
448 DCHECK_EQ(ThreadState::kNotStarted, thread_state_); 440 DCHECK_EQ(ThreadState::kNotStarted, thread_state_);
449 441
450 KURL script_url = startup_data->script_url_; 442 KURL script_url = startup_data->script_url_;
451 String source_code = startup_data->source_code_; 443 String source_code = startup_data->source_code_;
452 WorkerThreadStartMode start_mode = startup_data->start_mode_; 444 WorkerThreadStartMode start_mode = startup_data->start_mode_;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 inspector_task_runner_->Kill(); 521 inspector_task_runner_->Kill();
530 GetWorkerReportingProxy().WillDestroyWorkerGlobalScope(); 522 GetWorkerReportingProxy().WillDestroyWorkerGlobalScope();
531 probe::AllAsyncTasksCanceled(GlobalScope()); 523 probe::AllAsyncTasksCanceled(GlobalScope());
532 524
533 GlobalScope()->NotifyContextDestroyed(); 525 GlobalScope()->NotifyContextDestroyed();
534 if (worker_inspector_controller_) { 526 if (worker_inspector_controller_) {
535 worker_inspector_controller_->Dispose(); 527 worker_inspector_controller_->Dispose();
536 worker_inspector_controller_.Clear(); 528 worker_inspector_controller_.Clear();
537 } 529 }
538 GlobalScope()->Dispose(); 530 GlobalScope()->Dispose();
531 global_scope_scheduler_->Dispose();
539 console_message_storage_.Clear(); 532 console_message_storage_.Clear();
540 GetWorkerBackingThread().BackingThread().RemoveTaskObserver(this); 533 GetWorkerBackingThread().BackingThread().RemoveTaskObserver(this);
541 } 534 }
542 535
543 void WorkerThread::PerformShutdownOnWorkerThread() { 536 void WorkerThread::PerformShutdownOnWorkerThread() {
544 DCHECK(IsCurrentThread()); 537 DCHECK(IsCurrentThread());
545 DCHECK(CheckRequestedToTerminateOnWorkerThread()); 538 DCHECK(CheckRequestedToTerminateOnWorkerThread());
546 DCHECK_EQ(ThreadState::kReadyToShutdown, thread_state_); 539 DCHECK_EQ(ThreadState::kReadyToShutdown, thread_state_);
547 540
548 // The below assignment will destroy the context, which will in turn notify 541 // The below assignment will destroy the context, which will in turn notify
549 // messaging proxy. We cannot let any objects survive past thread exit, 542 // messaging proxy. We cannot let any objects survive past thread exit,
550 // because no other thread will run GC or otherwise destroy them. If Oilpan 543 // because no other thread will run GC or otherwise destroy them. If Oilpan
551 // is enabled, we detach of the context/global scope, with the final heap 544 // is enabled, we detach of the context/global scope, with the final heap
552 // cleanup below sweeping it out. 545 // cleanup below sweeping it out.
553 global_scope_ = nullptr; 546 global_scope_ = nullptr;
554 547
555 if (IsOwningBackingThread()) 548 if (IsOwningBackingThread())
556 GetWorkerBackingThread().Shutdown(); 549 GetWorkerBackingThread().Shutdown();
557 // We must not touch workerBackingThread() from now on. 550 // We must not touch workerBackingThread() from now on.
558 551
559 // Notify the proxy that the WorkerOrWorkletGlobalScope has been disposed 552 // Notify the proxy that the WorkerOrWorkletGlobalScope has been disposed
560 // of. This can free this thread object, hence it must not be touched 553 // of. This can free this thread object, hence it must not be touched
561 // afterwards. 554 // afterwards.
562 GetWorkerReportingProxy().DidTerminateWorkerThread(); 555 GetWorkerReportingProxy().DidTerminateWorkerThread();
563 556
564 shutdown_event_->Signal(); 557 shutdown_event_->Signal();
565 } 558 }
566 559
567 template <WTF::FunctionThreadAffinity threadAffinity>
568 void WorkerThread::PerformTaskOnWorkerThread(
569 std::unique_ptr<Function<void(), threadAffinity>> task) {
570 DCHECK(IsCurrentThread());
571 if (thread_state_ != ThreadState::kRunning)
572 return;
573
574 {
575 DEFINE_THREAD_SAFE_STATIC_LOCAL(
576 CustomCountHistogram, scoped_us_counter,
577 new CustomCountHistogram("WorkerThread.Task.Time", 0, 10000000, 50));
578 ScopedUsHistogramTimer timer(scoped_us_counter);
579 (*task)();
580 }
581 }
582
583 void WorkerThread::PerformDebuggerTaskOnWorkerThread( 560 void WorkerThread::PerformDebuggerTaskOnWorkerThread(
584 std::unique_ptr<CrossThreadClosure> task) { 561 std::unique_ptr<CrossThreadClosure> task) {
585 DCHECK(IsCurrentThread()); 562 DCHECK(IsCurrentThread());
586 InspectorTaskRunner::IgnoreInterruptsScope scope( 563 InspectorTaskRunner::IgnoreInterruptsScope scope(
587 inspector_task_runner_.get()); 564 inspector_task_runner_.get());
588 { 565 {
589 MutexLocker lock(thread_state_mutex_); 566 MutexLocker lock(thread_state_mutex_);
590 DCHECK_EQ(ThreadState::kRunning, thread_state_); 567 DCHECK_EQ(ThreadState::kRunning, thread_state_);
591 running_debugger_task_ = true; 568 running_debugger_task_ = true;
592 } 569 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 MutexLocker lock(thread_state_mutex_); 636 MutexLocker lock(thread_state_mutex_);
660 return requested_to_terminate_; 637 return requested_to_terminate_;
661 } 638 }
662 639
663 ExitCode WorkerThread::GetExitCodeForTesting() { 640 ExitCode WorkerThread::GetExitCodeForTesting() {
664 MutexLocker lock(thread_state_mutex_); 641 MutexLocker lock(thread_state_mutex_);
665 return exit_code_; 642 return exit_code_;
666 } 643 }
667 644
668 } // namespace blink 645 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698