diff options
-rw-r--r-- | dm/DMSrcSink.cpp | 2 | ||||
-rw-r--r-- | include/core/SkExecutor.h | 3 | ||||
-rw-r--r-- | src/core/SkExecutor.cpp | 28 | ||||
-rw-r--r-- | src/core/SkTaskGroup.cpp | 2 | ||||
-rw-r--r-- | src/core/SkThreadedBMPDevice.cpp | 2 | ||||
-rw-r--r-- | tests/GrContextFactoryTest.cpp | 2 | ||||
-rw-r--r-- | tools/flags/SkCommonFlags.cpp | 2 |
7 files changed, 30 insertions, 11 deletions
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp index 384ad10568..57e1e5ef8d 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -1520,7 +1520,7 @@ GPUThreadTestingSink::GPUThreadTestingSink(GrContextFactory::ContextType ct, const GrContextOptions& grCtxOptions) : INHERITED(ct, overrides, samples, diText, colorType, alphaType, std::move(colorSpace), threaded, grCtxOptions) - , fExecutor(SkExecutor::MakeThreadPool(FLAGS_gpuThreads)) { + , fExecutor(SkExecutor::MakeFIFOThreadPool(FLAGS_gpuThreads)) { SkASSERT(fExecutor); } diff --git a/include/core/SkExecutor.h b/include/core/SkExecutor.h index 303f9e3f54..ad612f3762 100644 --- a/include/core/SkExecutor.h +++ b/include/core/SkExecutor.h @@ -16,7 +16,8 @@ public: virtual ~SkExecutor(); // Create a thread pool SkExecutor with a fixed thread count, by default the number of cores. - static std::unique_ptr<SkExecutor> MakeThreadPool(int threads = 0); + static std::unique_ptr<SkExecutor> MakeFIFOThreadPool(int threads = 0); + static std::unique_ptr<SkExecutor> MakeLIFOThreadPool(int threads = 0); // There is always a default SkExecutor available by calling SkExecutor::GetDefault(). static SkExecutor& GetDefault(); diff --git a/src/core/SkExecutor.cpp b/src/core/SkExecutor.cpp index 681841d253..d37431eabb 100644 --- a/src/core/SkExecutor.cpp +++ b/src/core/SkExecutor.cpp @@ -12,6 +12,7 @@ #include "SkSpinlock.h" #include "SkTArray.h" #include "SkThreadUtils.h" +#include <deque> #if defined(SK_BUILD_FOR_WIN32) #include <windows.h> @@ -46,7 +47,20 @@ void SkExecutor::SetDefault(SkExecutor* executor) { gDefaultExecutor = executor ? executor : &gTrivial; } +// We'll always push_back() new work, but pop from the front of deques or the back of SkTArray. +static inline std::function<void(void)> pop(std::deque<std::function<void(void)>>* list) { + std::function<void(void)> fn = std::move(list->front()); + list->pop_front(); + return fn; +} +static inline std::function<void(void)> pop(SkTArray<std::function<void(void)>>* list) { + std::function<void(void)> fn = std::move(list->back()); + list->pop_back(); + return fn; +} + // An SkThreadPool is an executor that runs work on a fixed pool of OS threads. +template <typename WorkList> class SkThreadPool final : public SkExecutor { public: explicit SkThreadPool(int threads) { @@ -91,8 +105,7 @@ private: { SkAutoExclusive lock(fWorkLock); SkASSERT(!fWork.empty()); // TODO: if (fWork.empty()) { return true; } ? - work = std::move(fWork.back()); - fWork.pop_back(); + work = pop(&fWork); } if (!work) { @@ -114,11 +127,16 @@ private: using Lock = SkMutex; SkTArray<std::unique_ptr<SkThread>> fThreads; - SkTArray<std::function<void(void)>> fWork; + WorkList fWork; Lock fWorkLock; SkSemaphore fWorkAvailable; }; -std::unique_ptr<SkExecutor> SkExecutor::MakeThreadPool(int threads) { - return skstd::make_unique<SkThreadPool>(threads > 0 ? threads : num_cores()); +std::unique_ptr<SkExecutor> SkExecutor::MakeFIFOThreadPool(int threads) { + using WorkList = std::deque<std::function<void(void)>>; + return skstd::make_unique<SkThreadPool<WorkList>>(threads > 0 ? threads : num_cores()); +} +std::unique_ptr<SkExecutor> SkExecutor::MakeLIFOThreadPool(int threads) { + using WorkList = SkTArray<std::function<void(void)>>; + return skstd::make_unique<SkThreadPool<WorkList>>(threads > 0 ? threads : num_cores()); } diff --git a/src/core/SkTaskGroup.cpp b/src/core/SkTaskGroup.cpp index c7927db5ba..58b9216343 100644 --- a/src/core/SkTaskGroup.cpp +++ b/src/core/SkTaskGroup.cpp @@ -45,7 +45,7 @@ void SkTaskGroup::wait() { SkTaskGroup::Enabler::Enabler(int threads) { if (threads) { - fThreadPool = SkExecutor::MakeThreadPool(threads); + fThreadPool = SkExecutor::MakeLIFOThreadPool(threads); SkExecutor::SetDefault(fThreadPool.get()); } } diff --git a/src/core/SkThreadedBMPDevice.cpp b/src/core/SkThreadedBMPDevice.cpp index 9b6be1cfba..608abb26e2 100644 --- a/src/core/SkThreadedBMPDevice.cpp +++ b/src/core/SkThreadedBMPDevice.cpp @@ -218,7 +218,7 @@ SkThreadedBMPDevice::SkThreadedBMPDevice(const SkBitmap& bitmap, , fThreadCnt(threads <= 0 ? tiles : threads) { if (executor == nullptr) { - fInternalExecutor = SkExecutor::MakeThreadPool(fThreadCnt); + fInternalExecutor = SkExecutor::MakeFIFOThreadPool(fThreadCnt); executor = fInternalExecutor.get(); } fExecutor = executor; diff --git a/tests/GrContextFactoryTest.cpp b/tests/GrContextFactoryTest.cpp index a6291cf42d..1514d67717 100644 --- a/tests/GrContextFactoryTest.cpp +++ b/tests/GrContextFactoryTest.cpp @@ -147,7 +147,7 @@ DEF_GPUTEST(GrContextFactory_executorAndTaskGroup, reporter, /*factory*/) { contextOptions.fExecutor = nullptr; GrContextFactory serialFactory(contextOptions); - std::unique_ptr<SkExecutor> threadPool = SkExecutor::MakeThreadPool(1); + std::unique_ptr<SkExecutor> threadPool = SkExecutor::MakeFIFOThreadPool(1); contextOptions.fExecutor = threadPool.get(); GrContextFactory threadedFactory(contextOptions); diff --git a/tools/flags/SkCommonFlags.cpp b/tools/flags/SkCommonFlags.cpp index 0986d2b57c..7884bef30e 100644 --- a/tools/flags/SkCommonFlags.cpp +++ b/tools/flags/SkCommonFlags.cpp @@ -131,6 +131,6 @@ bool CollectImages(SkCommandLineFlags::StringArray images, SkTArray<SkString>* o SkExecutor* GpuExecutorForTools() { static std::unique_ptr<SkExecutor> gGpuExecutor = (0 != FLAGS_gpuThreads) - ? SkExecutor::MakeThreadPool(FLAGS_gpuThreads) : nullptr; + ? SkExecutor::MakeFIFOThreadPool(FLAGS_gpuThreads) : nullptr; return gGpuExecutor.get(); } |