ParallelJobs: maximum number of threads should be determined dynamically
authorkbalazs@webkit.org <kbalazs@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 18 Oct 2011 09:18:18 +0000 (09:18 +0000)
committerkbalazs@webkit.org <kbalazs@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 18 Oct 2011 09:18:18 +0000 (09:18 +0000)
https://bugs.webkit.org/show_bug.cgi?id=68540

Reviewed by Zoltan Herczeg.

Add logic to determine the number of cores and use this as
the maximum number of threads. The implementation currently
covers Linux, Darwin, Windows, AIX, Solaris, OpenBSD and NetBSD.
The patch was tested on Linux, Mac and Windows which was enough to
cover all code path. It should work on the rest accoring to the
documentation of those OS's. The hard coded constant is still used
on uncovered OS's which should be fixed in the future.

* wtf/ParallelJobs.h: Removed the default value of the requestedJobNumber
argument because clients should always fill it and the 0 default value
was incorrect anyway.
(WTF::ParallelJobs::ParallelJobs):
* wtf/ParallelJobsGeneric.cpp:
(WTF::ParallelEnvironment::determineMaxNumberOfParallelThreads):
* wtf/ParallelJobsGeneric.h:
(WTF::ParallelEnvironment::ParallelEnvironment):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@97731 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/wtf/ParallelJobs.h
Source/JavaScriptCore/wtf/ParallelJobsGeneric.cpp
Source/JavaScriptCore/wtf/ParallelJobsGeneric.h

index 4a36095..23a5fc3 100644 (file)
@@ -1,3 +1,27 @@
+2011-10-18  Balazs Kelemen  <kbalazs@webkit.org>
+
+        ParallelJobs: maximum number of threads should be determined dynamically
+        https://bugs.webkit.org/show_bug.cgi?id=68540
+
+        Reviewed by Zoltan Herczeg.
+
+        Add logic to determine the number of cores and use this as
+        the maximum number of threads. The implementation currently
+        covers Linux, Darwin, Windows, AIX, Solaris, OpenBSD and NetBSD.
+        The patch was tested on Linux, Mac and Windows which was enough to
+        cover all code path. It should work on the rest accoring to the
+        documentation of those OS's. The hard coded constant is still used
+        on uncovered OS's which should be fixed in the future.
+
+        * wtf/ParallelJobs.h: Removed the default value of the requestedJobNumber
+        argument because clients should always fill it and the 0 default value
+        was incorrect anyway.
+        (WTF::ParallelJobs::ParallelJobs):
+        * wtf/ParallelJobsGeneric.cpp:
+        (WTF::ParallelEnvironment::determineMaxNumberOfParallelThreads):
+        * wtf/ParallelJobsGeneric.h:
+        (WTF::ParallelEnvironment::ParallelEnvironment):
+
 2011-10-17  Gavin Barraclough  <barraclough@apple.com>
 
         Reverted r997709, this caused test failures.
index 2e0524d..77b51c2 100644 (file)
@@ -80,7 +80,7 @@ class ParallelJobs {
 public:
     typedef void (*WorkerFunction)(Type*);
 
-    ParallelJobs(WorkerFunction func, int requestedJobNumber = 0) :
+    ParallelJobs(WorkerFunction func, int requestedJobNumber) :
         m_parallelEnvironment(reinterpret_cast<ParallelEnvironment::ThreadFunction>(func), sizeof(Type), requestedJobNumber)
     {
         m_parameters.grow(m_parallelEnvironment.numberOfJobs());
index e241b83..7677427 100644 (file)
 #if ENABLE(PARALLEL_JOBS) && ENABLE(THREADING_GENERIC)
 
 #include "ParallelJobs.h"
+#include "UnusedParam.h"
+
+#if OS(DARWIN) || OS(OPENBSD) || OS(NETBSD)
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#elif OS(LINUX) || OS(AIX) || OS(SOLARIS)
+#include <unistd.h>
+#elif OS(WINDOWS)
+#include <Windows.h>
+#endif
 
 namespace WTF {
 
 Vector< RefPtr<ParallelEnvironment::ThreadPrivate> >* ParallelEnvironment::s_threadPool = 0;
 
+int ParallelEnvironment::s_maxNumberOfParallelThreads = -1;
+
+void ParallelEnvironment::determineMaxNumberOfParallelThreads()
+{
+    const int defaultIfUnavailable = 2;
+#if OS(DARWIN) || OS(OPENBSD) || OS(NETBSD)
+    unsigned result;
+    size_t length = sizeof(result);
+    int name[] = {
+        CTL_HW,
+        HW_NCPU
+    };
+    int sysctlResult = sysctl(name, sizeof(name) / sizeof(int), &result, &length, 0, 0);
+    s_maxNumberOfParallelThreads = sysctlResult < 0 ? defaultIfUnavailable : result;
+#elif OS(LINUX) || OS(AIX) || OS(SOLARIS)
+    long sysconfResult = sysconf(_SC_NPROCESSORS_ONLN);
+    s_maxNumberOfParallelThreads = sysconfResult < 0 ? defaultIfUnavailable : static_cast<int>(sysconfResult);
+#elif OS(WINDOWS)
+    UNUSED_PARAM(defaultIfUnavailable);
+
+    SYSTEM_INFO sysInfo;
+    GetSystemInfo(&sysInfo);
+    s_maxNumberOfParallelThreads = sysInfo.dwNumberOfProcessors;
+#else
+    s_maxNumberOfParallelThreads = defaultIfUnavailable;
+#endif
+}
+
 bool ParallelEnvironment::ThreadPrivate::tryLockFor(ParallelEnvironment* parent)
 {
     bool locked = m_mutex.tryLock();
index 2aa44d5..e7d2441 100644 (file)
 
 namespace WTF {
 
-static const unsigned int maxParallelThreads = 2;
-
 class ParallelEnvironment {
     WTF_MAKE_FAST_ALLOCATED;
 public:
     typedef void (*ThreadFunction)(void*);
 
-    ParallelEnvironment(ThreadFunction threadFunction, size_t sizeOfParameter, unsigned int requestedJobNumber) :
+    ParallelEnvironment(ThreadFunction threadFunction, size_t sizeOfParameter, int requestedJobNumber) :
         m_threadFunction(threadFunction),
         m_sizeOfParameter(sizeOfParameter)
     {
-        if (!requestedJobNumber || requestedJobNumber > maxParallelThreads)
-            requestedJobNumber = maxParallelThreads;
+        ASSERT_ARG(requestedJobNumber, requestedJobNumber >= 1);
+
+        if (s_maxNumberOfParallelThreads == -1)
+            determineMaxNumberOfParallelThreads();
+
+        if (!requestedJobNumber || requestedJobNumber > s_maxNumberOfParallelThreads)
+            requestedJobNumber = static_cast<unsigned>(s_maxNumberOfParallelThreads);
 
         if (!s_threadPool)
             s_threadPool = new Vector< RefPtr<ThreadPrivate> >();
 
         // The main thread should be also a worker.
-        unsigned int maxNewThreads = requestedJobNumber - 1;
+        int maxNumberOfNewThreads = requestedJobNumber - 1;
 
-        for (unsigned int i = 0; i < maxParallelThreads && m_threads.size() < maxNewThreads; ++i) {
+        for (int i = 0; i < s_maxNumberOfParallelThreads && m_threads.size() < maxNumberOfNewThreads; ++i) {
             if (s_threadPool->size() < i + 1)
                 s_threadPool->append(ThreadPrivate::create());
 
@@ -122,12 +125,15 @@ public:
     };
 
 private:
+    static void determineMaxNumberOfParallelThreads();
+
     ThreadFunction m_threadFunction;
     size_t m_sizeOfParameter;
     int m_numberOfJobs;
 
     Vector< RefPtr<ThreadPrivate> > m_threads;
     static Vector< RefPtr<ThreadPrivate> >* s_threadPool;
+    static int s_maxNumberOfParallelThreads;
 };
 
 } // namespace WTF