blob: 6902504d107a71eedd5a80c6292eaea5c1cfe2bd [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// Copyright 2013 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/libplatform/default-platform.h"
6
7#include <algorithm>
8#include <queue>
9
10#include "src/base/logging.h"
11#include "src/base/platform/platform.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040012#include "src/base/platform/time.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000013#include "src/base/sys-info.h"
14#include "src/libplatform/worker-thread.h"
15
16namespace v8 {
17namespace platform {
18
19
20v8::Platform* CreateDefaultPlatform(int thread_pool_size) {
21 DefaultPlatform* platform = new DefaultPlatform();
22 platform->SetThreadPoolSize(thread_pool_size);
23 platform->EnsureInitialized();
24 return platform;
25}
26
27
28bool PumpMessageLoop(v8::Platform* platform, v8::Isolate* isolate) {
29 return reinterpret_cast<DefaultPlatform*>(platform)->PumpMessageLoop(isolate);
30}
31
32
33const int DefaultPlatform::kMaxThreadPoolSize = 4;
34
35
36DefaultPlatform::DefaultPlatform()
37 : initialized_(false), thread_pool_size_(0) {}
38
39
40DefaultPlatform::~DefaultPlatform() {
41 base::LockGuard<base::Mutex> guard(&lock_);
42 queue_.Terminate();
43 if (initialized_) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000044 for (auto i = thread_pool_.begin(); i != thread_pool_.end(); ++i) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000045 delete *i;
46 }
47 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000048 for (auto i = main_thread_queue_.begin(); i != main_thread_queue_.end();
49 ++i) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000050 while (!i->second.empty()) {
51 delete i->second.front();
52 i->second.pop();
53 }
54 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000055 for (auto i = main_thread_delayed_queue_.begin();
56 i != main_thread_delayed_queue_.end(); ++i) {
57 while (!i->second.empty()) {
58 delete i->second.top().second;
59 i->second.pop();
60 }
61 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000062}
63
64
65void DefaultPlatform::SetThreadPoolSize(int thread_pool_size) {
66 base::LockGuard<base::Mutex> guard(&lock_);
67 DCHECK(thread_pool_size >= 0);
68 if (thread_pool_size < 1) {
69 thread_pool_size = base::SysInfo::NumberOfProcessors();
70 }
71 thread_pool_size_ =
72 std::max(std::min(thread_pool_size, kMaxThreadPoolSize), 1);
73}
74
75
76void DefaultPlatform::EnsureInitialized() {
77 base::LockGuard<base::Mutex> guard(&lock_);
78 if (initialized_) return;
79 initialized_ = true;
80
81 for (int i = 0; i < thread_pool_size_; ++i)
82 thread_pool_.push_back(new WorkerThread(&queue_));
83}
84
85
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000086Task* DefaultPlatform::PopTaskInMainThreadQueue(v8::Isolate* isolate) {
87 auto it = main_thread_queue_.find(isolate);
88 if (it == main_thread_queue_.end() || it->second.empty()) {
89 return NULL;
90 }
91 Task* task = it->second.front();
92 it->second.pop();
93 return task;
94}
95
96
97Task* DefaultPlatform::PopTaskInMainThreadDelayedQueue(v8::Isolate* isolate) {
98 auto it = main_thread_delayed_queue_.find(isolate);
99 if (it == main_thread_delayed_queue_.end() || it->second.empty()) {
100 return NULL;
101 }
102 double now = MonotonicallyIncreasingTime();
103 std::pair<double, Task*> deadline_and_task = it->second.top();
104 if (deadline_and_task.first > now) {
105 return NULL;
106 }
107 it->second.pop();
108 return deadline_and_task.second;
109}
110
111
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000112bool DefaultPlatform::PumpMessageLoop(v8::Isolate* isolate) {
113 Task* task = NULL;
114 {
115 base::LockGuard<base::Mutex> guard(&lock_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000116
117 // Move delayed tasks that hit their deadline to the main queue.
118 task = PopTaskInMainThreadDelayedQueue(isolate);
119 while (task != NULL) {
120 main_thread_queue_[isolate].push(task);
121 task = PopTaskInMainThreadDelayedQueue(isolate);
122 }
123
124 task = PopTaskInMainThreadQueue(isolate);
125
126 if (task == NULL) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000127 return false;
128 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000129 }
130 task->Run();
131 delete task;
132 return true;
133}
134
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000135
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000136void DefaultPlatform::CallOnBackgroundThread(Task *task,
137 ExpectedRuntime expected_runtime) {
138 EnsureInitialized();
139 queue_.Append(task);
140}
141
142
143void DefaultPlatform::CallOnForegroundThread(v8::Isolate* isolate, Task* task) {
144 base::LockGuard<base::Mutex> guard(&lock_);
145 main_thread_queue_[isolate].push(task);
146}
147
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400148
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000149void DefaultPlatform::CallDelayedOnForegroundThread(Isolate* isolate,
150 Task* task,
151 double delay_in_seconds) {
152 base::LockGuard<base::Mutex> guard(&lock_);
153 double deadline = MonotonicallyIncreasingTime() + delay_in_seconds;
154 main_thread_delayed_queue_[isolate].push(std::make_pair(deadline, task));
155}
156
157
158void DefaultPlatform::CallIdleOnForegroundThread(Isolate* isolate,
159 IdleTask* task) {
160 UNREACHABLE();
161}
162
163
164bool DefaultPlatform::IdleTasksEnabled(Isolate* isolate) { return false; }
165
166
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400167double DefaultPlatform::MonotonicallyIncreasingTime() {
168 return base::TimeTicks::HighResolutionNow().ToInternalValue() /
169 static_cast<double>(base::Time::kMicrosecondsPerSecond);
170}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000171
172
173uint64_t DefaultPlatform::AddTraceEvent(
174 char phase, const uint8_t* category_enabled_flag, const char* name,
175 uint64_t id, uint64_t bind_id, int num_args, const char** arg_names,
176 const uint8_t* arg_types, const uint64_t* arg_values, unsigned int flags) {
177 return 0;
178}
179
180
181void DefaultPlatform::UpdateTraceEventDuration(
182 const uint8_t* category_enabled_flag, const char* name, uint64_t handle) {}
183
184
185const uint8_t* DefaultPlatform::GetCategoryGroupEnabled(const char* name) {
186 static uint8_t no = 0;
187 return &no;
188}
189
190
191const char* DefaultPlatform::GetCategoryGroupName(
192 const uint8_t* category_enabled_flag) {
193 static const char dummy[] = "dummy";
194 return dummy;
195}
Ben Murdoch097c5b22016-05-18 11:27:45 +0100196
197size_t DefaultPlatform::NumberOfAvailableBackgroundThreads() {
198 return static_cast<size_t>(thread_pool_size_);
199}
200
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000201} // namespace platform
202} // namespace v8