1// 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" 12#include "src/base/sys-info.h" 13#include "src/libplatform/worker-thread.h" 14 15namespace v8 { 16namespace platform { 17 18 19v8::Platform* CreateDefaultPlatform(int thread_pool_size) { 20 DefaultPlatform* platform = new DefaultPlatform(); 21 platform->SetThreadPoolSize(thread_pool_size); 22 platform->EnsureInitialized(); 23 return platform; 24} 25 26 27bool PumpMessageLoop(v8::Platform* platform, v8::Isolate* isolate) { 28 return reinterpret_cast<DefaultPlatform*>(platform)->PumpMessageLoop(isolate); 29} 30 31 32const int DefaultPlatform::kMaxThreadPoolSize = 4; 33 34 35DefaultPlatform::DefaultPlatform() 36 : initialized_(false), thread_pool_size_(0) {} 37 38 39DefaultPlatform::~DefaultPlatform() { 40 base::LockGuard<base::Mutex> guard(&lock_); 41 queue_.Terminate(); 42 if (initialized_) { 43 for (std::vector<WorkerThread*>::iterator i = thread_pool_.begin(); 44 i != thread_pool_.end(); ++i) { 45 delete *i; 46 } 47 } 48 for (std::map<v8::Isolate*, std::queue<Task*> >::iterator i = 49 main_thread_queue_.begin(); 50 i != main_thread_queue_.end(); ++i) { 51 while (!i->second.empty()) { 52 delete i->second.front(); 53 i->second.pop(); 54 } 55 } 56} 57 58 59void DefaultPlatform::SetThreadPoolSize(int thread_pool_size) { 60 base::LockGuard<base::Mutex> guard(&lock_); 61 DCHECK(thread_pool_size >= 0); 62 if (thread_pool_size < 1) { 63 thread_pool_size = base::SysInfo::NumberOfProcessors(); 64 } 65 thread_pool_size_ = 66 std::max(std::min(thread_pool_size, kMaxThreadPoolSize), 1); 67} 68 69 70void DefaultPlatform::EnsureInitialized() { 71 base::LockGuard<base::Mutex> guard(&lock_); 72 if (initialized_) return; 73 initialized_ = true; 74 75 for (int i = 0; i < thread_pool_size_; ++i) 76 thread_pool_.push_back(new WorkerThread(&queue_)); 77} 78 79 80bool DefaultPlatform::PumpMessageLoop(v8::Isolate* isolate) { 81 Task* task = NULL; 82 { 83 base::LockGuard<base::Mutex> guard(&lock_); 84 std::map<v8::Isolate*, std::queue<Task*> >::iterator it = 85 main_thread_queue_.find(isolate); 86 if (it == main_thread_queue_.end() || it->second.empty()) { 87 return false; 88 } 89 task = it->second.front(); 90 it->second.pop(); 91 } 92 task->Run(); 93 delete task; 94 return true; 95} 96 97void DefaultPlatform::CallOnBackgroundThread(Task *task, 98 ExpectedRuntime expected_runtime) { 99 EnsureInitialized(); 100 queue_.Append(task); 101} 102 103 104void DefaultPlatform::CallOnForegroundThread(v8::Isolate* isolate, Task* task) { 105 base::LockGuard<base::Mutex> guard(&lock_); 106 main_thread_queue_[isolate].push(task); 107} 108 109} } // namespace v8::platform 110