mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
303dfdf9b5
Updates #37244. Change-Id: I32a5180a17fe43be5e18367d784cf756dffc6aeb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/106009 Commit-Queue: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Régis Crelier <regis@google.com>
157 lines
3.9 KiB
C++
157 lines
3.9 KiB
C++
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#ifndef RUNTIME_VM_THREAD_POOL_H_
|
|
#define RUNTIME_VM_THREAD_POOL_H_
|
|
|
|
#include <memory>
|
|
#include <utility>
|
|
|
|
#include "vm/allocation.h"
|
|
#include "vm/globals.h"
|
|
#include "vm/os_thread.h"
|
|
|
|
namespace dart {
|
|
|
|
class ThreadPool {
|
|
public:
|
|
// Subclasses of Task are able to run on a ThreadPool.
|
|
class Task {
|
|
protected:
|
|
Task();
|
|
|
|
public:
|
|
virtual ~Task();
|
|
|
|
// Override this to provide task-specific behavior.
|
|
virtual void Run() = 0;
|
|
|
|
private:
|
|
DISALLOW_COPY_AND_ASSIGN(Task);
|
|
};
|
|
|
|
ThreadPool();
|
|
|
|
// Shuts down this thread pool. Causes workers to terminate
|
|
// themselves when they are active again.
|
|
~ThreadPool();
|
|
|
|
// Runs a task on the thread pool.
|
|
template <typename T, typename... Args>
|
|
bool Run(Args&&... args) {
|
|
return RunImpl(std::unique_ptr<Task>(new T(std::forward<Args>(args)...)));
|
|
}
|
|
|
|
// Some simple stats.
|
|
uint64_t workers_running() const { return count_running_; }
|
|
uint64_t workers_idle() const { return count_idle_; }
|
|
uint64_t workers_started() const { return count_started_; }
|
|
uint64_t workers_stopped() const { return count_stopped_; }
|
|
|
|
private:
|
|
class Worker {
|
|
public:
|
|
explicit Worker(ThreadPool* pool);
|
|
|
|
// Sets a task on the worker.
|
|
void SetTask(std::unique_ptr<Task> task);
|
|
|
|
// Starts the thread for the worker. This should only be called
|
|
// after a task has been set by the initial call to SetTask().
|
|
void StartThread();
|
|
|
|
// Main loop for a worker. Returns true if worker is removed from thread
|
|
// lists, false otherwise.
|
|
bool Loop();
|
|
|
|
// Causes worker to terminate eventually.
|
|
void Shutdown();
|
|
|
|
// Get the Worker's thread id.
|
|
ThreadId id();
|
|
|
|
private:
|
|
friend class ThreadPool;
|
|
|
|
// The main entry point for new worker threads.
|
|
static void Main(uword args);
|
|
|
|
bool IsDone() const { return done_; }
|
|
|
|
// Fields owned by Worker.
|
|
Monitor monitor_;
|
|
ThreadPool* pool_;
|
|
std::unique_ptr<Task> task_;
|
|
ThreadId id_;
|
|
bool done_;
|
|
|
|
// Fields owned by ThreadPool. Workers should not look at these
|
|
// directly. It's like looking at the sun.
|
|
bool owned_; // Protected by ThreadPool::mutex_
|
|
Worker* all_next_; // Protected by ThreadPool::mutex_
|
|
Worker* idle_next_; // Protected by ThreadPool::mutex_
|
|
|
|
Worker* shutdown_next_; // Protected by ThreadPool::exit_monitor
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(Worker);
|
|
};
|
|
|
|
class JoinList {
|
|
public:
|
|
explicit JoinList(ThreadJoinId id, JoinList* next) : id_(id), next_(next) {}
|
|
|
|
// The thread pool's mutex_ must be held when calling this.
|
|
static void AddLocked(ThreadJoinId id, JoinList** list);
|
|
|
|
static void Join(JoinList** list);
|
|
|
|
ThreadJoinId id() const { return id_; }
|
|
JoinList* next() const { return next_; }
|
|
|
|
private:
|
|
ThreadJoinId id_;
|
|
JoinList* next_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(JoinList);
|
|
};
|
|
|
|
bool RunImpl(std::unique_ptr<Task> task);
|
|
void Shutdown();
|
|
|
|
// Expensive. Use only in assertions.
|
|
bool IsIdle(Worker* worker);
|
|
|
|
bool RemoveWorkerFromIdleList(Worker* worker);
|
|
bool RemoveWorkerFromAllList(Worker* worker);
|
|
|
|
void AddWorkerToShutdownList(Worker* worker);
|
|
bool RemoveWorkerFromShutdownList(Worker* worker);
|
|
|
|
void ReapExitedIdleThreads();
|
|
|
|
// Worker operations.
|
|
void SetIdleLocked(Worker* worker); // Assumes mutex_ is held.
|
|
void SetIdleAndReapExited(Worker* worker);
|
|
bool ReleaseIdleWorker(Worker* worker);
|
|
|
|
Mutex mutex_;
|
|
bool shutting_down_;
|
|
Worker* all_workers_;
|
|
Worker* idle_workers_;
|
|
uint64_t count_started_;
|
|
uint64_t count_stopped_;
|
|
uint64_t count_running_;
|
|
uint64_t count_idle_;
|
|
|
|
Monitor exit_monitor_;
|
|
Worker* shutting_down_workers_;
|
|
JoinList* join_list_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(ThreadPool);
|
|
};
|
|
|
|
} // namespace dart
|
|
|
|
#endif // RUNTIME_VM_THREAD_POOL_H_
|