aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--dm/DMSrcSink.cpp2
-rw-r--r--include/core/SkExecutor.h3
-rw-r--r--src/core/SkExecutor.cpp28
-rw-r--r--src/core/SkTaskGroup.cpp2
-rw-r--r--src/core/SkThreadedBMPDevice.cpp2
-rw-r--r--tests/GrContextFactoryTest.cpp2
-rw-r--r--tools/flags/SkCommonFlags.cpp2
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();
}