Index: tests/skia_test.cpp |
diff --git a/tests/skia_test.cpp b/tests/skia_test.cpp |
index 0851f8e661a1559d538dbd969005c1084a85eb7b..031c2224a7544cbf174083f8ae6d29481c509637 100644 |
--- a/tests/skia_test.cpp |
+++ b/tests/skia_test.cpp |
@@ -7,6 +7,10 @@ |
#include "SkCommandLineFlags.h" |
#include "SkGraphics.h" |
+#include "SkRunnable.h" |
+#include "SkThreadPool.h" |
+#include "SkTArray.h" |
+#include "SkTScopedPtr.h" |
#include "Test.h" |
#include "SkOSFile.h" |
@@ -63,13 +67,12 @@ static const char* result2string(Reporter::Result result) { |
class DebugfReporter : public Reporter { |
public: |
DebugfReporter(bool allowExtendedTest) |
- : fIndex(0) |
+ : fNextIndex(0) |
, fTotal(0) |
, fAllowExtendedTest(allowExtendedTest) { |
} |
- void setIndexOfTotal(int index, int total) { |
- fIndex = index; |
+ void setTotal(int total) { |
fTotal = total; |
} |
@@ -79,18 +82,21 @@ public: |
protected: |
virtual void onStart(Test* test) { |
- SkDebugf("[%d/%d] %s...\n", fIndex+1, fTotal, test->getName()); |
+ const int index = sk_atomic_inc(&fNextIndex); |
+ SkDebugf("[%d/%d] %s...\n", index+1, fTotal, test->getName()); |
} |
virtual void onReport(const char desc[], Reporter::Result result) { |
SkDebugf("\t%s: %s\n", result2string(result), desc); |
} |
- virtual void onEnd(Test*) { |
- if (!this->getCurrSuccess()) { |
- SkDebugf("---- FAILED\n"); |
+ |
+ virtual void onEnd(Test* test) { |
+ if (!test->passed()) { |
+ SkDebugf("---- FAILED\n"); |
} |
} |
+ |
private: |
- int fIndex, fTotal; |
+ int fNextIndex, fTotal; |
bool fAllowExtendedTest; |
}; |
@@ -127,6 +133,27 @@ DEFINE_string2(tmpDir, t, NULL, "tmp directory for tests to use."); |
DEFINE_string2(resourcePath, i, NULL, "directory for test resources."); |
DEFINE_bool2(extendedTest, x, false, "run extended tests for pathOps."); |
DEFINE_bool2(verbose, v, false, "enable verbose output."); |
+DEFINE_int32(threads, 8, |
+ "If >0, run threadsafe tests on a threadpool with this many threads."); |
+ |
+// Deletes self when run. |
+class SkTestRunnable : public SkRunnable { |
+public: |
+ // Takes ownership of test. |
+ SkTestRunnable(Test* test, int* failCount) : fTest(test), fFailCount(failCount) {} |
+ |
+ virtual void run() { |
+ fTest->run(); |
+ if(!fTest->passed()) { |
+ sk_atomic_inc(fFailCount); |
+ } |
+ SkDELETE(this); |
+ } |
+ |
+private: |
+ SkTScopedPtr<Test> fTest; |
+ int* fFailCount; |
scroggo
2013/04/17 17:34:52
Shouldn't this be int32_t since it's passed to sk_
mtklein
2013/04/17 18:13:59
Done.
|
+}; |
int tool_main(int argc, char** argv); |
int tool_main(int argc, char** argv) { |
@@ -172,25 +199,33 @@ int tool_main(int argc, char** argv) { |
DebugfReporter reporter(FLAGS_extendedTest); |
Iter iter(&reporter); |
- Test* test; |
const int count = Iter::Count(); |
- int index = 0; |
+ reporter.setTotal(count); |
int failCount = 0; |
scroggo
2013/04/17 17:34:52
int32_t?
mtklein
2013/04/17 18:13:59
Done.
|
int skipCount = 0; |
- while ((test = iter.next()) != NULL) { |
- reporter.setIndexOfTotal(index, count); |
+ |
+ SkTScopedPtr<SkThreadPool> threadpool(SkNEW_ARGS(SkThreadPool, (FLAGS_threads))); |
+ SkTArray<Test*> unsafeTests; // Always passes ownership to an SkTestRunnable |
+ for (int i = 0; i < count; i++) { |
+ SkTScopedPtr<Test> test(iter.next()); |
if (!FLAGS_match.isEmpty() && !strstr(test->getName(), FLAGS_match[0])) { |
++skipCount; |
+ } else if (!test->isThreadsafe()) { |
+ unsafeTests.push_back() = test.release(); |
} else { |
- if (!test->run()) { |
- ++failCount; |
- } |
+ threadpool->add(SkNEW_ARGS(SkTestRunnable, (test.release(), &failCount))); |
} |
- SkDELETE(test); |
- index += 1; |
} |
+ // Run the tests that aren't threadsafe. |
+ for (int i = 0; i < unsafeTests.count(); i++) { |
+ SkNEW_ARGS(SkTestRunnable, (unsafeTests[i], &failCount))->run(); |
scroggo
2013/04/17 17:34:52
Won't the destructor for SkTArray call the destruc
mtklein
2013/04/17 18:13:59
This is an SkTArray<Test*>. Does SkTArray delete
|
+ } |
+ |
+ // Blocks until threaded tests finish. |
+ threadpool.reset(); |
+ |
SkDebugf("Finished %d tests, %d failures, %d skipped.\n", |
count, failCount, skipCount); |
int testCount = reporter.countTests(); |