add --race to FM
Try to uncover races by running parallel replicas. The default --race 0 should keep FM working as before, but now with --race ≥2 we'll actively try to race replicas, syncing between tests. --race 1 is almost pointless, just changing the thread tests run on but without any interesting concurrency. Rearrange a bit how fm_driver decides what flags to pass to which invocations of FM, so individual runs can easily override defaults (e.g. --nativeFonts overriding the usual --nonativeFonts). Use that here to set --race 0 for unit tests; many unit tests are not reentrant. Change-Id: Ida451626c093793b0805d3036beb185e7d54f27e Reviewed-on: https://skia-review.googlesource.com/c/skia/+/376761 Reviewed-by: Brian Osman <brianosman@google.com> Reviewed-by: Eric Boren <borenet@google.com> Commit-Queue: Mike Klein <mtklein@google.com>
This commit is contained in:
parent
b7b9a23281
commit
bc4a36af7c
@ -397,10 +397,15 @@ func main() {
|
||||
parts := strings.Split(*bot, "-")
|
||||
OS, model, CPU_or_GPU := parts[1], parts[3], parts[4]
|
||||
|
||||
commonFlags := []string{}
|
||||
// Bots use portable fonts except where we explicitly opt-in to native fonts.
|
||||
defaultFlags := []string{"--nonativeFonts"}
|
||||
|
||||
run := func(sources []string, extraFlags string) {
|
||||
kickoff(sources, append(strings.Fields(extraFlags), commonFlags...))
|
||||
// Default then extra to allow overriding the defaults.
|
||||
flags := []string{}
|
||||
flags = append(flags, defaultFlags...)
|
||||
flags = append(flags, strings.Fields(extraFlags)...)
|
||||
kickoff(sources, flags)
|
||||
}
|
||||
|
||||
gms := shorthands["gms"]
|
||||
@ -423,19 +428,21 @@ func main() {
|
||||
imgs = filter(imgs, func(s string) bool { return !rawExts[normalizedExt(s)] })
|
||||
}
|
||||
|
||||
if CPU_or_GPU == "CPU" {
|
||||
commonFlags = append(commonFlags, "-b", "cpu")
|
||||
if strings.Contains(*bot, "TSAN") {
|
||||
// Run each test a few times in parallel to uncover races.
|
||||
defaultFlags = append(defaultFlags, "--race", "4")
|
||||
}
|
||||
|
||||
// Run GMs once using native fonts, then switch to portable fonts for everything else.
|
||||
run(gms, "--nativeFonts true")
|
||||
commonFlags = append(commonFlags, "--nativeFonts", "false")
|
||||
if CPU_or_GPU == "CPU" {
|
||||
defaultFlags = append(defaultFlags, "-b", "cpu")
|
||||
|
||||
// FM's default ct/gamut/tf flags are equivalent to --config srgb in DM.
|
||||
run(gms, "")
|
||||
run(gms, "--nativeFonts")
|
||||
run(imgs, "")
|
||||
run(svgs, "")
|
||||
run(skps, "--clipW 1000 --clipH 1000")
|
||||
run(tests, "")
|
||||
run(tests, "--race 0") // Several unit tests are not reentrant.
|
||||
|
||||
if model == "GCE" {
|
||||
run(gms, "--ct g8 --legacy") // --config g8
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "src/core/SkColorSpacePriv.h"
|
||||
#include "src/core/SkMD5.h"
|
||||
#include "src/core/SkOSFile.h"
|
||||
#include "src/core/SkTaskGroup.h"
|
||||
#include "src/gpu/GrDirectContextPriv.h"
|
||||
#include "src/gpu/GrGpu.h"
|
||||
#include "src/utils/SkOSPath.h"
|
||||
@ -82,6 +83,7 @@ static DEFINE_int(clipH, INT_MAX, "Limit source height.");
|
||||
static DEFINE_bool (cpuDetect, true, "Detect CPU features for runtime optimizations?");
|
||||
static DEFINE_string2(writePath, w, "", "Write .pngs to this directory if set.");
|
||||
static DEFINE_bool (quick, false, "Skip image hashing and encoding?");
|
||||
static DEFINE_int (race, 0, "If >0, use threads to induce race conditions?");
|
||||
|
||||
static DEFINE_string(writeShaders, "", "Write GLSL shaders to this directory if set.");
|
||||
|
||||
@ -372,6 +374,7 @@ extern bool gSkVMJITViaDylib;
|
||||
int main(int argc, char** argv) {
|
||||
CommandLineFlags::Parse(argc, argv);
|
||||
SetupCrashHandler();
|
||||
SkTaskGroup::Enabler enabled(FLAGS_race);
|
||||
|
||||
if (FLAGS_cpuDetect) {
|
||||
SkGraphics::Init();
|
||||
@ -423,8 +426,11 @@ int main(int argc, char** argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const int replicas = std::max(1, FLAGS_race);
|
||||
|
||||
SkTArray<Source> sources;
|
||||
for (const SkString& name : FLAGS_sources) {
|
||||
for (const SkString& name : FLAGS_sources)
|
||||
for (int replica = 0; replica < replicas; replica++) {
|
||||
Source* source = &sources.push_back();
|
||||
source->name = name;
|
||||
|
||||
@ -549,7 +555,10 @@ int main(int argc, char** argv) {
|
||||
: SkColorSpace::MakeRGB(tf,gamut);
|
||||
const SkColorInfo color_info{ct,at,cs};
|
||||
|
||||
for (auto source : sources) {
|
||||
for (int i = 0; i < sources.count(); i += replicas)
|
||||
SkTaskGroup{}.batch(replicas, [=](int replica) {
|
||||
Source source = sources[i+replica];
|
||||
|
||||
AutoreleasePool pool;
|
||||
const auto start = std::chrono::steady_clock::now();
|
||||
|
||||
@ -593,12 +602,6 @@ int main(int argc, char** argv) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!image && !blob) {
|
||||
fprintf(stdout, "%50s skipped\n", source.name.c_str());
|
||||
fflush(stdout);
|
||||
continue;
|
||||
}
|
||||
|
||||
// We read back a bitmap even when --quick is set and we won't use it,
|
||||
// to keep us honest about deferred work, flushing pipelines, etc.
|
||||
SkBitmap bitmap;
|
||||
@ -606,6 +609,17 @@ int main(int argc, char** argv) {
|
||||
SK_ABORT("SkImage::asLegacyBitmap() failed.");
|
||||
}
|
||||
|
||||
// Our --race replicas have done their job by now if they're going to catch anything.
|
||||
if (replica != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!image && !blob) {
|
||||
fprintf(stdout, "%50s skipped\n", source.name.c_str());
|
||||
fflush(stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
SkString md5;
|
||||
if (!FLAGS_quick) {
|
||||
HashAndEncode hashAndEncode{bitmap};
|
||||
@ -646,7 +660,8 @@ int main(int argc, char** argv) {
|
||||
md5.c_str(),
|
||||
(int)std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count());
|
||||
fflush(stdout);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (!FLAGS_writeShaders.isEmpty()) {
|
||||
sk_mkdir(FLAGS_writeShaders[0]);
|
||||
|
Loading…
Reference in New Issue
Block a user