Source/WTF/ChangeLog

 12012-07-11 Kwonjin Jeong <gram@company100.net>
 2
 3 Add ImageDecodeWorker
 4 https://bugs.webkit.org/show_bug.cgi?id=90869
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 ImageDecodeWorker is a thread pool implementation based on WorkQueue.
 9 ImageDecodeWorker internally manages a pool of WorkQueues (n = number
 10 of cores) and assigns one from the pool when an ImageDecodeWorker
 11 instance is created. So two ImageDecodeWorkers can share one WorkQueue.
 12
 13 Parallel image decoders create an instance of ImageDecodeWorker for
 14 each image. So the number of ImageDecodeWorker instances can be
 15 arbitrarily large, but the number of WorkQueues is limited to the
 16 number of cores. This effectively utilizes the underlying cores.
 17
 18 * wtf/chromium/MainThreadChromium.cpp:
 19 (WTF::callFunctionObject):
 20 (WTF):
 21 (WTF::callOnMainThread):
 22
1232012-07-09 Kwang Yul Seo <skyul@company100.net>
224
325 Move WorkQueue to WTF

Source/WebCore/ChangeLog

 12012-07-11 Kwonjin Jeong <gram@company100.net>
 2
 3 Add ImageDecodeWorker
 4 https://bugs.webkit.org/show_bug.cgi?id=90869
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 ImageDecodeWorker is a thread pool implementation based on WorkQueue.
 9 ImageDecodeWorker internally manages a pool of WorkQueues (n = number
 10 of cores) and assigns one from the pool when an ImageDecodeWorker
 11 instance is created. So two ImageDecodeWorkers can share one WorkQueue.
 12
 13 Parallel image decoders create an instance of ImageDecodeWorker for
 14 each image. So the number of ImageDecodeWorker instances can be
 15 arbitrarily large, but the number of WorkQueues is limited to the
 16 number of cores. This effectively utilizes the underlying cores.
 17
 18 * CMakeLists.txt:
 19 * GNUmakefile.list.am:
 20 * Target.pri:
 21 * WebCore.gypi:
 22 * WebCore.vcproj/WebCore.vcproj:
 23 * WebCore.xcodeproj/project.pbxproj:
 24 * platform/graphics/ImageDecodeWorker.cpp: Added.
 25 (WebCore):
 26 (WebCore::ImageDecodeWorker::acquireSharedWorker):
 27 (WebCore::ImageDecodeWorker::initializeWorkQueuePool):
 28 (WebCore::ImageDecodeWorker::queueIdWithMinimumAcquireCount):
 29 (WebCore::ImageDecodeWorker::ImageDecodeWorker):
 30 (WebCore::ImageDecodeWorker::~ImageDecodeWorker):
 31 (WebCore::ImageDecodeWorker::hasInvalidationBegun):
 32 (WebCore::ImageDecodeWorker::cancelableFunction):
 33 (WebCore::ImageDecodeWorker::postTask):
 34 (WebCore::ImageDecodeWorker::invalidate):
 35 (WebCore::ImageDecodeWorker::ensureTerminate):
 36 * platform/graphics/ImageDecodeWorker.h: Added.
 37 (WebCore):
 38 (ImageDecodeWorker):
 39
1402012-07-10 Huang Dongsung <luxtella@company100.net>
241
342 Fix a potential bug of BitmapImage::frameCount().

Source/WTF/wtf/chromium/MainThreadChromium.cpp

3333
3434#include "Assertions.h"
3535#include "ChromiumThreading.h"
 36#include "Functional.h"
3637#include "Threading.h"
3738
3839namespace WTF {

@@void callOnMainThread(MainThreadFunction* function, void* context)
5455 ChromiumThreading::callOnMainThread(function, context);
5556}
5657
 58static void callFunctionObject(void* context)
 59{
 60 Function<void()>* function = static_cast<Function<void()>*>(context);
 61 (*function)();
 62 delete function;
 63}
 64
 65void callOnMainThread(const Function<void()>& function)
 66{
 67 callOnMainThread(callFunctionObject, new Function<void ()>(function));
 68}
 69
5770void callOnMainThreadAndWait(MainThreadFunction*, void*)
5871{
5972 ASSERT_NOT_REACHED();

Source/WebCore/CMakeLists.txt

@@SET(WebCore_SOURCES
11941194 platform/graphics/GraphicsTypes.cpp
11951195 platform/graphics/Image.cpp
11961196 platform/graphics/ImageBuffer.cpp
 1197 platform/graphics/ImageDecodeWorker.cpp
11971198 platform/graphics/ImageOrientation.cpp
11981199 platform/graphics/IntRect.cpp
11991200 platform/graphics/Path.cpp

Source/WebCore/GNUmakefile.list.am

@@webcore_sources += \
33553355 Source/WebCore/platform/graphics/ImageBufferData.h \
33563356 Source/WebCore/platform/graphics/Image.cpp \
33573357 Source/WebCore/platform/graphics/Image.h \
 3358 Source/WebCore/platform/graphics/ImageDecodeBuffer.cpp \
 3359 Source/WebCore/platform/graphics/ImageDecodeBuffer.h \
33583360 Source/WebCore/platform/graphics/ImageObserver.h \
33593361 Source/WebCore/platform/graphics/ImageOrientation.cpp \
33603362 Source/WebCore/platform/graphics/ImageOrientation.h \

Source/WebCore/Target.pri

@@SOURCES += \
11221122 platform/graphics/GraphicsTypes.cpp \
11231123 platform/graphics/Image.cpp \
11241124 platform/graphics/ImageBuffer.cpp \
 1125 platform/graphics/ImageDecodeWorker.cpp \
11251126 platform/graphics/ImageOrientation.cpp \
11261127 platform/graphics/ImageSource.cpp \
11271128 platform/graphics/IntRect.cpp \

@@HEADERS += \
22982299 platform/graphics/GraphicsTypes.h \
22992300 platform/graphics/GraphicsTypes3D.h \
23002301 platform/graphics/Image.h \
 2302 platform/graphics/ImageDecodeWorker.h \
23012303 platform/graphics/ImageOrientation.h \
23022304 platform/graphics/ImageSource.h \
23032305 platform/graphics/IntPoint.h \

Source/WebCore/WebCore.gypi

382382 'platform/graphics/Image.h',
383383 'platform/graphics/ImageBuffer.h',
384384 'platform/graphics/ImageBufferData.h',
 385 'platform/graphics/ImageDecodeBuffer.h',
385386 'platform/graphics/ImageObserver.h',
386387 'platform/graphics/ImageOrientation.h',
387388 'platform/graphics/ImageSource.h',

34953496 'platform/graphics/GraphicsTypes.cpp',
34963497 'platform/graphics/Image.cpp',
34973498 'platform/graphics/ImageBuffer.cpp',
 3499 'platform/graphics/ImageDecodeBuffer.cpp',
34983500 'platform/graphics/ImageOrientation.cpp',
34993501 'platform/graphics/ImageSource.cpp',
35003502 'platform/graphics/IntRect.cpp',

Source/WebCore/WebCore.vcproj/WebCore.vcproj

2929829298 >
2929929299 </File>
2930029300 <File
 29301 RelativePath="..\platform\graphics\ImageDecodeWorker.cpp"
 29302 >
 29303 </File>
 29304 <File
 29305 RelativePath="..\platform\graphics\ImageDecodeWorker.h"
 29306 >
 29307 </File>
 29308 <File
2930129309 RelativePath="..\platform\graphics\ImageObserver.h"
2930229310 >
2930329311 </File>

Source/WebCore/WebCore.xcodeproj/project.pbxproj

64806480 FE80DA720E9C472F000D6F75 /* JSPositionError.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80DA6E0E9C472F000D6F75 /* JSPositionError.h */; };
64816481 FFD5B97A135CC97800D5E92A /* PageVisibilityState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FFD5B977135CC97800D5E92A /* PageVisibilityState.cpp */; };
64826482 FFD5B97B135CC97800D5E92A /* PageVisibilityState.h in Headers */ = {isa = PBXBuildFile; fileRef = FFD5B978135CC97800D5E92A /* PageVisibilityState.h */; settings = {ATTRIBUTES = (Private, ); }; };
 6483 FFD6B97A135CC97800D5E92A /* ImageDecodeWorker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FFD6B96A135CC97800D5E92A /* ImageDecodeWorker.cpp */; };
 6484 FFD6B97B135CC97800D5E92A /* ImageDecodeWorker.h in Headers */ = {isa = PBXBuildFile; fileRef = FFD6B96B135CC97800D5E92A /* ImageDecodeWorker.h */; };
64836485/* End PBXBuildFile section */
64846486
64856487/* Begin PBXContainerItemProxy section */

1381513817 FE80DA6E0E9C472F000D6F75 /* JSPositionError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPositionError.h; sourceTree = "<group>"; };
1381613818 FFD5B977135CC97800D5E92A /* PageVisibilityState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageVisibilityState.cpp; sourceTree = "<group>"; };
1381713819 FFD5B978135CC97800D5E92A /* PageVisibilityState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageVisibilityState.h; sourceTree = "<group>"; };
 13820 FFD6B96A135CC97800D5E92A /* ImageDecodeWorker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageDecodeWorker.cpp; sourceTree = "<group>"; };
 13821 FFD6B97B135CC97800D5E92A /* ImageDecodeWorker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageDecodeWorker.h; sourceTree = "<group>"; };
1381813822/* End PBXFileReference section */
1381913823
1382013824/* Begin PBXFrameworksBuildPhase section */

1967519679 43D2597613C816F400608559 /* ImageBuffer.cpp */,
1967619680 B2A10B910B3818BD00099AA4 /* ImageBuffer.h */,
1967719681 22BD9F7D1353625C009BD102 /* ImageBufferData.h */,
 19682 FFD6B96A135CC97800D5E92A /* ImageDecodeWorker.cpp */
 19683 FFD6B96A135CC97800D5E92A /* ImageDecodeWorker.h */
1967819684 BC7F44A70B9E324E00A9D081 /* ImageObserver.h */,
1967919685 A8748D7412CC3F89001FBA41 /* ImageOrientation.cpp */,
1968019686 A8748D6612CC3763001FBA41 /* ImageOrientation.h */,

Source/WebCore/platform/graphics/ImageDecodeWorker.cpp

 1/*
 2 * Copyright (C) 2012 Company 100 Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "ImageDecodeWorker.h"
 28
 29#include <limits>
 30
 31#include <wtf/NumberOfCores.h>
 32#include <wtf/WorkQueue.h>
 33#include <wtf/text/CString.h>
 34#include <wtf/text/WTFString.h>
 35
 36namespace WebCore {
 37
 38Vector<WorkQueue*>* ImageDecodeWorker::s_workQueuePool = 0;
 39Vector<int>* ImageDecodeWorker::s_workQueueAcquireCount = 0;
 40
 41PassRefPtr<ImageDecodeWorker> ImageDecodeWorker::acquireSharedWorker()
 42{
 43 if (!s_workQueuePool)
 44 initializeWorkQueuePool();
 45
 46 return adoptRef(new ImageDecodeWorker());
 47}
 48
 49void ImageDecodeWorker::initializeWorkQueuePool()
 50{
 51 const int numCores = WTF::numberOfProcessorCores();
 52
 53 s_workQueueAcquireCount = new Vector<int>(numCores, 0);
 54 s_workQueuePool = new Vector<WorkQueue*>();
 55 s_workQueuePool->reserveInitialCapacity(numCores);
 56 for (int i = 0; i < numCores; i++) {
 57 s_workQueueAcquireCount->at(i) = 0;
 58 String queueName = "ImageDecodeWorker." + String::number(i);
 59 s_workQueuePool->append(new WorkQueue(queueName.ascii().data()));
 60 }
 61}
 62
 63int ImageDecodeWorker::queueIdWithMinimumAcquireCount()
 64{
 65 int minimumAcquireCount = std::numeric_limits<int>::max();
 66 int index = s_workQueuePool->size();
 67
 68 for (size_t i = 0; i < s_workQueuePool->size(); i++)
 69 if (s_workQueueAcquireCount->at(i) < minimumAcquireCount) {
 70 minimumAcquireCount = s_workQueueAcquireCount->at(i);
 71 index = i;
 72 }
 73
 74 ASSERT(index < s_workQueuePool->size());
 75 return index;
 76}
 77
 78ImageDecodeWorker::ImageDecodeWorker()
 79 : m_workerStatus(Running)
 80{
 81 m_workQueueId = queueIdWithMinimumAcquireCount();
 82 m_workQueue = (*s_workQueuePool)[m_workQueueId];
 83 s_workQueueAcquireCount->at(m_workQueueId)++;
 84}
 85
 86ImageDecodeWorker::~ImageDecodeWorker()
 87{
 88 ASSERT(m_workerStatus == InvaidationReady);
 89}
 90
 91bool ImageDecodeWorker::hasInvalidationBegun()
 92{
 93 MutexLocker locker(m_workerStatusMutex);
 94 if (m_workerStatus == InvalidationBegun) {
 95 m_workerStatus = InvaidationReady;
 96 m_invalidationReady.signal();
 97 }
 98 return m_workerStatus != Running;
 99}
 100
 101void ImageDecodeWorker::cancelableFunction(PassRefPtr<ImageDecodeWorker> worker, const Function<void()>& function)
 102{
 103 if (UNLIKELY(worker->hasInvalidationBegun()))
 104 return;
 105
 106 function();
 107}
 108
 109void ImageDecodeWorker::postTask(const Function<void()>& function)
 110{
 111 ASSERT(m_workerStatus == Running);
 112 m_workQueue->dispatch(bind(ImageDecodeWorker::cancelableFunction, this, function));
 113}
 114
 115void ImageDecodeWorker::invalidate()
 116{
 117 MutexLocker locker(m_workerStatusMutex);
 118
 119 if (m_workerStatus != Running)
 120 return;
 121
 122 m_workerStatus = InvalidationBegun;
 123
 124 m_workQueue->dispatch(bind(&ImageDecodeWorker::ensureTerminate, this));
 125 while (m_workerStatus != InvaidationReady)
 126 m_invalidationReady.wait(m_workerStatusMutex);
 127 s_workQueueAcquireCount->at(m_workQueueId)--;
 128}
 129
 130void ImageDecodeWorker::ensureTerminate(PassRefPtr<ImageDecodeWorker> worker)
 131{
 132 MutexLocker locker(worker->m_workerStatusMutex);
 133 ASSERT(worker->m_workerStatus != Running);
 134 worker->m_workerStatus = InvaidationReady;
 135 worker->m_invalidationReady.signal();
 136}
 137
 138} // namespace WebCore

Source/WebCore/platform/graphics/ImageDecodeWorker.h

 1/*
 2 * Copyright (C) 2012 Company 100 Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef ImageDecodeWorker_h
 27#define ImageDecodeWorker_h
 28
 29#include <wtf/Functional.h>
 30#include <wtf/RefCounted.h>
 31#include <wtf/WorkQueue.h>
 32
 33class WorkQueue;
 34
 35namespace WebCore {
 36
 37class ImageDecodeWorker : public ThreadSafeRefCounted<ImageDecodeWorker> {
 38public:
 39 static PassRefPtr<ImageDecodeWorker> acquireSharedWorker();
 40
 41 virtual ~ImageDecodeWorker();
 42
 43 void postTask(const Function<void()>&);
 44 void invalidate();
 45
 46private:
 47 static void initializeWorkQueuePool();
 48 static int queueIdWithMinimumAcquireCount();
 49
 50 // FIXME: These two static functions should become non-static methods.
 51 // However, defining them as non-static methods causes an unintended destructor
 52 // call while a Function object passed WorkQueue::dispatch() is being destructed.
 53 // To avoid this problem, these functions are defined as static methods.
 54 static void cancelableFunction(PassRefPtr<ImageDecodeWorker>, const Function<void()>&);
 55 static void ensureTerminate(PassRefPtr<ImageDecodeWorker>);
 56
 57 ImageDecodeWorker();
 58
 59 bool hasInvalidationBegun();
 60
 61 static Vector<WorkQueue*>* s_workQueuePool;
 62 static Vector<int>* s_workQueueAcquireCount;
 63
 64 enum WorkerStatus { Running, InvalidationBegun, InvaidationReady };
 65 Mutex m_workerStatusMutex;
 66 WorkerStatus m_workerStatus;
 67 ThreadCondition m_invalidationReady;
 68
 69 int m_workQueueId;
 70 WorkQueue* m_workQueue;
 71};
 72
 73} // namespace WebCore
 74
 75#endif // ImageDecodeWorker_h