Commit 2b4273f6 authored by Sergio Villar Senin's avatar Sergio Villar Senin Committed by Commit Bot

Introducing WorkerThread::GCSupport

This is the first step to wipe WebThreadSupportingGC from the tree. It's
basically a wrapper over WorkerThread adding some GC capabilities.

This CL adds GC handling support to WorkerThread. It uses a new class called
GCSupport which is in charge of creating the GCTaskRunner apart from
attaching/detaching the current thread to ThreadState.

This new machinery is disabled ATM, it'll be enabled later in followup CLs which
will convert callsites to use WorkerThread instead of WebThreadSupportingGC.

Bug: 961743
Change-Id: Ibee4e3ce40500398d5794c13e18984e52fc2c39e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1655430Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Commit-Queue: Sergio Villar <svillar@igalia.com>
Cr-Commit-Position: refs/heads/master@{#668398}
parent 42834757
......@@ -37,7 +37,8 @@ WorkerThread::WorkerThread(const ThreadCreationParams& params)
options.priority = params.thread_priority;
thread_ = std::make_unique<SimpleThreadImpl>(
params.name ? params.name : std::string(), options,
std::move(non_main_thread_scheduler_factory));
std::move(non_main_thread_scheduler_factory), supports_gc_,
const_cast<scheduler::WorkerThread*>(this));
if (supports_gc_) {
MemoryPressureListenerRegistry::Instance().RegisterThread(
const_cast<scheduler::WorkerThread*>(this));
......@@ -81,12 +82,21 @@ scoped_refptr<base::SingleThreadTaskRunner> WorkerThread::GetTaskRunner()
return thread_->GetDefaultTaskRunner();
}
void WorkerThread::ShutdownOnThread() {
thread_->ShutdownOnThread();
Scheduler()->Shutdown();
}
WorkerThread::SimpleThreadImpl::SimpleThreadImpl(
const std::string& name_prefix,
const base::SimpleThread ::Options& options,
NonMainThreadSchedulerFactory factory)
NonMainThreadSchedulerFactory factory,
bool supports_gc,
WorkerThread* worker_thread)
: SimpleThread(name_prefix, options),
scheduler_factory_(std::move(factory)) {
thread_(worker_thread),
scheduler_factory_(std::move(factory)),
supports_gc_(supports_gc) {
// TODO(alexclarke): Do we need to unify virtual time for workers and the main
// thread?
sequence_manager_ = base::sequence_manager::CreateUnboundSequenceManager(
......@@ -110,6 +120,25 @@ void WorkerThread::SimpleThreadImpl::WaitForInit() {
initialized.Wait();
}
WorkerThread::GCSupport::GCSupport(WorkerThread* thread) {
ThreadState::AttachCurrentThread();
gc_task_runner_ = std::make_unique<GCTaskRunner>(thread);
}
WorkerThread::GCSupport::~GCSupport() {
#if defined(LEAK_SANITIZER)
ThreadState::Current()->ReleaseStaticPersistentNodes();
#endif
// Ensure no posted tasks will run from this point on.
gc_task_runner_.reset();
ThreadState::DetachCurrentThread();
}
void WorkerThread::SimpleThreadImpl::ShutdownOnThread() {
gc_support_.reset();
}
void WorkerThread::SimpleThreadImpl::Run() {
auto scoped_sequence_manager = std::move(sequence_manager_);
auto scoped_internal_task_queue = std::move(internal_task_queue_);
......
......@@ -53,12 +53,18 @@ class PLATFORM_EXPORT WorkerThread : public Thread {
return worker_scheduler_proxy_.get();
}
// This should be eventually removed. It's needed for a very specific case
// when we cannot wait until the underlying SimpleThreadImpl finishes, see
// WorkerBackingThread::ShutdownOnBackingThread().
void ShutdownOnThread();
protected:
virtual std::unique_ptr<NonMainThreadSchedulerImpl>
CreateNonMainThreadScheduler(
base::sequence_manager::SequenceManager* sequence_manager);
private:
class GCSupport;
class SimpleThreadImpl final : public base::SimpleThread {
public:
using NonMainThreadSchedulerFactory = base::OnceCallback<
......@@ -67,10 +73,12 @@ class PLATFORM_EXPORT WorkerThread : public Thread {
explicit SimpleThreadImpl(const std::string& name_prefix,
const base::SimpleThread::Options& options,
NonMainThreadSchedulerFactory factory);
NonMainThreadSchedulerFactory factory,
bool supports_gc,
WorkerThread* worker_thread);
// Attention: Can only be called after the worker thread has initialized the
// internal state. The best way to be sure that is the case is to call
// Attention: Can only be called after the worker thread has initialized
// the internal state. The best way to be sure that is the case is to call
// WaitForInit().
scoped_refptr<base::SingleThreadTaskRunner> GetDefaultTaskRunner() const {
DCHECK(is_initialized_.IsSet());
......@@ -83,6 +91,11 @@ class PLATFORM_EXPORT WorkerThread : public Thread {
return non_main_thread_scheduler_.get();
}
// SimpleThreadImpl automatically calls this after exiting the Run() but
// there are some use cases in which clients must call it before. See
// WorkerThread::ShutdownOnThread().
void ShutdownOnThread();
// Blocks until the worker thread is ready to enter the run loop and the
// default task runner has been initialized.
void WaitForInit();
......@@ -98,9 +111,12 @@ class PLATFORM_EXPORT WorkerThread : public Thread {
base::AtomicFlag is_initialized_;
// Internal queue not exposed externally nor to the scheduler used for
// internal operations such as posting the task that will stop the run loop.
// internal operations such as posting the task that will stop the run
// loop.
scoped_refptr<base::SingleThreadTaskRunner> internal_task_runner_;
WorkerThread* thread_ ALLOW_UNUSED_TYPE;
// The following variables are "owned" by the worker thread
NonMainThreadSchedulerFactory scheduler_factory_;
std::unique_ptr<base::sequence_manager::SequenceManager> sequence_manager_;
......@@ -109,13 +125,23 @@ class PLATFORM_EXPORT WorkerThread : public Thread {
non_main_thread_scheduler_;
scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
base::RunLoop* run_loop_;
bool supports_gc_ ALLOW_UNUSED_TYPE;
std::unique_ptr<GCSupport> gc_support_;
};
class GCSupport final {
public:
explicit GCSupport(WorkerThread* thread);
~GCSupport();
private:
std::unique_ptr<GCTaskRunner> gc_task_runner_;
};
std::unique_ptr<SimpleThreadImpl> thread_;
const WebThreadType thread_type_;
std::unique_ptr<scheduler::WorkerSchedulerProxy> worker_scheduler_proxy_;
bool supports_gc_;
std::unique_ptr<GCTaskRunner> gc_task_runner_;
};
} // namespace scheduler
......
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