summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-07 20:57:13 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-07 20:57:13 +0000
commitc6e672e847e080826800d92583f1d57405977819 (patch)
treef7021abdf377d187151bd0b5d31bad664b8b3b56
parent5fe2718a5268ab261a54d41d1cffa51bdc052932 (diff)
downloadchromium_src-c6e672e847e080826800d92583f1d57405977819.zip
chromium_src-c6e672e847e080826800d92583f1d57405977819.tar.gz
chromium_src-c6e672e847e080826800d92583f1d57405977819.tar.bz2
Use one worker process per domain until we hit the maximum count of 10, then reuse processes.
Also add a test mode --webworker-process-per-core to create a worker process per worker until we hit the number of cores, then reuse. Review URL: http://codereview.chromium.org/61001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13279 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/worker_host/worker_process_host.h27
-rw-r--r--chrome/browser/worker_host/worker_service.cc68
-rw-r--r--chrome/browser/worker_host/worker_service.h12
-rw-r--r--chrome/common/chrome_switches.cc3
-rw-r--r--chrome/common/chrome_switches.h2
5 files changed, 95 insertions, 17 deletions
diff --git a/chrome/browser/worker_host/worker_process_host.h b/chrome/browser/worker_host/worker_process_host.h
index cf8072c..5432396 100644
--- a/chrome/browser/worker_host/worker_process_host.h
+++ b/chrome/browser/worker_host/worker_process_host.h
@@ -35,6 +35,22 @@ class WorkerProcessHost : public ChildProcessHost {
void RendererShutdown(ResourceMessageFilter* filter);
+ protected:
+ friend class WorkerService;
+
+ // Contains information about each worker instance, needed to forward messages
+ // between the renderer and worker processes.
+ struct WorkerInstance {
+ GURL url;
+ int render_view_route_id;
+ int worker_route_id;
+ int renderer_route_id;
+ ResourceMessageFilter* filter;
+ };
+
+ typedef std::list<WorkerInstance> Instances;
+ const Instances& instances() const { return instances_; }
+
private:
// ResourceDispatcherHost::Receiver implementation:
virtual URLRequestContext* GetRequestContext(
@@ -49,17 +65,6 @@ class WorkerProcessHost : public ChildProcessHost {
// Updates the title shown in the task manager.
void UpdateTitle();
- // Contains information about each worker instance, needed to forward messages
- // between the renderer and worker processes.
- struct WorkerInstance {
- GURL url;
- int render_view_route_id;
- int worker_route_id;
- int renderer_route_id;
- ResourceMessageFilter* filter;
- };
-
- typedef std::list<WorkerInstance> Instances;
Instances instances_;
DISALLOW_COPY_AND_ASSIGN(WorkerProcessHost);
diff --git a/chrome/browser/worker_host/worker_service.cc b/chrome/browser/worker_host/worker_service.cc
index 675326f..8151d9b 100644
--- a/chrome/browser/worker_host/worker_service.cc
+++ b/chrome/browser/worker_host/worker_service.cc
@@ -4,13 +4,21 @@
#include "chrome/browser/worker_host/worker_service.h"
+#include "base/command_line.h"
#include "base/singleton.h"
+#include "base/sys_info.h"
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/plugin_service.h"
#include "chrome/browser/worker_host/worker_process_host.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/resource_message_filter.h"
+#include "chrome/common/chrome_switches.h"
+#include "net/base/registry_controlled_domain.h"
+
+namespace {
+static const int kMaxWorkerProcesses = 10;
+}
WorkerService* WorkerService::GetInstance() {
return Singleton<WorkerService>::get();
@@ -27,11 +35,12 @@ bool WorkerService::CreateDedicatedWorker(const GURL &url,
ResourceMessageFilter* filter,
int renderer_route_id) {
WorkerProcessHost* worker = NULL;
- // One worker process for quick bringup!
- for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
- !iter.Done(); ++iter) {
- worker = static_cast<WorkerProcessHost*>(*iter);
- break;
+
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kWebWorkerProcessPerCore)) {
+ worker = GetProcessToFillUpCores();
+ } else {
+ worker = GetProcessForDomain(url);
}
if (!worker) {
@@ -48,7 +57,6 @@ bool WorkerService::CreateDedicatedWorker(const GURL &url,
// it to.
worker->CreateWorker(url, render_view_route_id, ++next_worker_route_id_,
renderer_route_id, filter);
-
return true;
}
@@ -70,3 +78,51 @@ void WorkerService::RendererShutdown(ResourceMessageFilter* filter) {
worker->RendererShutdown(filter);
}
}
+
+WorkerProcessHost* WorkerService::GetProcessForDomain(const GURL& url) {
+ int num_processes = 0;
+ std::string domain =
+ net::RegistryControlledDomainService::GetDomainAndRegistry(url);
+ for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
+ !iter.Done(); ++iter) {
+ num_processes++;
+ WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
+ for (WorkerProcessHost::Instances::const_iterator instance =
+ worker->instances().begin();
+ instance != worker->instances().end(); ++instance) {
+ if (net::RegistryControlledDomainService::GetDomainAndRegistry(
+ instance->url) == domain) {
+ return worker;
+ }
+ }
+ }
+
+ if (num_processes >= kMaxWorkerProcesses)
+ return GetLeastLoadedWorker();
+
+ return NULL;
+}
+
+WorkerProcessHost* WorkerService::GetProcessToFillUpCores() {
+ int num_processes = 0;
+ ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
+ for (; !iter.Done(); ++iter)
+ num_processes++;
+
+ if (num_processes >= base::SysInfo::NumberOfProcessors())
+ return GetLeastLoadedWorker();
+
+ return NULL;
+}
+
+WorkerProcessHost* WorkerService::GetLeastLoadedWorker() {
+ WorkerProcessHost* smallest = NULL;
+ for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
+ !iter.Done(); ++iter) {
+ WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
+ if (!smallest || worker->instances().size() < smallest->instances().size())
+ smallest = worker;
+ }
+
+ return smallest;
+}
diff --git a/chrome/browser/worker_host/worker_service.h b/chrome/browser/worker_host/worker_service.h
index 4f00c15..1aea2aa 100644
--- a/chrome/browser/worker_host/worker_service.h
+++ b/chrome/browser/worker_host/worker_service.h
@@ -44,6 +44,18 @@ class WorkerService {
WorkerService();
~WorkerService();
+ // Returns a WorkerProcessHost object if one exists for the given domain, or
+ // NULL if there are no such workers yet.
+ WorkerProcessHost* GetProcessForDomain(const GURL& url);
+
+ // Returns a WorkerProcessHost based on a strategy of creating one worker per
+ // core.
+ WorkerProcessHost* GetProcessToFillUpCores();
+
+ // Returns the WorkerProcessHost from the existing set that has the least
+ // number of worker instance running.
+ WorkerProcessHost* GetLeastLoadedWorker();
+
int next_worker_route_id_;
DISALLOW_COPY_AND_ASSIGN(WorkerService);
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index c12b578..e5573ca 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -400,6 +400,9 @@ const wchar_t kEnableOutOfProcessDevTools[] = L"enable-oop-devtools";
// Enable HTML5 Worker support
const wchar_t kEnableWebWorkers[] = L"enable-web-workers";
+// Causes the worker process allocation to use as many processes as cores.
+const wchar_t kWebWorkerProcessPerCore[] = L"web-worker-process-per-core";
+
// Enables experimental views under gtk.
const wchar_t kViewsGtk[] = L"views-gtk";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index fb72d4f..4b94a45 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -156,6 +156,8 @@ extern const wchar_t kEnableOutOfProcessDevTools[];
extern const wchar_t kEnableWebWorkers[];
+extern const wchar_t kWebWorkerProcessPerCore[];
+
extern const wchar_t kViewsGtk[];
extern const wchar_t kBookmarkMenu[];