Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Unified Diff: dm/DM.cpp

Issue 1675423002: dm: simplify parallel/serial decisions (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | dm/DMSrcSink.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dm/DM.cpp
diff --git a/dm/DM.cpp b/dm/DM.cpp
index 456c6abf6f0cee33744ee72ddd536bee60815fd3..c87f578babf22df5bf86aec95ace2b86d27ca205 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -583,12 +583,8 @@ static bool gather_srcs() {
for (auto image : images) {
push_codec_srcs(image);
- const char* ext = "";
- int index = image.findLastOf('.');
- if (index >= 0 && (size_t) ++index < image.size()) {
- ext = &image.c_str()[index];
- }
- if (brd_supported(ext)) {
+ const char* ext = strrchr(image.c_str(), '.');
+ if (ext && brd_supported(ext+1)) {
push_brd_srcs(image);
}
}
@@ -842,16 +838,16 @@ struct Task {
const TaggedSrc& src;
const TaggedSink& sink;
- static void Run(Task* task) {
- SkString name = task->src->name();
+ static void Run(const Task& task) {
+ SkString name = task.src->name();
// We'll skip drawing this Src/Sink pair if:
// - the Src vetoes the Sink;
// - this Src / Sink combination is on the blacklist;
// - it's a dry run.
- SkString note(task->src->veto(task->sink->flags()) ? " (veto)" : "");
- SkString whyBlacklisted = is_blacklisted(task->sink.tag.c_str(), task->src.tag.c_str(),
- task->src.options.c_str(), name.c_str());
+ SkString note(task.src->veto(task.sink->flags()) ? " (veto)" : "");
+ SkString whyBlacklisted = is_blacklisted(task.sink.tag.c_str(), task.src.tag.c_str(),
+ task.src.options.c_str(), name.c_str());
if (!whyBlacklisted.isEmpty()) {
note.appendf(" (--blacklist %s)", whyBlacklisted.c_str());
}
@@ -862,22 +858,22 @@ struct Task {
SkBitmap bitmap;
SkDynamicMemoryWStream stream;
if (FLAGS_pre_log) {
- SkDebugf("\nRunning %s->%s", name.c_str(), task->sink.tag.c_str());
+ SkDebugf("\nRunning %s->%s", name.c_str(), task.sink.tag.c_str());
}
- start(task->sink.tag.c_str(), task->src.tag, task->src.options, name.c_str());
- Error err = task->sink->draw(*task->src, &bitmap, &stream, &log);
+ start(task.sink.tag.c_str(), task.src.tag, task.src.options, name.c_str());
+ Error err = task.sink->draw(*task.src, &bitmap, &stream, &log);
if (!err.isEmpty()) {
if (err.isFatal()) {
fail(SkStringPrintf("%s %s %s %s: %s",
- task->sink.tag.c_str(),
- task->src.tag.c_str(),
- task->src.options.c_str(),
+ task.sink.tag.c_str(),
+ task.src.tag.c_str(),
+ task.src.options.c_str(),
name.c_str(),
err.c_str()));
} else {
note.appendf(" (skipped: %s)", err.c_str());
auto elapsed = now_ms() - timerStart;
- done(elapsed, task->sink.tag.c_str(), task->src.tag, task->src.options,
+ done(elapsed, task.sink.tag.c_str(), task.src.tag, task.src.options,
name, note, log);
return;
}
@@ -918,30 +914,30 @@ struct Task {
}
if (!FLAGS_readPath.isEmpty() &&
- !gGold.contains(Gold(task->sink.tag.c_str(), task->src.tag.c_str(),
- task->src.options.c_str(), name, md5))) {
+ !gGold.contains(Gold(task.sink.tag.c_str(), task.src.tag.c_str(),
+ task.src.options.c_str(), name, md5))) {
fail(SkStringPrintf("%s not found for %s %s %s %s in %s",
md5.c_str(),
- task->sink.tag.c_str(),
- task->src.tag.c_str(),
- task->src.options.c_str(),
+ task.sink.tag.c_str(),
+ task.src.tag.c_str(),
+ task.src.options.c_str(),
name.c_str(),
FLAGS_readPath[0]));
}
if (!FLAGS_writePath.isEmpty()) {
- const char* ext = task->sink->fileExtension();
+ const char* ext = task.sink->fileExtension();
if (data->getLength()) {
- WriteToDisk(*task, md5, ext, data, data->getLength(), nullptr);
+ WriteToDisk(task, md5, ext, data, data->getLength(), nullptr);
SkASSERT(bitmap.drawsNothing());
} else if (!bitmap.drawsNothing()) {
- WriteToDisk(*task, md5, ext, nullptr, 0, &bitmap);
+ WriteToDisk(task, md5, ext, nullptr, 0, &bitmap);
}
}
});
}
auto elapsed = now_ms() - timerStart;
- done(elapsed, task->sink.tag.c_str(), task->src.tag.c_str(), task->src.options.c_str(),
+ done(elapsed, task.sink.tag.c_str(), task.src.tag.c_str(), task.src.options.c_str(),
name, note, log);
}
@@ -1012,19 +1008,11 @@ struct Task {
}
};
-// Run all tasks in the same enclave serially on the same thread.
-// They can't possibly run concurrently with each other.
-static void run_enclave(SkTArray<Task>* tasks) {
- for (int i = 0; i < tasks->count(); i++) {
- Task::Run(tasks->begin() + i);
- }
-}
-
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// Unit tests don't fit so well into the Src/Sink model, so we give them special treatment.
-static SkTDArray<skiatest::Test> gThreadedTests, gGPUTests;
+static SkTDArray<skiatest::Test> gParallelTests, gSerialTests;
static void gather_tests() {
if (!FLAGS_src.contains("tests")) {
@@ -1041,14 +1029,14 @@ static void gather_tests() {
continue;
}
if (test.needsGpu && gpu_supported()) {
- (FLAGS_gpu_threading ? gThreadedTests : gGPUTests).push(test);
+ (FLAGS_gpu_threading ? gParallelTests : gSerialTests).push(test);
} else if (!test.needsGpu && FLAGS_cpu) {
- gThreadedTests.push(test);
+ gParallelTests.push(test);
}
}
}
-static void run_test(skiatest::Test* test) {
+static void run_test(skiatest::Test test) {
struct : public skiatest::Reporter {
void reportFailed(const skiatest::Failure& failure) override {
fail(failure.toString());
@@ -1061,33 +1049,25 @@ static void run_test(skiatest::Test* test) {
} reporter;
SkString note;
- SkString whyBlacklisted = is_blacklisted("_", "tests", "_", test->name);
+ SkString whyBlacklisted = is_blacklisted("_", "tests", "_", test.name);
if (!whyBlacklisted.isEmpty()) {
note.appendf(" (--blacklist %s)", whyBlacklisted.c_str());
}
auto timerStart = now_ms();
if (!FLAGS_dryRun && whyBlacklisted.isEmpty()) {
- start("unit", "test", "", test->name);
+ start("unit", "test", "", test.name);
GrContextFactory factory;
if (FLAGS_pre_log) {
- SkDebugf("\nRunning test %s", test->name);
+ SkDebugf("\nRunning test %s", test.name);
}
- test->proc(&reporter, &factory);
+ test.proc(&reporter, &factory);
}
- done(now_ms()-timerStart, "unit", "test", "", test->name, note, "");
+ done(now_ms()-timerStart, "unit", "test", "", test.name, note, "");
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-// If we're isolating all GPU-bound work to one thread (the default), this function runs all that.
-static void run_enclave_and_gpu_tests(SkTArray<Task>* tasks) {
- run_enclave(tasks);
- for (int i = 0; i < gGPUTests.count(); i++) {
- run_test(&gGPUTests[i]);
- }
-}
-
// Some runs (mostly, Valgrind) are so slow that the bot framework thinks we've hung.
// This prints something every once in a while so that it knows we're still working.
static void start_keepalive() {
@@ -1148,39 +1128,33 @@ int dm_main() {
gather_sinks();
gather_tests();
- gPending = gSrcs.count() * gSinks.count() + gThreadedTests.count() + gGPUTests.count();
+ gPending = gSrcs.count() * gSinks.count() + gParallelTests.count() + gSerialTests.count();
SkDebugf("%d srcs * %d sinks + %d tests == %d tasks\n",
- gSrcs.count(), gSinks.count(), gThreadedTests.count() + gGPUTests.count(), gPending);
-
- // We try to exploit as much parallelism as is safe. Most Src/Sink pairs run on any thread,
- // but Sinks that identify as part of a particular enclave run serially on a single thread.
- // CPU tests run on any thread. GPU tests depend on --gpu_threading.
- SkTArray<Task> enclaves[kNumEnclaves];
- for (int j = 0; j < gSinks.count(); j++) {
- SkTArray<Task>& tasks = enclaves[gSinks[j]->enclave()];
- for (int i = 0; i < gSrcs.count(); i++) {
- tasks.push_back(Task(gSrcs[i], gSinks[j]));
- }
- }
+ gSrcs.count(), gSinks.count(), gParallelTests.count() + gSerialTests.count(), gPending);
- SkTaskGroup tg;
- tg.batch(gThreadedTests.count(), [](int i){ run_test(&gThreadedTests[i]); });
- for (int i = 0; i < kNumEnclaves; i++) {
- SkTArray<Task>* currentEnclave = &enclaves[i];
- switch(i) {
- case kAnyThread_Enclave:
- tg.batch(currentEnclave->count(),
- [currentEnclave](int j) { Task::Run(&(*currentEnclave)[j]); });
- break;
- case kGPU_Enclave:
- tg.add([currentEnclave](){ run_enclave_and_gpu_tests(currentEnclave); });
- break;
- default:
- tg.add([currentEnclave](){ run_enclave(currentEnclave); });
- break;
+ // Kick off as much parallel work as we can, making note of any serial work we'll need to do.
+ SkTaskGroup parallel;
+ SkTArray<Task> serial;
+
+ for (auto& sink : gSinks)
+ for (auto& src : gSrcs) {
+ Task task(src, sink);
+ if (src->serial() || sink->serial()) {
+ serial.push_back(task);
+ } else {
+ parallel.add([task] { Task::Run(task); });
}
}
- tg.wait();
+ for (auto test : gParallelTests) {
+ parallel.add([test] { run_test(test); });
+ }
+
+ // With the parallel work running, run serial tasks and tests here on main thread.
+ for (auto task : serial) { Task::Run(task); }
+ for (auto test : gSerialTests) { run_test(test); }
+
+ // Wait for any remaining parallel work to complete (including any spun off of serial tasks).
+ parallel.wait();
gDefinitelyThreadSafeWork.wait();
// At this point we're back in single-threaded land.
« no previous file with comments | « no previous file | dm/DMSrcSink.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698