2 * Copyright (C) 2011 University of Szeged
3 * Copyright (C) 2011 Gabor Loki <loki@webkit.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #ifndef ParallelJobsGeneric_h
29 #define ParallelJobsGeneric_h
31 #if ENABLE(THREADING_GENERIC)
33 #include <wtf/RefCounted.h>
34 #include <wtf/Threading.h>
38 static const unsigned int maxParallelThreads
= 2;
40 class ParallelEnvironment
{
41 WTF_MAKE_FAST_ALLOCATED
;
43 typedef void (*ThreadFunction
)(void*);
45 ParallelEnvironment(ThreadFunction threadFunction
, size_t sizeOfParameter
, unsigned int requestedJobNumber
) :
46 m_threadFunction(threadFunction
),
47 m_sizeOfParameter(sizeOfParameter
)
49 if (!requestedJobNumber
|| requestedJobNumber
> maxParallelThreads
)
50 requestedJobNumber
= maxParallelThreads
;
53 s_threadPool
= new Vector
< RefPtr
<ThreadPrivate
> >();
55 // The main thread should be also a worker.
56 unsigned int maxNewThreads
= requestedJobNumber
- 1;
58 for (unsigned int i
= 0; i
< maxParallelThreads
&& m_threads
.size() < maxNewThreads
; ++i
) {
59 if (s_threadPool
->size() < i
+ 1)
60 s_threadPool
->append(ThreadPrivate::create());
62 if ((*s_threadPool
)[i
]->tryLockFor(this))
63 m_threads
.append((*s_threadPool
)[i
]);
66 m_numberOfJobs
= m_threads
.size() + 1;
71 return m_numberOfJobs
;
74 void execute(unsigned char* parameters
)
77 for (i
= 0; i
< m_threads
.size(); ++i
) {
78 m_threads
[i
]->execute(m_threadFunction
, parameters
);
79 parameters
+= m_sizeOfParameter
;
82 // The work for the main thread
83 (*m_threadFunction
)(parameters
);
85 // Wait until all jobs are done.
86 for (i
= 0; i
< m_threads
.size(); ++i
)
87 m_threads
[i
]->waitForFinish();
90 class ThreadPrivate
: public RefCounted
<ThreadPrivate
> {
99 bool tryLockFor(ParallelEnvironment
*);
101 void execute(ThreadFunction
, void*);
103 void waitForFinish();
105 static PassRefPtr
<ThreadPrivate
> create()
107 return adoptRef(new ThreadPrivate());
110 static void* workerThread(void*);
113 ThreadIdentifier m_threadID
;
115 ParallelEnvironment
* m_parent
;
117 mutable Mutex m_mutex
;
118 ThreadCondition m_threadCondition
;
120 ThreadFunction m_threadFunction
;
125 ThreadFunction m_threadFunction
;
126 size_t m_sizeOfParameter
;
129 Vector
< RefPtr
<ThreadPrivate
> > m_threads
;
130 static Vector
< RefPtr
<ThreadPrivate
> >* s_threadPool
;
135 #endif // ENABLE(THREADING_GENERIC)
138 #endif // ParallelJobsGeneric_h