blob: 71ee6bee980372a17ac6d33e5e16e794e1aa21be [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
Ben Murdochda12d292016-06-02 14:46:10 +010032const int DefaultPlatform::kMaxThreadPoolSize = 8;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000033
34DefaultPlatform::DefaultPlatform()
35 : initialized_(false), thread_pool_size_(0) {}
36
37
38DefaultPlatform::~DefaultPlatform() {
39 base::LockGuard<base::Mutex> guard(&lock_);
40 queue_.Terminate();
41 if (initialized_) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000042 for (auto i = thread_pool_.begin(); i != thread_pool_.end(); ++i) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000043 delete *i;
44 }
45 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000046 for (auto i = main_thread_queue_.begin(); i != main_thread_queue_.end();
47 ++i) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000048 while (!i->second.empty()) {
49 delete i->second.front();
50 i->second.pop();
51 }
52 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000053 for (auto i = main_thread_delayed_queue_.begin();
54 i != main_thread_delayed_queue_.end(); ++i) {
55 while (!i->second.empty()) {
56 delete i->second.top().second;
57 i->second.pop();
58 }
59 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000060}
61
62
63void DefaultPlatform::SetThreadPoolSize(int thread_pool_size) {
64 base::LockGuard<base::Mutex> guard(&lock_);
65 DCHECK(thread_pool_size >= 0);
66 if (thread_pool_size < 1) {
Ben Murdochda12d292016-06-02 14:46:10 +010067 thread_pool_size = base::SysInfo::NumberOfProcessors() - 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000068 }
69 thread_pool_size_ =
70 std::max(std::min(thread_pool_size, kMaxThreadPoolSize), 1);
71}
72
73
74void DefaultPlatform::EnsureInitialized() {
75 base::LockGuard<base::Mutex> guard(&lock_);
76 if (initialized_) return;
77 initialized_ = true;
78
79 for (int i = 0; i < thread_pool_size_; ++i)
80 thread_pool_.push_back(new WorkerThread(&queue_));
81}
82
83
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000084Task* DefaultPlatform::PopTaskInMainThreadQueue(v8::Isolate* isolate) {
85 auto it = main_thread_queue_.find(isolate);
86 if (it == main_thread_queue_.end() || it->second.empty()) {
87 return NULL;
88 }
89 Task* task = it->second.front();
90 it->second.pop();
91 return task;
92}
93
94
95Task* DefaultPlatform::PopTaskInMainThreadDelayedQueue(v8::Isolate* isolate) {
96 auto it = main_thread_delayed_queue_.find(isolate);
97 if (it == main_thread_delayed_queue_.end() || it->second.empty()) {
98 return NULL;
99 }
100 double now = MonotonicallyIncreasingTime();
101 std::pair<double, Task*> deadline_and_task = it->second.top();
102 if (deadline_and_task.first > now) {
103 return NULL;
104 }
105 it->second.pop();
106 return deadline_and_task.second;
107}
108
109
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000110bool DefaultPlatform::PumpMessageLoop(v8::Isolate* isolate) {
111 Task* task = NULL;
112 {
113 base::LockGuard<base::Mutex> guard(&lock_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000114
115 // Move delayed tasks that hit their deadline to the main queue.
116 task = PopTaskInMainThreadDelayedQueue(isolate);
117 while (task != NULL) {
118 main_thread_queue_[isolate].push(task);
119 task = PopTaskInMainThreadDelayedQueue(isolate);
120 }
121
122 task = PopTaskInMainThreadQueue(isolate);
123
124 if (task == NULL) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000125 return false;
126 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000127 }
128 task->Run();
129 delete task;
130 return true;
131}
132
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000133
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000134void DefaultPlatform::CallOnBackgroundThread(Task *task,
135 ExpectedRuntime expected_runtime) {
136 EnsureInitialized();
137 queue_.Append(task);
138}
139
140
141void DefaultPlatform::CallOnForegroundThread(v8::Isolate* isolate, Task* task) {
142 base::LockGuard<base::Mutex> guard(&lock_);
143 main_thread_queue_[isolate].push(task);
144}
145
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400146
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000147void DefaultPlatform::CallDelayedOnForegroundThread(Isolate* isolate,
148 Task* task,
149 double delay_in_seconds) {
150 base::LockGuard<base::Mutex> guard(&lock_);
151 double deadline = MonotonicallyIncreasingTime() + delay_in_seconds;
152 main_thread_delayed_queue_[isolate].push(std::make_pair(deadline, task));
153}
154
155
156void DefaultPlatform::CallIdleOnForegroundThread(Isolate* isolate,
157 IdleTask* task) {
158 UNREACHABLE();
159}
160
161
162bool DefaultPlatform::IdleTasksEnabled(Isolate* isolate) { return false; }
163
164
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400165double DefaultPlatform::MonotonicallyIncreasingTime() {
166 return base::TimeTicks::HighResolutionNow().ToInternalValue() /
167 static_cast<double>(base::Time::kMicrosecondsPerSecond);
168}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000169
170
171uint64_t DefaultPlatform::AddTraceEvent(
172 char phase, const uint8_t* category_enabled_flag, const char* name,
Ben Murdochda12d292016-06-02 14:46:10 +0100173 const char* scope, uint64_t id, uint64_t bind_id, int num_args,
174 const char** arg_names, const uint8_t* arg_types,
175 const uint64_t* arg_values, unsigned int flags) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000176 return 0;
177}
178
179
180void DefaultPlatform::UpdateTraceEventDuration(
181 const uint8_t* category_enabled_flag, const char* name, uint64_t handle) {}
182
183
184const uint8_t* DefaultPlatform::GetCategoryGroupEnabled(const char* name) {
185 static uint8_t no = 0;
186 return &no;
187}
188
189
190const char* DefaultPlatform::GetCategoryGroupName(
191 const uint8_t* category_enabled_flag) {
192 static const char dummy[] = "dummy";
193 return dummy;
194}
Ben Murdoch097c5b22016-05-18 11:27:45 +0100195
Ben Murdochda12d292016-06-02 14:46:10 +0100196
Ben Murdoch097c5b22016-05-18 11:27:45 +0100197size_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