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 15 namespace v8 { 16 namespace platform { 17 18 19 v8::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 27 bool PumpMessageLoop(v8::Platform* platform, v8::Isolate* isolate) { 28 return reinterpret_cast<DefaultPlatform*>(platform)->PumpMessageLoop(isolate); 29 } 30 31 32 const int DefaultPlatform::kMaxThreadPoolSize = 4; 33 34 35 DefaultPlatform::DefaultPlatform() 36 : initialized_(false), thread_pool_size_(0) {} 37 38 39 DefaultPlatform::~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 59 void 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 70 void 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 80 bool 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 97 void DefaultPlatform::CallOnBackgroundThread(Task *task, 98 ExpectedRuntime expected_runtime) { 99 EnsureInitialized(); 100 queue_.Append(task); 101 } 102 103 104 void 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