Flutter Engine
The Flutter Engine
thread_pool.h
Go to the documentation of this file.
1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_THREAD_POOL_H_
6#define RUNTIME_VM_THREAD_POOL_H_
7
8#include <memory>
9#include <utility>
10
11#include "vm/allocation.h"
12#include "vm/globals.h"
13#include "vm/intrusive_dlist.h"
14#include "vm/os_thread.h"
15
16namespace dart {
17
18class MonitorLocker;
19
21 public:
22 // Subclasses of Task are able to run on a ThreadPool.
23 class Task : public IntrusiveDListEntry<Task> {
24 protected:
25 Task() {}
26
27 public:
28 virtual ~Task() {}
29
30 // Override this to provide task-specific behavior.
31 virtual void Run() = 0;
32
33 private:
34 DISALLOW_COPY_AND_ASSIGN(Task);
35 };
36
37 explicit ThreadPool(uintptr_t max_pool_size = 0);
38
39 // Prevent scheduling of new tasks, wait until all pending tasks are done
40 // and join worker threads.
41 virtual ~ThreadPool();
42
43 // Runs a task on the thread pool.
44 template <typename T, typename... Args>
45 bool Run(Args&&... args) {
46 return RunImpl(std::unique_ptr<Task>(new T(std::forward<Args>(args)...)));
47 }
48
49 // Returns `true` if the current thread is running on the [this] thread pool.
51
52 // Mark the current thread as being blocked (e.g. in native code). This might
53 // temporarily increase the max thread pool size.
55
56 // Mark the current thread as being unblocked. Must be called iff
57 // [MarkCurrentWorkerAsBlocked] was called before and the thread is now ready
58 // to continue executing.
60
61 // Triggers shutdown, prevents scheduling of new tasks.
62 void Shutdown();
63
64 // Exposed for unit test in thread_pool_test.cc
65 uint64_t workers_started() const { return count_idle_ + count_running_; }
66 // Exposed for unit test in thread_pool_test.cc
67 uint64_t workers_stopped() const { return count_dead_; }
68
69 private:
70 class Worker : public IntrusiveDListEntry<Worker> {
71 public:
72 explicit Worker(ThreadPool* pool);
73
74 // Starts the thread for the worker. This should only be called
75 // after a task has been set by the initial call to SetTask().
76 void StartThread();
77
78 private:
79 friend class ThreadPool;
80
81 // The main entry point for new worker threads.
82 static void Main(uword args);
83
84 // Fields initialized during construction or in start of main function of
85 // thread.
86 ThreadPool* pool_;
87 ThreadJoinId join_id_;
88 OSThread* os_thread_ = nullptr;
89 bool is_blocked_ = false;
90
92 };
93
94 protected:
95 // Called when the thread pool turns idle.
96 //
97 // Subclasses can override this to perform some action.
98 // NOTE: While this function is running the thread pool will be locked.
99 virtual void OnEnterIdleLocked(MonitorLocker* ml) {}
100
101 // Whether a shutdown was requested.
102 bool ShuttingDownLocked() { return shutting_down_; }
103
104 // Whether new tasks are ready to be run.
105 bool TasksWaitingToRunLocked() { return !tasks_.IsEmpty(); }
106
107 private:
108 using TaskList = IntrusiveDList<Task>;
109 using WorkerList = IntrusiveDList<Worker>;
110
111 bool RunImpl(std::unique_ptr<Task> task);
112 void WorkerLoop(Worker* worker);
113
114 Worker* ScheduleTaskLocked(MonitorLocker* ml, std::unique_ptr<Task> task);
115
116 void IdleToRunningLocked(Worker* worker);
117 void RunningToIdleLocked(Worker* worker);
118 void IdleToDeadLocked(Worker* worker);
119 void ObtainDeadWorkersLocked(WorkerList* dead_workers_to_join);
120 void JoinDeadWorkersLocked(WorkerList* dead_workers_to_join);
121
122 Monitor pool_monitor_;
123 bool shutting_down_ = false;
124 uint64_t count_running_ = 0;
125 uint64_t count_idle_ = 0;
126 uint64_t count_dead_ = 0;
127 WorkerList running_workers_;
128 WorkerList idle_workers_;
129 WorkerList dead_workers_;
130 uint64_t pending_tasks_ = 0;
131 TaskList tasks_;
132
133 Monitor exit_monitor_;
134 std::atomic<bool> all_workers_dead_;
135
136 uintptr_t max_pool_size_ = 0;
137
139};
140
141} // namespace dart
142
143#endif // RUNTIME_VM_THREAD_POOL_H_
AutoreleasePool pool
virtual void Run()=0
uint64_t workers_started() const
Definition: thread_pool.h:65
bool ShuttingDownLocked()
Definition: thread_pool.h:102
uint64_t workers_stopped() const
Definition: thread_pool.h:67
bool Run(Args &&... args)
Definition: thread_pool.h:45
virtual ~ThreadPool()
Definition: thread_pool.cc:40
ThreadPool(uintptr_t max_pool_size=0)
Definition: thread_pool.cc:37
void MarkCurrentWorkerAsBlocked()
Definition: thread_pool.cc:105
virtual void OnEnterIdleLocked(MonitorLocker *ml)
Definition: thread_pool.h:99
bool CurrentThreadIsWorker()
Definition: thread_pool.cc:99
void MarkCurrentWorkerAsUnBlocked()
Definition: thread_pool.cc:131
bool TasksWaitingToRunLocked()
Definition: thread_pool.h:105
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
Definition: dart_vm.cc:33
pthread_t ThreadJoinId
uintptr_t uword
Definition: globals.h:501
static int Main(int argc, const char **argv)
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:581
#define T
Definition: precompiler.cc:65