aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--dm/DM.cpp3
-rw-r--r--dm/DMQuiltTask.cpp6
-rw-r--r--dm/DMTask.cpp20
-rw-r--r--dm/DMTask.h9
-rw-r--r--dm/DMTaskRunner.cpp20
-rw-r--r--dm/DMTaskRunner.h13
-rw-r--r--dm/DMTestTask.cpp8
-rw-r--r--dm/DMTestTask.h1
-rw-r--r--gyp/dm.gypi2
-rwxr-xr-xgyp/pathops_skpclip.gyp3
-rw-r--r--gyp/pathops_unittest.gyp1
-rw-r--r--gyp/tools.gyp1
-rw-r--r--gyp/utils.gypi1
-rw-r--r--src/utils/SkRunnable.h13
-rw-r--r--src/utils/SkTaskGroup.cpp137
-rw-r--r--src/utils/SkTaskGroup.h34
-rw-r--r--src/utils/SkThreadPool.h221
-rw-r--r--tests/OnceTest.cpp10
-rw-r--r--tests/PathOpsExtendedTest.cpp5
-rw-r--r--tests/PathOpsExtendedTest.h2
-rw-r--r--tests/PathOpsOpCubicThreadedTest.cpp4
-rwxr-xr-xtests/PathOpsOpLoopThreadedTest.cpp6
-rw-r--r--tests/PathOpsOpRectThreadedTest.cpp4
-rw-r--r--tests/PathOpsQuadLineIntersectionThreadedTest.cpp4
-rwxr-xr-xtests/PathOpsSimplifyDegenerateThreadedTest.cpp4
-rw-r--r--tests/PathOpsSimplifyQuadThreadedTest.cpp4
-rwxr-xr-xtests/PathOpsSimplifyQuadralateralsThreadedTest.cpp4
-rw-r--r--tests/PathOpsSimplifyRectThreadedTest.cpp4
-rwxr-xr-xtests/PathOpsSimplifyTrianglesThreadedTest.cpp4
-rwxr-xr-xtests/PathOpsSkpClipTest.cpp44
-rw-r--r--tests/PathOpsThreadedCommon.cpp6
-rw-r--r--tests/PathOpsThreadedCommon.h6
-rw-r--r--tests/PathOpsTightBoundsTest.cpp8
-rw-r--r--tests/SkpSkGrTest.cpp15
-rw-r--r--tests/Test.cpp4
-rw-r--r--tests/Test.h1
-rw-r--r--tests/skia_test.cpp10
-rw-r--r--tools/flags/SkCommonFlags.cpp7
-rw-r--r--tools/flags/SkCommonFlags.h1
-rw-r--r--tools/iOSShell.cpp1
-rw-r--r--tools/skpdiff/SkDiffContext.cpp17
-rw-r--r--tools/valgrind.supp9
42 files changed, 294 insertions, 383 deletions
diff --git a/dm/DM.cpp b/dm/DM.cpp
index 09f0ce8f26..9d111eac30 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -41,7 +41,6 @@ using skiatest::TestRegistry;
static const char kGpuAPINameGL[] = "gl";
static const char kGpuAPINameGLES[] = "gles";
-DEFINE_int32(gpuThreads, 1, "Threads for GPU work.");
DEFINE_string2(expectations, r, "",
"If a directory, compare generated images against images under this path. "
"If a file, compare generated images against JSON expectations at this path."
@@ -233,7 +232,7 @@ int dm_main() {
SkDebugf("%d GMs x %d configs, %d tests, %d pictures\n",
gms.count(), configs.count(), tests.count(), skps.count());
DM::Reporter reporter;
- DM::TaskRunner tasks(FLAGS_threads, FLAGS_gpuThreads);
+ DM::TaskRunner tasks(FLAGS_threads);
kick_off_tests(tests, &reporter, &tasks);
kick_off_gms(gms, configs, gpuAPI, *expectations, &reporter, &tasks);
kick_off_skps(skps, &reporter, &tasks);
diff --git a/dm/DMQuiltTask.cpp b/dm/DMQuiltTask.cpp
index 6961f09671..a824de0f15 100644
--- a/dm/DMQuiltTask.cpp
+++ b/dm/DMQuiltTask.cpp
@@ -5,7 +5,7 @@
#include "SkBBHFactory.h"
#include "SkCommandLineFlags.h"
#include "SkPicture.h"
-#include "SkThreadPool.h"
+#include "SkTaskGroup.h"
DEFINE_bool(quilt, true, "If true, draw GM via a picture into a quilt of small tiles and compare.");
DEFINE_int32(quiltTile, 256, "Dimension of (square) quilt tile.");
@@ -96,11 +96,11 @@ void QuiltTask::draw() {
canvas.flush();
} else {
// Draw tiles in parallel into the same bitmap, simulating aggressive impl-side painting.
- SkThreadPool pool(SkThreadPool::kThreadPerCore);
+ SkTaskGroup tg;
for (int y = 0; y < tiles_needed(full.height(), FLAGS_quiltTile); y++) {
for (int x = 0; x < tiles_needed(full.width(), FLAGS_quiltTile); x++) {
// Deletes itself when done.
- pool.add(new Tile(x, y, *recorded, &full));
+ tg.add(new Tile(x, y, *recorded, &full));
}
}
}
diff --git a/dm/DMTask.cpp b/dm/DMTask.cpp
index 05eda4ea20..5ceb53b062 100644
--- a/dm/DMTask.cpp
+++ b/dm/DMTask.cpp
@@ -38,8 +38,8 @@ void Task::finish() {
fReporter->printStatus(this->name(), SkTime::GetMSecs() - fStart);
}
-void Task::spawnChildNext(CpuTask* task) {
- fTaskRunner->addNext(task);
+void Task::reallySpawnChild(CpuTask* task) {
+ fTaskRunner->add(task);
}
CpuTask::CpuTask(Reporter* reporter, TaskRunner* taskRunner) : Task(reporter, taskRunner) {}
@@ -56,32 +56,32 @@ void CpuTask::run() {
void CpuTask::spawnChild(CpuTask* task) {
// Run children serially on this (CPU) thread. This tends to save RAM and is usually no slower.
- // Calling spawnChildNext() is nearly equivalent, but it'd pointlessly contend on the
- // threadpool; spawnChildNext() is most useful when you want to change threadpools.
+ // Calling reallySpawnChild() is nearly equivalent, but it'd pointlessly contend on the
+ // threadpool; reallySpawnChild() is most useful when you want to change threadpools.
task->run();
}
GpuTask::GpuTask(Reporter* reporter, TaskRunner* taskRunner) : Task(reporter, taskRunner) {}
-void GpuTask::run(GrContextFactory& factory) {
+void GpuTask::run(GrContextFactory* factory) {
if (FLAGS_gpu && !this->shouldSkip()) {
this->start();
- if (!FLAGS_dryRun) this->draw(&factory);
+ if (!FLAGS_dryRun) this->draw(factory);
this->finish();
if (FLAGS_abandonGpuContext) {
- factory.abandonContexts();
+ factory->abandonContexts();
}
if (FLAGS_resetGpuContext || FLAGS_abandonGpuContext) {
- factory.destroyContexts();
+ factory->destroyContexts();
}
}
SkDELETE(this);
}
void GpuTask::spawnChild(CpuTask* task) {
- // Really spawn a new task so it runs on the CPU threadpool instead of the GPU one we're on now.
+ // Spawn a new task so it runs on the CPU threadpool instead of the GPU one we're on now.
// It goes on the front of the queue to minimize the time we must hold reference bitmaps in RAM.
- this->spawnChildNext(task);
+ this->reallySpawnChild(task);
}
} // namespace DM
diff --git a/dm/DMTask.h b/dm/DMTask.h
index 32bb9486f5..3f41b497ba 100644
--- a/dm/DMTask.h
+++ b/dm/DMTask.h
@@ -1,9 +1,10 @@
#ifndef DMTask_DEFINED
#define DMTask_DEFINED
-#include "DMReporter.h"
#include "DMGpuSupport.h"
+#include "DMReporter.h"
#include "SkRunnable.h"
+#include "SkTaskGroup.h"
#include "SkTime.h"
// DM will run() these tasks on one of two threadpools.
@@ -36,7 +37,7 @@ protected:
void fail(const char* msg = NULL);
void finish();
- void spawnChildNext(CpuTask* task); // For now we don't allow GPU child tasks.
+ void reallySpawnChild(CpuTask* task); // For now we don't allow GPU child tasks.
private:
Reporter* fReporter; // Unowned.
@@ -57,12 +58,12 @@ public:
void spawnChild(CpuTask* task);
};
-class GpuTask : public Task, public SkTRunnable<GrContextFactory> {
+class GpuTask : public Task {
public:
GpuTask(Reporter* reporter, TaskRunner* taskRunner);
virtual ~GpuTask() {}
- void run(GrContextFactory&) SK_OVERRIDE;
+ void run(GrContextFactory*);
virtual void draw(GrContextFactory*) = 0;
void spawnChild(CpuTask* task);
diff --git a/dm/DMTaskRunner.cpp b/dm/DMTaskRunner.cpp
index 8a0bc838e1..30d07babc8 100644
--- a/dm/DMTaskRunner.cpp
+++ b/dm/DMTaskRunner.cpp
@@ -3,19 +3,19 @@
namespace DM {
-TaskRunner::TaskRunner(int cpuThreads, int gpuThreads) : fCpu(cpuThreads), fGpu(gpuThreads) {}
+TaskRunner::TaskRunner(int cpuThreads) {
+ SkTaskGroup::SetThreadCount(cpuThreads);
+}
-void TaskRunner::add(CpuTask* task) { fCpu.add(task); }
-void TaskRunner::addNext(CpuTask* task) { fCpu.addNext(task); }
-void TaskRunner::add(GpuTask* task) { fGpu.add(task); }
+void TaskRunner::add(CpuTask* task) { fCpuWork.add(task); }
+void TaskRunner::add(GpuTask* task) { fGpuWork.push(task); }
void TaskRunner::wait() {
- // These wait calls block until each threadpool is done. We don't allow
- // spawning new child GPU tasks, so we can wait for that first knowing
- // we'll never try to add to it later. Same can't be said of the CPU pool:
- // both CPU and GPU tasks can spawn off new CPU work, so we wait for that last.
- fGpu.wait();
- fCpu.wait();
+ GrContextFactory factory;
+ for (int i = 0; i < fGpuWork.count(); i++) {
+ fGpuWork[i]->run(&factory);
+ }
+ fCpuWork.wait();
}
} // namespace DM
diff --git a/dm/DMTaskRunner.h b/dm/DMTaskRunner.h
index dd1440ed9a..d147525380 100644
--- a/dm/DMTaskRunner.h
+++ b/dm/DMTaskRunner.h
@@ -2,11 +2,12 @@
#define DMTaskRunner_DEFINED
#include "DMGpuSupport.h"
-#include "SkThreadPool.h"
+#include "SkTDArray.h"
+#include "SkTaskGroup.h"
#include "SkTypes.h"
// TaskRunner runs Tasks on one of two threadpools depending on the need for a GrContextFactory.
-// It's typically a good idea to run fewer GPU threads than CPU threads (go nuts with those).
+// We fix the number of GPU threads to 1, but go nuts with CPU threads.
namespace DM {
@@ -15,16 +16,16 @@ class GpuTask;
class TaskRunner : SkNoncopyable {
public:
- explicit TaskRunner(int cpuThreads, int gpuThreads);
+ // 0 -> one thread per core
+ explicit TaskRunner(int cpuThreads);
void add(CpuTask* task);
- void addNext(CpuTask* task);
void add(GpuTask* task);
void wait();
private:
- SkTThreadPool<void> fCpu;
- SkTThreadPool<GrContextFactory> fGpu;
+ SkTaskGroup fCpuWork;
+ SkTDArray<GpuTask*> fGpuWork;
};
} // namespace DM
diff --git a/dm/DMTestTask.cpp b/dm/DMTestTask.cpp
index 9e7f41e7d0..ad0c3fb4f3 100644
--- a/dm/DMTestTask.cpp
+++ b/dm/DMTestTask.cpp
@@ -3,17 +3,11 @@
#include "SkCommandLineFlags.h"
#include "SkCommonFlags.h"
-// When PathOps threaded tests get going, they're briefly a big consumer of lots of RAM.
-// We disable the internal threading there by default on 32-bit builds.
-static const bool is32Bit = sizeof(void*) == 4;
-
-DEFINE_bool2(pathOpsExtended, x, false, "Run extended pathOps tests.");
-DEFINE_bool2(pathOpsSingleThread, z, is32Bit, "Disallow pathOps tests from using threads.");
+DEFINE_bool2(pathOpsExtended, x, false, "Run extended pathOps tests.");
namespace DM {
bool TestReporter::allowExtendedTest() const { return FLAGS_pathOpsExtended; }
-bool TestReporter::allowThreaded() const { return !FLAGS_pathOpsSingleThread; }
bool TestReporter::verbose() const { return FLAGS_veryVerbose; }
static SkString test_name(const char* name) {
diff --git a/dm/DMTestTask.h b/dm/DMTestTask.h
index a65f096c58..ceb0e12e96 100644
--- a/dm/DMTestTask.h
+++ b/dm/DMTestTask.h
@@ -19,7 +19,6 @@ public:
private:
virtual bool allowExtendedTest() const SK_OVERRIDE;
- virtual bool allowThreaded() const SK_OVERRIDE;
virtual bool verbose() const SK_OVERRIDE;
virtual void onReportFailed(const SkString& desc) SK_OVERRIDE {
diff --git a/gyp/dm.gypi b/gyp/dm.gypi
index 1ecccd82b2..0d8652fd22 100644
--- a/gyp/dm.gypi
+++ b/gyp/dm.gypi
@@ -47,6 +47,8 @@
'../gm/gm.cpp',
'../gm/gm_expectations.cpp',
+ '../src/utils/SkTaskGroup.cpp',
+
'../src/pipe/utils/SamplePipeControllers.cpp',
'../src/utils/debugger/SkDebugCanvas.cpp',
'../src/utils/debugger/SkDrawCommand.cpp',
diff --git a/gyp/pathops_skpclip.gyp b/gyp/pathops_skpclip.gyp
index a1e51d65f8..32a909bd47 100755
--- a/gyp/pathops_skpclip.gyp
+++ b/gyp/pathops_skpclip.gyp
@@ -15,7 +15,7 @@
'../src/pipe/utils',
'../src/utils',
],
- 'dependencies': [
+ 'dependencies': [
'flags.gyp:flags',
'skia_lib.gyp:skia_lib',
'tools.gyp:crash_handler',
@@ -24,6 +24,7 @@
'sources': [
'../tests/PathOpsDebug.cpp',
'../tests/PathOpsSkpClipTest.cpp',
+ '../src/utils/SkTaskGroup.cpp',
],
'conditions': [
[ 'skia_android_framework == 1', {
diff --git a/gyp/pathops_unittest.gyp b/gyp/pathops_unittest.gyp
index d3152d2cf3..98e74bd54c 100644
--- a/gyp/pathops_unittest.gyp
+++ b/gyp/pathops_unittest.gyp
@@ -20,6 +20,7 @@
'../tests/PathOpsDebug.cpp',
'../tests/PathOpsOpLoopThreadedTest.cpp',
'../tests/skia_test.cpp',
+ '../src/utils/SkTaskGroup.cpp',
],
'conditions': [
[ 'skia_android_framework == 1', {
diff --git a/gyp/tools.gyp b/gyp/tools.gyp
index 66b84db66f..ce397f3cf3 100644
--- a/gyp/tools.gyp
+++ b/gyp/tools.gyp
@@ -167,6 +167,7 @@
'../tools/skpdiff/SkImageDiffer.cpp',
'../tools/skpdiff/SkPMetric.cpp',
'../tools/skpdiff/skpdiff_util.cpp',
+ '../src/utils/SkTaskGroup.cpp',
],
'include_dirs': [
'../src/core/', # needed for SkTLList.h
diff --git a/gyp/utils.gypi b/gyp/utils.gypi
index 9156b847c8..e62d287bb9 100644
--- a/gyp/utils.gypi
+++ b/gyp/utils.gypi
@@ -10,7 +10,6 @@
# Classes for a threadpool.
'<(skia_src_path)/utils/SkCondVar.h',
'<(skia_src_path)/utils/SkRunnable.h',
- '<(skia_src_path)/utils/SkThreadPool.h',
'<(skia_src_path)/utils/SkCondVar.cpp',
'<(skia_include_path)/utils/SkBoundaryPatch.h',
diff --git a/src/utils/SkRunnable.h b/src/utils/SkRunnable.h
index 5acf4dbc61..7a93b60c89 100644
--- a/src/utils/SkRunnable.h
+++ b/src/utils/SkRunnable.h
@@ -8,18 +8,9 @@
#ifndef SkRunnable_DEFINED
#define SkRunnable_DEFINED
-template <typename T>
-struct SkTRunnable {
- virtual ~SkTRunnable() {};
- virtual void run(T&) = 0;
-};
-
-template <>
-struct SkTRunnable<void> {
- virtual ~SkTRunnable() {};
+struct SkRunnable {
+ virtual ~SkRunnable() {};
virtual void run() = 0;
};
-typedef SkTRunnable<void> SkRunnable;
-
#endif
diff --git a/src/utils/SkTaskGroup.cpp b/src/utils/SkTaskGroup.cpp
new file mode 100644
index 0000000000..a42c0a43af
--- /dev/null
+++ b/src/utils/SkTaskGroup.cpp
@@ -0,0 +1,137 @@
+#include "SkTaskGroup.h"
+
+#include "SkCondVar.h"
+#include "SkLazyPtr.h"
+#include "SkTDArray.h"
+#include "SkThread.h"
+#include "SkThreadUtils.h"
+
+#if defined(SK_BUILD_FOR_WIN32)
+ static inline int num_cores() {
+ SYSTEM_INFO sysinfo;
+ GetSystemInfo(&sysinfo);
+ return sysinfo.dwNumberOfProcessors;
+ }
+#else
+ #include <unistd.h>
+ static inline int num_cores() {
+ return (int) sysconf(_SC_NPROCESSORS_ONLN);
+ }
+#endif
+
+namespace {
+
+static int gThreadCount = 0;
+
+class ThreadPool : SkNoncopyable {
+public:
+ static void Add(SkRunnable* task, int32_t* pending) {
+ Global()->add(task, pending);
+ }
+
+ static void Wait(int32_t* pending) {
+ while (sk_acquire_load(pending) > 0) { // Pairs with sk_atomic_dec here or in Loop.
+ // Lend a hand until our SkTaskGroup of interest is done.
+ ThreadPool* pool = Global();
+ Work work;
+ {
+ AutoLock lock(&pool->fReady);
+ if (pool->fWork.isEmpty()) {
+ // Someone has picked up all the work (including ours). How nice of them!
+ // (They may still be working on it, so we can't assert *pending == 0 here.)
+ continue;
+ }
+ pool->fWork.pop(&work);
+ }
+ // This Work isn't necessarily part of our SkTaskGroup of interest, but that's fine.
+ // We threads gotta stick together. We're always making forward progress.
+ work.task->run();
+ sk_atomic_dec(work.pending); // Release pairs with the sk_acquire_load() just above.
+ }
+ }
+
+private:
+ struct AutoLock {
+ AutoLock(SkCondVar* c) : fC(c) { fC->lock(); }
+ ~AutoLock() { fC->unlock(); }
+ private:
+ SkCondVar* fC;
+ };
+
+ struct Work {
+ SkRunnable* task; // A task to ->run(),
+ int32_t* pending; // then sk_atomic_dec(pending) afterwards.
+ };
+
+ static ThreadPool* Create() { return SkNEW(ThreadPool); }
+ static void Destroy(ThreadPool* p) { SkDELETE(p); }
+ static ThreadPool* Global() {
+ SK_DECLARE_STATIC_LAZY_PTR(ThreadPool, global, Create, Destroy);
+ return global.get();
+ }
+
+ ThreadPool() : fDraining(false) {
+ const int threads = gThreadCount ? gThreadCount : num_cores();
+ for (int i = 0; i < threads; i++) {
+ fThreads.push(SkNEW_ARGS(SkThread, (&ThreadPool::Loop, this)));
+ fThreads.top()->start();
+ }
+ }
+
+ ~ThreadPool() {
+ SkASSERT(fWork.isEmpty()); // All SkTaskGroups should be destroyed by now.
+ {
+ AutoLock lock(&fReady);
+ fDraining = true;
+ fReady.broadcast();
+ }
+ for (int i = 0; i < fThreads.count(); i++) {
+ fThreads[i]->join();
+ }
+ SkASSERT(fWork.isEmpty()); // Can't hurt to double check.
+ fThreads.deleteAll();
+ }
+
+ void add(SkRunnable* task, int32_t* pending) {
+ Work work = { task, pending };
+ sk_atomic_inc(pending); // No barrier needed.
+ {
+ AutoLock lock(&fReady);
+ fWork.push(work);
+ fReady.signal();
+ }
+ }
+
+ static void Loop(void* arg) {
+ ThreadPool* pool = (ThreadPool*)arg;
+ Work work;
+ while (true) {
+ {
+ AutoLock lock(&pool->fReady);
+ while (pool->fWork.isEmpty()) {
+ if (pool->fDraining) {
+ return;
+ }
+ pool->fReady.wait();
+ }
+ pool->fWork.pop(&work);
+ }
+ work.task->run();
+ sk_atomic_dec(work.pending); // Release pairs with sk_acquire_load() in Wait().
+ }
+ }
+
+ SkTDArray<Work> fWork;
+ SkTDArray<SkThread*> fThreads;
+ SkCondVar fReady;
+ bool fDraining;
+};
+
+} // namespace
+
+void SkTaskGroup::SetThreadCount(int n) { gThreadCount = n; }
+
+SkTaskGroup::SkTaskGroup() : fPending(0) {}
+
+void SkTaskGroup::add(SkRunnable* task) { ThreadPool::Add(task, &fPending); }
+void SkTaskGroup::wait() { ThreadPool::Wait(&fPending); }
diff --git a/src/utils/SkTaskGroup.h b/src/utils/SkTaskGroup.h
new file mode 100644
index 0000000000..af4d47aa97
--- /dev/null
+++ b/src/utils/SkTaskGroup.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkTaskGroup_DEFINED
+#define SkTaskGroup_DEFINED
+
+#include "SkTypes.h"
+#include "SkRunnable.h"
+
+class SkTaskGroup : SkNoncopyable {
+public:
+ // Call before creating any SkTaskGroup to set the number of threads all SkTaskGroups share.
+ // If not called, we default to the number of system-reported cores.
+ static void SetThreadCount(int);
+
+ SkTaskGroup();
+ ~SkTaskGroup() { this->wait(); }
+
+ // Add a task to this SkTaskGroup. It will likely run() on another thread.
+ void add(SkRunnable*);
+
+ // Block until all Tasks previously add()ed to this SkTaskGroup have run().
+ // You may safely reuse this SkTaskGroup after wait() returns.
+ void wait();
+
+private:
+ /*atomic*/ int32_t fPending;
+};
+
+#endif//SkTaskGroup_DEFINED
diff --git a/src/utils/SkThreadPool.h b/src/utils/SkThreadPool.h
deleted file mode 100644
index c99c5c4188..0000000000
--- a/src/utils/SkThreadPool.h
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkThreadPool_DEFINED
-#define SkThreadPool_DEFINED
-
-#include "SkCondVar.h"
-#include "SkRunnable.h"
-#include "SkTDArray.h"
-#include "SkTInternalLList.h"
-#include "SkThreadUtils.h"
-#include "SkTypes.h"
-
-#if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_ANDROID)
-# include <unistd.h>
-#endif
-
-// Returns the number of cores on this machine.
-static inline int num_cores() {
-#if defined(SK_BUILD_FOR_WIN32)
- SYSTEM_INFO sysinfo;
- GetSystemInfo(&sysinfo);
- return sysinfo.dwNumberOfProcessors;
-#elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_ANDROID)
- return (int) sysconf(_SC_NPROCESSORS_ONLN);
-#else
- return 1;
-#endif
-}
-
-template <typename T>
-class SkTThreadPool {
-public:
- /**
- * Create a threadpool with count threads, or one thread per core if kThreadPerCore.
- */
- static const int kThreadPerCore = -1;
- explicit SkTThreadPool(int count);
- ~SkTThreadPool();
-
- /**
- * Queues up an SkRunnable to run when a thread is available, or synchronously if count is 0.
- * Does not take ownership. NULL is a safe no-op. If T is not void, the runnable will be passed
- * a reference to a T on the thread's local stack.
- */
- void add(SkTRunnable<T>*);
-
- /**
- * Same as add, but adds the runnable as the very next to run rather than enqueueing it.
- */
- void addNext(SkTRunnable<T>*);
-
- /**
- * Block until all added SkRunnables have completed. Once called, calling add() is undefined.
- */
- void wait();
-
- private:
- struct LinkedRunnable {
- SkTRunnable<T>* fRunnable; // Unowned.
- SK_DECLARE_INTERNAL_LLIST_INTERFACE(LinkedRunnable);
- };
-
- enum State {
- kRunning_State, // Normal case. We've been constructed and no one has called wait().
- kWaiting_State, // wait has been called, but there still might be work to do or being done.
- kHalting_State, // There's no work to do and no thread is busy. All threads can shut down.
- };
-
- void addSomewhere(SkTRunnable<T>* r,
- void (SkTInternalLList<LinkedRunnable>::*)(LinkedRunnable*));
-
- SkTInternalLList<LinkedRunnable> fQueue;
- SkCondVar fReady;
- SkTDArray<SkThread*> fThreads;
- State fState;
- int fBusyThreads;
-
- static void Loop(void*); // Static because we pass in this.
-};
-
-template <typename T>
-SkTThreadPool<T>::SkTThreadPool(int count) : fState(kRunning_State), fBusyThreads(0) {
- if (count < 0) {
- count = num_cores();
- }
- // Create count threads, all running SkTThreadPool::Loop.
- for (int i = 0; i < count; i++) {
- SkThread* thread = SkNEW_ARGS(SkThread, (&SkTThreadPool::Loop, this));
- *fThreads.append() = thread;
- thread->start();
- }
-}
-
-template <typename T>
-SkTThreadPool<T>::~SkTThreadPool() {
- if (kRunning_State == fState) {
- this->wait();
- }
-}
-
-namespace SkThreadPoolPrivate {
-
-template <typename T>
-struct ThreadLocal {
- void run(SkTRunnable<T>* r) { r->run(data); }
- T data;
-};
-
-template <>
-struct ThreadLocal<void> {
- void run(SkTRunnable<void>* r) { r->run(); }
-};
-
-} // namespace SkThreadPoolPrivate
-
-template <typename T>
-void SkTThreadPool<T>::addSomewhere(SkTRunnable<T>* r,
- void (SkTInternalLList<LinkedRunnable>::* f)(LinkedRunnable*)) {
- if (r == NULL) {
- return;
- }
-
- if (fThreads.isEmpty()) {
- SkThreadPoolPrivate::ThreadLocal<T> threadLocal;
- threadLocal.run(r);
- return;
- }
-
- LinkedRunnable* linkedRunnable = SkNEW(LinkedRunnable);
- linkedRunnable->fRunnable = r;
- fReady.lock();
- SkASSERT(fState != kHalting_State); // Shouldn't be able to add work when we're halting.
- (fQueue.*f)(linkedRunnable);
- fReady.signal();
- fReady.unlock();
-}
-
-template <typename T>
-void SkTThreadPool<T>::add(SkTRunnable<T>* r) {
- this->addSomewhere(r, &SkTInternalLList<LinkedRunnable>::addToTail);
-}
-
-template <typename T>
-void SkTThreadPool<T>::addNext(SkTRunnable<T>* r) {
- this->addSomewhere(r, &SkTInternalLList<LinkedRunnable>::addToHead);
-}
-
-
-template <typename T>
-void SkTThreadPool<T>::wait() {
- fReady.lock();
- fState = kWaiting_State;
- fReady.broadcast();
- fReady.unlock();
-
- // Wait for all threads to stop.
- for (int i = 0; i < fThreads.count(); i++) {
- fThreads[i]->join();
- SkDELETE(fThreads[i]);
- }
- SkASSERT(fQueue.isEmpty());
-}
-
-template <typename T>
-/*static*/ void SkTThreadPool<T>::Loop(void* arg) {
- // The SkTThreadPool passes itself as arg to each thread as they're created.
- SkTThreadPool<T>* pool = static_cast<SkTThreadPool<T>*>(arg);
- SkThreadPoolPrivate::ThreadLocal<T> threadLocal;
-
- while (true) {
- // We have to be holding the lock to read the queue and to call wait.
- pool->fReady.lock();
- while(pool->fQueue.isEmpty()) {
- // Does the client want to stop and are all the threads ready to stop?
- // If so, we move into the halting state, and whack all the threads so they notice.
- if (kWaiting_State == pool->fState && pool->fBusyThreads == 0) {
- pool->fState = kHalting_State;
- pool->fReady.broadcast();
- }
- // Any time we find ourselves in the halting state, it's quitting time.
- if (kHalting_State == pool->fState) {
- pool->fReady.unlock();
- return;
- }
- // wait yields the lock while waiting, but will have it again when awoken.
- pool->fReady.wait();
- }
- // We've got the lock back here, no matter if we ran wait or not.
-
- // The queue is not empty, so we have something to run. Claim it.
- LinkedRunnable* r = pool->fQueue.head();
-
- pool->fQueue.remove(r);
-
- // Having claimed our SkRunnable, we now give up the lock while we run it.
- // Otherwise, we'd only ever do work on one thread at a time, which rather
- // defeats the point of this code.
- pool->fBusyThreads++;
- pool->fReady.unlock();
-
- // OK, now really do the work.
- threadLocal.run(r->fRunnable);
- SkDELETE(r);
-
- // Let everyone know we're not busy.
- pool->fReady.lock();
- pool->fBusyThreads--;
- pool->fReady.unlock();
- }
-
- SkASSERT(false); // Unreachable. The only exit happens when pool->fState is kHalting_State.
-}
-
-typedef SkTThreadPool<void> SkThreadPool;
-
-#endif
diff --git a/tests/OnceTest.cpp b/tests/OnceTest.cpp
index 389d257b73..192abaaee3 100644
--- a/tests/OnceTest.cpp
+++ b/tests/OnceTest.cpp
@@ -6,7 +6,7 @@
*/
#include "SkOnce.h"
-#include "SkThreadPool.h"
+#include "SkTaskGroup.h"
#include "Test.h"
static void add_five(int* x) {
@@ -42,7 +42,7 @@ public:
};
DEF_TEST(SkOnce_Multithreaded, r) {
- const int kTasks = 16, kThreads = 4;
+ const int kTasks = 16;
// Make a bunch of tasks that will race to be the first to add six to x.
Racer racers[kTasks];
@@ -54,11 +54,11 @@ DEF_TEST(SkOnce_Multithreaded, r) {
}
// Let them race.
- SkThreadPool pool(kThreads);
+ SkTaskGroup tg;
for (int i = 0; i < kTasks; i++) {
- pool.add(&racers[i]);
+ tg.add(&racers[i]);
}
- pool.wait();
+ tg.wait();
// Only one should have done the +=.
REPORTER_ASSERT(r, 6 == x);
diff --git a/tests/PathOpsExtendedTest.cpp b/tests/PathOpsExtendedTest.cpp
index 05d00045b9..f90b9fec69 100644
--- a/tests/PathOpsExtendedTest.cpp
+++ b/tests/PathOpsExtendedTest.cpp
@@ -14,8 +14,8 @@
#include "SkPaint.h"
#include "SkRTConf.h"
#include "SkStream.h"
+#include "SkTaskGroup.h"
#include "SkThread.h"
-#include "SkThreadPool.h"
#ifdef SK_BUILD_FOR_MAC
#include <sys/sysctl.h>
@@ -542,7 +542,7 @@ bool testThreadedPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkP
SK_DECLARE_STATIC_MUTEX(gMutex);
-int initializeTests(skiatest::Reporter* reporter, const char* test) {
+void initializeTests(skiatest::Reporter* reporter, const char* test) {
#if 0 // doesn't work yet
SK_CONF_SET("images.jpeg.suppressDecoderWarnings", true);
SK_CONF_SET("images.png.suppressDecoderWarnings", true);
@@ -566,7 +566,6 @@ int initializeTests(skiatest::Reporter* reporter, const char* test) {
}
}
}
- return reporter->allowThreaded() ? SkThreadPool::kThreadPerCore : 1;
}
void outputProgress(char* ramStr, const char* pathStr, SkPath::FillType pathFillType) {
diff --git a/tests/PathOpsExtendedTest.h b/tests/PathOpsExtendedTest.h
index 5f3413c572..a854410139 100644
--- a/tests/PathOpsExtendedTest.h
+++ b/tests/PathOpsExtendedTest.h
@@ -36,7 +36,7 @@ extern bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadSt
const char* pathStr);
extern bool testSimplify(skiatest::Reporter* reporter, const SkPath& path, const char* filename);
-int initializeTests(skiatest::Reporter* reporter, const char* testName);
+void initializeTests(skiatest::Reporter* reporter, const char* testName);
void outputProgress(char* ramStr, const char* pathStr, SkPath::FillType );
void outputProgress(char* ramStr, const char* pathStr, SkPathOp op);
diff --git a/tests/PathOpsOpCubicThreadedTest.cpp b/tests/PathOpsOpCubicThreadedTest.cpp
index 889ade0487..751ccc5f1b 100644
--- a/tests/PathOpsOpCubicThreadedTest.cpp
+++ b/tests/PathOpsOpCubicThreadedTest.cpp
@@ -67,8 +67,8 @@ static void testOpCubicsMain(PathOpsThreadState* data) {
}
DEF_TEST(PathOpsOpCubicsThreaded, reporter) {
- int threadCount = initializeTests(reporter, "cubicOp");
- PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+ initializeTests(reporter, "cubicOp");
+ PathOpsThreadedTestRunner testRunner(reporter);
for (int a = 0; a < 6; ++a) { // outermost
for (int b = a + 1; b < 7; ++b) {
for (int c = 0 ; c < 6; ++c) {
diff --git a/tests/PathOpsOpLoopThreadedTest.cpp b/tests/PathOpsOpLoopThreadedTest.cpp
index 71efff3edc..3f316d1fe9 100755
--- a/tests/PathOpsOpLoopThreadedTest.cpp
+++ b/tests/PathOpsOpLoopThreadedTest.cpp
@@ -62,8 +62,8 @@ static void testOpLoopsMain(PathOpsThreadState* data) {
}
DEF_TEST(PathOpsOpLoopsThreaded, reporter) {
- int threadCount = initializeTests(reporter, "cubicOp");
- PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+ initializeTests(reporter, "cubicOp");
+ PathOpsThreadedTestRunner testRunner(reporter);
for (int a = 0; a < 6; ++a) { // outermost
for (int b = a + 1; b < 7; ++b) {
for (int c = 0 ; c < 6; ++c) {
@@ -81,7 +81,7 @@ finish:
}
DEF_TEST(PathOpsOpLoops, reporter) {
- (void) initializeTests(reporter, "cubicOp");
+ initializeTests(reporter, "cubicOp");
PathOpsThreadState state;
state.fReporter = reporter;
SkBitmap bitmap;
diff --git a/tests/PathOpsOpRectThreadedTest.cpp b/tests/PathOpsOpRectThreadedTest.cpp
index 3d07d74bb0..1b6e4e86b9 100644
--- a/tests/PathOpsOpRectThreadedTest.cpp
+++ b/tests/PathOpsOpRectThreadedTest.cpp
@@ -74,8 +74,8 @@ static void testPathOpsRectsMain(PathOpsThreadState* data)
}
DEF_TEST(PathOpsRectsThreaded, reporter) {
- int threadCount = initializeTests(reporter, "testOp");
- PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+ initializeTests(reporter, "testOp");
+ PathOpsThreadedTestRunner testRunner(reporter);
for (int a = 0; a < 6; ++a) { // outermost
for (int b = a + 1; b < 7; ++b) {
for (int c = 0 ; c < 6; ++c) {
diff --git a/tests/PathOpsQuadLineIntersectionThreadedTest.cpp b/tests/PathOpsQuadLineIntersectionThreadedTest.cpp
index fd7581fa58..7e33b7b374 100644
--- a/tests/PathOpsQuadLineIntersectionThreadedTest.cpp
+++ b/tests/PathOpsQuadLineIntersectionThreadedTest.cpp
@@ -111,8 +111,8 @@ static void testQuadLineIntersectMain(PathOpsThreadState* data)
}
DEF_TEST(PathOpsQuadLineIntersectionThreaded, reporter) {
- int threadCount = initializeTests(reporter, "testQuadLineIntersect");
- PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+ initializeTests(reporter, "testQuadLineIntersect");
+ PathOpsThreadedTestRunner testRunner(reporter);
for (int a = 0; a < 16; ++a) {
for (int b = 0 ; b < 16; ++b) {
for (int c = 0 ; c < 16; ++c) {
diff --git a/tests/PathOpsSimplifyDegenerateThreadedTest.cpp b/tests/PathOpsSimplifyDegenerateThreadedTest.cpp
index 5cd3c35d8a..8e8c58bf44 100755
--- a/tests/PathOpsSimplifyDegenerateThreadedTest.cpp
+++ b/tests/PathOpsSimplifyDegenerateThreadedTest.cpp
@@ -68,8 +68,8 @@ static void testSimplifyDegeneratesMain(PathOpsThreadState* data) {
}
DEF_TEST(PathOpsSimplifyDegeneratesThreaded, reporter) {
- int threadCount = initializeTests(reporter, "testDegenerates");
- PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+ initializeTests(reporter, "testDegenerates");
+ PathOpsThreadedTestRunner testRunner(reporter);
for (int a = 0; a < 16; ++a) {
int ax = a & 0x03;
int ay = a >> 2;
diff --git a/tests/PathOpsSimplifyQuadThreadedTest.cpp b/tests/PathOpsSimplifyQuadThreadedTest.cpp
index dbbec3e3e6..3c92cca217 100644
--- a/tests/PathOpsSimplifyQuadThreadedTest.cpp
+++ b/tests/PathOpsSimplifyQuadThreadedTest.cpp
@@ -74,8 +74,8 @@ static void testSimplifyQuadsMain(PathOpsThreadState* data)
}
DEF_TEST(PathOpsSimplifyQuadsThreaded, reporter) {
- int threadCount = initializeTests(reporter, "testQuads");
- PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+ initializeTests(reporter, "testQuads");
+ PathOpsThreadedTestRunner testRunner(reporter);
int a = 0;
for (; a < 16; ++a) {
for (int b = a ; b < 16; ++b) {
diff --git a/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp b/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp
index afa9200389..f8e9a6e3dc 100755
--- a/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp
+++ b/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp
@@ -76,8 +76,8 @@ static void testSimplifyQuadralateralsMain(PathOpsThreadState* data)
}
DEF_TEST(PathOpsSimplifyQuadralateralsThreaded, reporter) {
- int threadCount = initializeTests(reporter, "testQuadralaterals");
- PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+ initializeTests(reporter, "testQuadralaterals");
+ PathOpsThreadedTestRunner testRunner(reporter);
for (int a = 0; a < 16; ++a) {
for (int b = a ; b < 16; ++b) {
for (int c = b ; c < 16; ++c) {
diff --git a/tests/PathOpsSimplifyRectThreadedTest.cpp b/tests/PathOpsSimplifyRectThreadedTest.cpp
index 9e6a5eaf03..52a78ece84 100644
--- a/tests/PathOpsSimplifyRectThreadedTest.cpp
+++ b/tests/PathOpsSimplifyRectThreadedTest.cpp
@@ -187,8 +187,8 @@ static void testSimplify4x4RectsMain(PathOpsThreadState* data)
}
DEF_TEST(PathOpsSimplifyRectsThreaded, reporter) {
- int threadCount = initializeTests(reporter, "testLine");
- PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+ initializeTests(reporter, "testLine");
+ PathOpsThreadedTestRunner testRunner(reporter);
for (int a = 0; a < 8; ++a) { // outermost
for (int b = a ; b < 8; ++b) {
for (int c = b ; c < 8; ++c) {
diff --git a/tests/PathOpsSimplifyTrianglesThreadedTest.cpp b/tests/PathOpsSimplifyTrianglesThreadedTest.cpp
index b5d6508846..ee0ca2bcaa 100755
--- a/tests/PathOpsSimplifyTrianglesThreadedTest.cpp
+++ b/tests/PathOpsSimplifyTrianglesThreadedTest.cpp
@@ -73,8 +73,8 @@ static void testSimplifyTrianglesMain(PathOpsThreadState* data) {
}
DEF_TEST(PathOpsSimplifyTrianglesThreaded, reporter) {
- int threadCount = initializeTests(reporter, "testTriangles");
- PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+ initializeTests(reporter, "testTriangles");
+ PathOpsThreadedTestRunner testRunner(reporter);
for (int a = 0; a < 15; ++a) {
int ax = a & 0x03;
int ay = a >> 2;
diff --git a/tests/PathOpsSkpClipTest.cpp b/tests/PathOpsSkpClipTest.cpp
index cdc3c1fcd9..0769141685 100755
--- a/tests/PathOpsSkpClipTest.cpp
+++ b/tests/PathOpsSkpClipTest.cpp
@@ -20,8 +20,8 @@
#include "SkString.h"
#include "SkTArray.h"
#include "SkTDArray.h"
+#include "SkTaskGroup.h"
#include "SkTemplates.h"
-#include "SkThreadPool.h"
#include "SkTime.h"
__SK_FORCE_IMAGE_DECODER_LINKING;
@@ -90,14 +90,14 @@ static SkString get_in_path(int dirNo, const char* filename) {
}
if (filename) {
path.appendf("%s%s", PATH_SLASH, filename);
- if (!sk_exists(path.c_str())) {
+ if (!sk_exists(path.c_str())) {
SkDebugf("could not read %s\n", path.c_str());
return SkString();
}
}
return path;
}
-
+
static void make_recursive_dir(const SkString& path) {
if (sk_exists(path.c_str())) {
return;
@@ -129,7 +129,7 @@ static SkString get_out_path(int dirNo, const char* dirName) {
make_recursive_dir(path);
return path;
}
-
+
static SkString get_sum_path(const char* dirName) {
SkString path;
SkASSERT(dirName);
@@ -166,12 +166,12 @@ struct TestResult {
fTestStep = kCompareBits;
fScale = 1;
}
-
+
void init(int dirNo, const SkString& filename) {
fDirNo = dirNo;
strcpy(fFilename, filename.c_str());
fTestStep = kCompareBits;
- fScale = 1;
+ fScale = 1;
}
SkString status() {
@@ -204,7 +204,7 @@ struct TestResult {
}
void testOne();
-
+
char fFilename[kMaxLength];
TestStep fTestStep;
int fDirNo;
@@ -245,13 +245,8 @@ struct TestState {
};
struct TestRunner {
- TestRunner(int threadCount)
- : fNumThreads(threadCount) {
- }
-
~TestRunner();
void render();
- int fNumThreads;
SkTDArray<class TestRunnable*> fRunnables;
};
@@ -300,9 +295,9 @@ TestRunner::~TestRunner() {
}
void TestRunner::render() {
- SkThreadPool pool(fNumThreads);
+ SkTaskGroup tg;
for (int index = 0; index < fRunnables.count(); ++ index) {
- pool.add(fRunnables[index]);
+ tg.add(fRunnables[index]);
}
}
@@ -531,18 +526,12 @@ DEFINE_string2(dir, d, NULL, "range of directories (e.g., 1-100)");
DEFINE_string2(skp, s, NULL, "skp to test");
DEFINE_bool2(single, z, false, "run tests on a single thread internally.");
DEFINE_int32(testIndex, 0, "override local test index (PathOpsSkpClipOneOff only).");
-DEFINE_int32(threads, SkThreadPool::kThreadPerCore,
- "Run threadsafe tests on a threadpool with this many threads.");
DEFINE_bool2(verbose, v, false, "enable verbose output.");
static bool verbose() {
return FLAGS_verbose;
}
-static int getThreadCount() {
- return FLAGS_single ? 1 : FLAGS_threads;
-}
-
class Dirs {
public:
Dirs() {
@@ -616,7 +605,7 @@ public:
}
return NULL;
}
-
+
void set(const SkCommandLineFlags::StringArray& names) {
fNames = &names;
}
@@ -626,7 +615,7 @@ private:
const SkCommandLineFlags::StringArray* fNames;
} gNames;
-static bool buildTestDir(int dirNo, int firstDirNo,
+static bool buildTestDir(int dirNo, int firstDirNo,
SkTDArray<TestResult>* tests, SkTDArray<SortByName*>* sorted) {
SkString dirName = get_out_path(dirNo, outStatusDir);
if (!dirName.size()) {
@@ -792,8 +781,7 @@ static void encodeFound(TestState& state) {
}
}
}
- int threadCount = getThreadCount();
- TestRunner testRunner(threadCount);
+ TestRunner testRunner;
for (int index = 0; index < state.fPixelWorst.count(); ++index) {
const TestResult& result = state.fPixelWorst[index];
SkString filename(result.fFilename);
@@ -865,8 +853,7 @@ static void testSkpClipMain(TestState* data) {
DEF_TEST(PathOpsSkpClipThreaded) {
gDirs.setDefault();
initTest();
- int threadCount = getThreadCount();
- TestRunner testRunner(threadCount);
+ TestRunner testRunner;
int dirNo;
gDirs.reset();
while ((dirNo = gDirs.next()) > 0) {
@@ -889,7 +876,7 @@ DEF_TEST(PathOpsSkpClipThreaded) {
}
encodeFound(state);
}
-
+
static bool buildTests(SkTDArray<TestResult>* tests, SkTDArray<SortByName*>* sorted) {
int firstDirNo = gDirs.first();
int dirNo;
@@ -912,8 +899,7 @@ DEF_TEST(PathOpsSkpClipUberThreaded) {
if (!buildTests(tests.get(), sorted.get())) {
return;
}
- int threadCount = getThreadCount();
- TestRunner testRunner(threadCount);
+ TestRunner testRunner;
int dirNo;
gDirs.reset();
while ((dirNo = gDirs.next()) > 0) {
diff --git a/tests/PathOpsThreadedCommon.cpp b/tests/PathOpsThreadedCommon.cpp
index ac4cd6ba62..0adde915e0 100644
--- a/tests/PathOpsThreadedCommon.cpp
+++ b/tests/PathOpsThreadedCommon.cpp
@@ -7,7 +7,7 @@
#include "PathOpsExtendedTest.h"
#include "PathOpsThreadedCommon.h"
-#include "SkThreadPool.h"
+#include "SkTaskGroup.h"
PathOpsThreadedTestRunner::~PathOpsThreadedTestRunner() {
for (int index = 0; index < fRunnables.count(); index++) {
@@ -16,8 +16,8 @@ PathOpsThreadedTestRunner::~PathOpsThreadedTestRunner() {
}
void PathOpsThreadedTestRunner::render() {
- SkThreadPool pool(fNumThreads);
+ SkTaskGroup tg;
for (int index = 0; index < fRunnables.count(); ++ index) {
- pool.add(fRunnables[index]);
+ tg.add(fRunnables[index]);
}
}
diff --git a/tests/PathOpsThreadedCommon.h b/tests/PathOpsThreadedCommon.h
index a638cd2fdf..124921e389 100644
--- a/tests/PathOpsThreadedCommon.h
+++ b/tests/PathOpsThreadedCommon.h
@@ -33,17 +33,13 @@ struct PathOpsThreadState {
class PathOpsThreadedTestRunner {
public:
- PathOpsThreadedTestRunner(skiatest::Reporter* reporter, int threadCount)
- : fNumThreads(threadCount)
- , fReporter(reporter) {
- }
+ PathOpsThreadedTestRunner(skiatest::Reporter* reporter) : fReporter(reporter) {}
~PathOpsThreadedTestRunner();
void render();
public:
- int fNumThreads;
SkTDArray<PathOpsThreadedRunnable*> fRunnables;
skiatest::Reporter* fReporter;
};
diff --git a/tests/PathOpsTightBoundsTest.cpp b/tests/PathOpsTightBoundsTest.cpp
index 09f962296f..cea37520b1 100644
--- a/tests/PathOpsTightBoundsTest.cpp
+++ b/tests/PathOpsTightBoundsTest.cpp
@@ -35,8 +35,8 @@ static void testTightBoundsLines(PathOpsThreadState* data) {
}
DEF_TEST(PathOpsTightBoundsLines, reporter) {
- int threadCount = initializeTests(reporter, "tightBoundsLines");
- PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+ initializeTests(reporter, "tightBoundsLines");
+ PathOpsThreadedTestRunner testRunner(reporter);
int outerCount = reporter->allowExtendedTest() ? 100 : 1;
for (int index = 0; index < outerCount; ++index) {
for (int idx2 = 0; idx2 < 10; ++idx2) {
@@ -110,8 +110,8 @@ static void testTightBoundsQuads(PathOpsThreadState* data) {
}
DEF_TEST(PathOpsTightBoundsQuads, reporter) {
- int threadCount = initializeTests(reporter, "tightBoundsQuads");
- PathOpsThreadedTestRunner testRunner(reporter, threadCount);
+ initializeTests(reporter, "tightBoundsQuads");
+ PathOpsThreadedTestRunner testRunner(reporter);
int outerCount = reporter->allowExtendedTest() ? 100 : 1;
for (int index = 0; index < outerCount; ++index) {
for (int idx2 = 0; idx2 < 10; ++idx2) {
diff --git a/tests/SkpSkGrTest.cpp b/tests/SkpSkGrTest.cpp
index c1883a9890..c882654650 100644
--- a/tests/SkpSkGrTest.cpp
+++ b/tests/SkpSkGrTest.cpp
@@ -23,7 +23,7 @@
#include "SkString.h"
#include "SkTArray.h"
#include "SkTDArray.h"
-#include "SkThreadPool.h"
+#include "SkTaskGroup.h"
#include "SkTime.h"
#include "Test.h"
@@ -125,14 +125,12 @@ struct SkpSkGrThreadState {
};
struct SkpSkGrThreadedTestRunner {
- SkpSkGrThreadedTestRunner(skiatest::Reporter* reporter, int threadCount)
- : fNumThreads(threadCount)
- , fReporter(reporter) {
+ SkpSkGrThreadedTestRunner(skiatest::Reporter* reporter)
+ : fReporter(reporter) {
}
~SkpSkGrThreadedTestRunner();
void render();
- int fNumThreads;
SkTDArray<SkpSkGrThreadedRunnable*> fRunnables;
skiatest::Reporter* fReporter;
};
@@ -164,9 +162,9 @@ SkpSkGrThreadedTestRunner::~SkpSkGrThreadedTestRunner() {
}
void SkpSkGrThreadedTestRunner::render() {
- SkThreadPool pool(fNumThreads);
+ SkTaskGroup tg;
for (int index = 0; index < fRunnables.count(); ++ index) {
- pool.add(fRunnables[index]);
+ tg.add(fRunnables[index]);
}
}
@@ -676,8 +674,7 @@ DEF_TEST(SkpSkGrThreaded, reporter) {
if (!initTest()) {
return;
}
- int threadCount = reporter->allowThreaded() ? 3 : 1;
- SkpSkGrThreadedTestRunner testRunner(reporter, threadCount);
+ SkpSkGrThreadedTestRunner testRunner(reporter);
for (int dirIndex = 1; dirIndex <= 100; ++dirIndex) {
SkString pictDir = make_in_dir_name(dirIndex);
if (pictDir.size() == 0) {
diff --git a/tests/Test.cpp b/tests/Test.cpp
index 20afd45561..d0147e1e4a 100644
--- a/tests/Test.cpp
+++ b/tests/Test.cpp
@@ -75,10 +75,6 @@ protected:
return fReporter->allowExtendedTest();
}
- virtual bool allowThreaded() const SK_OVERRIDE {
- return fReporter->allowThreaded();
- }
-
virtual void bumpTestCount() SK_OVERRIDE {
fReporter->bumpTestCount();
}
diff --git a/tests/Test.h b/tests/Test.h
index 72b0bee126..6c85b32bce 100644
--- a/tests/Test.h
+++ b/tests/Test.h
@@ -32,7 +32,6 @@ namespace skiatest {
void endTest(Test*);
virtual bool allowExtendedTest() const { return false; }
- virtual bool allowThreaded() const { return false; }
virtual bool verbose() const { return false; }
virtual void bumpTestCount() { sk_atomic_inc(&fTestCount); }
diff --git a/tests/skia_test.cpp b/tests/skia_test.cpp
index 97ac29b0fd..a73b6bae53 100644
--- a/tests/skia_test.cpp
+++ b/tests/skia_test.cpp
@@ -12,8 +12,8 @@
#include "SkGraphics.h"
#include "SkOSFile.h"
#include "SkTArray.h"
+#include "SkTaskGroup.h"
#include "SkTemplates.h"
-#include "SkThreadPool.h"
#include "SkTime.h"
#include "Test.h"
@@ -54,7 +54,6 @@ public:
explicit DebugfReporter(int total) : fDone(0), fTotal(total) {}
virtual bool allowExtendedTest() const SK_OVERRIDE { return FLAGS_extendedTest; }
- virtual bool allowThreaded() const SK_OVERRIDE { return !FLAGS_single; }
virtual bool verbose() const SK_OVERRIDE { return FLAGS_veryVerbose; }
protected:
@@ -175,7 +174,8 @@ int test_main() {
int32_t failCount = 0;
int skipCount = 0;
- SkThreadPool threadpool(FLAGS_threads);
+ SkTaskGroup::SetThreadCount(FLAGS_threads);
+ SkTaskGroup cpuTests;
SkTArray<Test*> gpuTests; // Always passes ownership to an SkTestRunnable
DebugfReporter reporter(toRun);
@@ -186,7 +186,7 @@ int test_main() {
} else if (test->isGPUTest()) {
gpuTests.push_back() = test.detach();
} else {
- threadpool.add(SkNEW_ARGS(SkTestRunnable, (test.detach(), &failCount)));
+ cpuTests.add(SkNEW_ARGS(SkTestRunnable, (test.detach(), &failCount)));
}
}
@@ -204,7 +204,7 @@ int test_main() {
}
// Block until threaded tests finish.
- threadpool.wait();
+ cpuTests.wait();
if (FLAGS_verbose) {
SkDebugf("\nFinished %d tests, %d failures, %d skipped. (%d internal tests)",
diff --git a/tools/flags/SkCommonFlags.cpp b/tools/flags/SkCommonFlags.cpp
index 4d08ba6340..7776c36a59 100644
--- a/tools/flags/SkCommonFlags.cpp
+++ b/tools/flags/SkCommonFlags.cpp
@@ -6,7 +6,6 @@
*/
#include "SkCommonFlags.h"
-#include "SkThreadPool.h"
DEFINE_string(config, "565 8888 pdf gpu nonrendering angle",
"Options: 565 8888 pdf gpu nonrendering msaa4 msaa16 nvprmsaa4 nvprmsaa16 "
@@ -42,12 +41,10 @@ DEFINE_bool(resetGpuContext, true, "Reset the GrContext before running each test
DEFINE_bool(abandonGpuContext, false, "Abandon the GrContext after running each test. "
"Implies --resetGpuContext.");
-DEFINE_bool2(single, z, false, "run tests on a single thread internally.");
-
DEFINE_string(skps, "skps", "Directory to read skps from.");
-DEFINE_int32(threads, SkThreadPool::kThreadPerCore,
- "run threadsafe tests on a threadpool with this many threads.");
+DEFINE_int32(threads, 0, "Run threadsafe tests on a threadpool with this many threads, "
+ "defaulting to one thread per core.");
DEFINE_bool2(verbose, v, false, "enable verbose output from the test driver.");
diff --git a/tools/flags/SkCommonFlags.h b/tools/flags/SkCommonFlags.h
index b45ef0738a..ecd4148448 100644
--- a/tools/flags/SkCommonFlags.h
+++ b/tools/flags/SkCommonFlags.h
@@ -20,7 +20,6 @@ DECLARE_string(match);
DECLARE_bool(quiet);
DECLARE_bool(resetGpuContext);
DECLARE_bool(abandonGpuContext);
-DECLARE_bool(single);
DECLARE_string(skps);
DECLARE_int32(threads);
DECLARE_string(resourcePath);
diff --git a/tools/iOSShell.cpp b/tools/iOSShell.cpp
index 49be34d65b..8656e645aa 100644
--- a/tools/iOSShell.cpp
+++ b/tools/iOSShell.cpp
@@ -12,7 +12,6 @@
#include "SkCanvas.h"
#include "SkCommonFlags.h"
#include "SkGraphics.h"
-#include "SkThreadPool.h"
#include "SkWindow.h"
#include "sk_tool_utils.h"
diff --git a/tools/skpdiff/SkDiffContext.cpp b/tools/skpdiff/SkDiffContext.cpp
index 42d20de19d..78d8400968 100644
--- a/tools/skpdiff/SkDiffContext.cpp
+++ b/tools/skpdiff/SkDiffContext.cpp
@@ -12,7 +12,7 @@
#include "SkSize.h"
#include "SkStream.h"
#include "SkTDict.h"
-#include "SkThreadPool.h"
+#include "SkTaskGroup.h"
// from the tools directory for replace_char(...)
#include "picture_utils.h"
@@ -24,7 +24,6 @@
SkDiffContext::SkDiffContext() {
fDiffers = NULL;
fDifferCount = 0;
- fThreadCount = SkThreadPool::kThreadPerCore;
}
SkDiffContext::~SkDiffContext() {
@@ -87,7 +86,7 @@ static SkString get_common_prefix(const SkString& a, const SkString& b) {
}
static SkString get_combined_name(const SkString& a, const SkString& b) {
- // Note (stephana): We must keep this function in sync with
+ // Note (stephana): We must keep this function in sync with
// getImageDiffRelativeUrl() in static/loader.js (under rebaseline_server).
SkString result = a;
result.append("-vs-");
@@ -238,7 +237,7 @@ void SkDiffContext::diffDirectories(const char baselinePath[], const char testPa
return;
}
- SkThreadPool threadPool(fThreadCount);
+ SkTaskGroup tg;
SkTArray<SkThreadedDiff> runnableDiffs;
runnableDiffs.reset(baselineEntries.count());
@@ -253,13 +252,11 @@ void SkDiffContext::diffDirectories(const char baselinePath[], const char testPa
if (sk_exists(testFile.c_str()) && !sk_isdir(testFile.c_str())) {
// Queue up the comparison with the differ
runnableDiffs[x].setup(this, baselineFile, testFile);
- threadPool.add(&runnableDiffs[x]);
+ tg.add(&runnableDiffs[x]);
} else {
SkDebugf("Baseline file \"%s\" has no corresponding test file\n", baselineFile.c_str());
}
}
-
- threadPool.wait();
}
@@ -284,16 +281,14 @@ void SkDiffContext::diffPatterns(const char baselinePattern[], const char testPa
return;
}
- SkThreadPool threadPool(fThreadCount);
+ SkTaskGroup tg;
SkTArray<SkThreadedDiff> runnableDiffs;
runnableDiffs.reset(baselineEntries.count());
for (int x = 0; x < baselineEntries.count(); x++) {
runnableDiffs[x].setup(this, baselineEntries[x], testEntries[x]);
- threadPool.add(&runnableDiffs[x]);
+ tg.add(&runnableDiffs[x]);
}
-
- threadPool.wait();
}
void SkDiffContext::outputRecords(SkWStream& stream, bool useJSONP) {
diff --git a/tools/valgrind.supp b/tools/valgrind.supp
index d96ada04e7..f0331ed4cb 100644
--- a/tools/valgrind.supp
+++ b/tools/valgrind.supp
@@ -213,3 +213,12 @@
Memcheck:Addr2
fun:_ZN22GrAAConvexPathRenderer10onDrawPathERK6SkPathRK11SkStrokeRecP12GrDrawTargetb
}
+
+{
+ sk_task_group_thread_pool_intentionally_leaks_in_Release_mode
+ Memcheck:Leak
+ ...
+ fun:_ZN8SkThreadC1EPFvPvES0_
+ ...
+ fun:_ZN11SkTaskGroup3addEP10SkRunnable
+}