Home | History | Annotate | Download | only in libplatform
      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