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

Side by Side Diff: dm/DM.cpp

Issue 1730943003: Rethink DM output (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: simplify name Created 4 years, 9 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "CrashHandler.h" 8 #include "CrashHandler.h"
9 #include "DMJsonWriter.h" 9 #include "DMJsonWriter.h"
10 #include "DMSrcSink.h" 10 #include "DMSrcSink.h"
11 #include "DMSrcSinkAndroid.h" 11 #include "DMSrcSinkAndroid.h"
12 #include "OverwriteLine.h"
13 #include "ProcStats.h" 12 #include "ProcStats.h"
14 #include "SkBBHFactory.h" 13 #include "SkBBHFactory.h"
15 #include "SkChecksum.h" 14 #include "SkChecksum.h"
16 #include "SkCodec.h" 15 #include "SkCodec.h"
17 #include "SkCommonFlags.h" 16 #include "SkCommonFlags.h"
18 #include "SkCommonFlagsConfig.h" 17 #include "SkCommonFlagsConfig.h"
19 #include "SkFontMgr.h" 18 #include "SkFontMgr.h"
20 #include "SkForceLinking.h" 19 #include "SkForceLinking.h"
21 #include "SkGraphics.h" 20 #include "SkGraphics.h"
22 #include "SkMD5.h" 21 #include "SkMD5.h"
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 74
76 SK_DECLARE_STATIC_MUTEX(gFailuresMutex); 75 SK_DECLARE_STATIC_MUTEX(gFailuresMutex);
77 static SkTArray<SkString> gFailures; 76 static SkTArray<SkString> gFailures;
78 77
79 static void fail(ImplicitString err) { 78 static void fail(ImplicitString err) {
80 SkAutoMutexAcquire lock(gFailuresMutex); 79 SkAutoMutexAcquire lock(gFailuresMutex);
81 SkDebugf("\n\nFAILURE: %s\n\n", err.c_str()); 80 SkDebugf("\n\nFAILURE: %s\n\n", err.c_str());
82 gFailures.push_back(err); 81 gFailures.push_back(err);
83 } 82 }
84 83
85 static int32_t gPending = 0; // Atomic. Total number of running and queued tas ks.
86 84
87 // We use a spinlock to make locking this in a signal handler _somewhat_ safe. 85 // We use a spinlock to make locking this in a signal handler _somewhat_ safe.
88 SK_DECLARE_STATIC_SPINLOCK(gRunningAndTallyMutex); 86 SK_DECLARE_STATIC_SPINLOCK(gMutex);
87 static int32_t gPending;
89 static SkTArray<SkString> gRunning; 88 static SkTArray<SkString> gRunning;
90 static SkTHashMap<SkString, int> gNoteTally; 89 static SkTHashMap<SkString, int> gNoteTally;
91 90
92 static void done(double ms, 91 static void done(double ms,
93 ImplicitString config, ImplicitString src, ImplicitString srcOp tions, 92 ImplicitString config, ImplicitString src, ImplicitString srcOp tions,
94 ImplicitString name, ImplicitString note, ImplicitString log) { 93 ImplicitString name, ImplicitString note, ImplicitString log) {
95 SkString id = SkStringPrintf("%s %s %s %s", config.c_str(), src.c_str(), 94 SkString id = SkStringPrintf("%s %s %s %s", config.c_str(), src.c_str(),
96 srcOptions.c_str(), name.c_str() ); 95 srcOptions.c_str(), name.c_str() );
96 int pending;
97 { 97 {
98 SkAutoTAcquire<SkPODSpinlock> lock(gRunningAndTallyMutex); 98 SkAutoTAcquire<SkPODSpinlock> lock(gMutex);
99 for (int i = 0; i < gRunning.count(); i++) { 99 for (int i = 0; i < gRunning.count(); i++) {
100 if (gRunning[i] == id) { 100 if (gRunning[i] == id) {
101 gRunning.removeShuffle(i); 101 gRunning.removeShuffle(i);
102 break; 102 break;
103 } 103 }
104 } 104 }
105 if (!note.isEmpty()) { 105 if (!note.isEmpty()) {
106 if (int* tally = gNoteTally.find(note)) { 106 if (int* tally = gNoteTally.find(note)) {
107 *tally += 1; 107 *tally += 1;
108 } else { 108 } else {
109 gNoteTally.set(note, 1); 109 gNoteTally.set(note, 1);
110 } 110 }
111 } 111 }
112 } 112 pending = --gPending;
113 if (!log.isEmpty()) {
114 log.prepend("\n");
115 }
116 auto pending = sk_atomic_dec(&gPending)-1;
117 if (!FLAGS_quiet && note.isEmpty()) {
118 SkDebugf("%s(%4d/%-4dMB %6d) %s\t%s%s", FLAGS_verbose ? "\n" : kSkOverwr iteLine
119 , sk_tools::getCurrResidentSetSizeMB( )
120 , sk_tools::getMaxResidentSetSizeMB()
121 , pending
122 , HumanizeMs(ms).c_str()
123 , id.c_str()
124 , log.c_str());
125 } 113 }
126 // We write our dm.json file every once in a while in case we crash. 114 // We write our dm.json file every once in a while in case we crash.
127 // Notice this also handles the final dm.json when pending == 0. 115 // Notice this also handles the final dm.json when pending == 0.
128 if (pending % 500 == 0) { 116 if (pending % 500 == 0) {
129 JsonWriter::DumpJson(); 117 JsonWriter::DumpJson();
130 } 118 }
131 } 119 }
132 120
133 static void start(ImplicitString config, ImplicitString src, 121 static void start(ImplicitString config, ImplicitString src,
134 ImplicitString srcOptions, ImplicitString name) { 122 ImplicitString srcOptions, ImplicitString name) {
135 SkString id = SkStringPrintf("%s %s %s %s", config.c_str(), src.c_str(), 123 SkString id = SkStringPrintf("%s %s %s %s", config.c_str(), src.c_str(),
136 srcOptions.c_str(), name.c_str() ); 124 srcOptions.c_str(), name.c_str() );
137 SkAutoTAcquire<SkPODSpinlock> lock(gRunningAndTallyMutex); 125 SkAutoTAcquire<SkPODSpinlock> lock(gMutex);
138 gRunning.push_back(id); 126 gRunning.push_back(id);
139 } 127 }
140 128
129 static void print_status() {
130 static SkMSec start_ms = SkTime::GetMSecs();
131
132 int curr = sk_tools::getCurrResidentSetSizeMB(),
133 peak = sk_tools::getMaxResidentSetSizeMB();
134 SkString elapsed = HumanizeMs(SkTime::GetMSecs() - start_ms);
135
136 SkAutoTAcquire<SkPODSpinlock> lock(gMutex);
137 SkDebugf("\n%s elapsed, %d active, %d queued, %dMB RAM, %dMB peak\n",
138 elapsed.c_str(), gRunning.count(), gPending - gRunning.count(), cur r, peak);
139 for (auto& task : gRunning) {
140 SkDebugf("\t%s\n", task.c_str());
141 }
142 }
143
141 #if defined(SK_BUILD_FOR_WIN32) 144 #if defined(SK_BUILD_FOR_WIN32)
142 static void setup_crash_handler() { 145 static void setup_crash_handler() {
143 // TODO: custom crash handler like below to print out what was running 146 // TODO: custom crash handler like below to print out what was running
144 SetupCrashHandler(); 147 SetupCrashHandler();
145 } 148 }
146 149
147 #else 150 #else
148 #include <signal.h> 151 #include <signal.h>
149 static void setup_crash_handler() { 152 static void setup_crash_handler() {
150 const int kSignals[] = { SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV }; 153 const int kSignals[] = { SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV };
151 for (int sig : kSignals) { 154 for (int sig : kSignals) {
152 signal(sig, [](int sig) { 155 signal(sig, [](int sig) {
153 SkAutoTAcquire<SkPODSpinlock> lock(gRunningAndTallyMutex); 156 SkDebugf("\nCaught signal %d [%s].\n", sig, strsignal(sig));
154 SkDebugf("\nCaught signal %d [%s] while running %d tasks:\n", 157 print_status();
155 sig, strsignal(sig), gRunning.count());
156 for (auto& task : gRunning) {
157 SkDebugf("\t%s\n", task.c_str());
158 }
159 }); 158 });
160 } 159 }
161 } 160 }
162 #endif 161 #endif
163 162
164 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ 163 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/
165 164
166 struct Gold : public SkString { 165 struct Gold : public SkString {
167 Gold() : SkString("") {} 166 Gold() : SkString("") {}
168 Gold(ImplicitString sink, ImplicitString src, ImplicitString srcOptions, 167 Gold(ImplicitString sink, ImplicitString src, ImplicitString srcOptions,
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 task.src.options.c_str(), name. c_str()); 893 task.src.options.c_str(), name. c_str());
895 if (!whyBlacklisted.isEmpty()) { 894 if (!whyBlacklisted.isEmpty()) {
896 note.appendf(" (--blacklist %s)", whyBlacklisted.c_str()); 895 note.appendf(" (--blacklist %s)", whyBlacklisted.c_str());
897 } 896 }
898 897
899 SkString log; 898 SkString log;
900 auto timerStart = now_ms(); 899 auto timerStart = now_ms();
901 if (!FLAGS_dryRun && note.isEmpty()) { 900 if (!FLAGS_dryRun && note.isEmpty()) {
902 SkBitmap bitmap; 901 SkBitmap bitmap;
903 SkDynamicMemoryWStream stream; 902 SkDynamicMemoryWStream stream;
904 if (FLAGS_pre_log) {
905 SkDebugf("\nRunning %s->%s", name.c_str(), task.sink.tag.c_str() );
906 }
907 start(task.sink.tag.c_str(), task.src.tag, task.src.options, name.c_ str()); 903 start(task.sink.tag.c_str(), task.src.tag, task.src.options, name.c_ str());
908 Error err = task.sink->draw(*task.src, &bitmap, &stream, &log); 904 Error err = task.sink->draw(*task.src, &bitmap, &stream, &log);
909 if (!err.isEmpty()) { 905 if (!err.isEmpty()) {
910 if (err.isFatal()) { 906 if (err.isFatal()) {
911 fail(SkStringPrintf("%s %s %s %s: %s", 907 fail(SkStringPrintf("%s %s %s %s: %s",
912 task.sink.tag.c_str(), 908 task.sink.tag.c_str(),
913 task.src.tag.c_str(), 909 task.src.tag.c_str(),
914 task.src.options.c_str(), 910 task.src.options.c_str(),
915 name.c_str(), 911 name.c_str(),
916 err.c_str())); 912 err.c_str()));
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 SkString note; 1091 SkString note;
1096 SkString whyBlacklisted = is_blacklisted("_", "tests", "_", test.name); 1092 SkString whyBlacklisted = is_blacklisted("_", "tests", "_", test.name);
1097 if (!whyBlacklisted.isEmpty()) { 1093 if (!whyBlacklisted.isEmpty()) {
1098 note.appendf(" (--blacklist %s)", whyBlacklisted.c_str()); 1094 note.appendf(" (--blacklist %s)", whyBlacklisted.c_str());
1099 } 1095 }
1100 1096
1101 auto timerStart = now_ms(); 1097 auto timerStart = now_ms();
1102 if (!FLAGS_dryRun && whyBlacklisted.isEmpty()) { 1098 if (!FLAGS_dryRun && whyBlacklisted.isEmpty()) {
1103 start("unit", "test", "", test.name); 1099 start("unit", "test", "", test.name);
1104 GrContextFactory factory; 1100 GrContextFactory factory;
1105 if (FLAGS_pre_log) {
1106 SkDebugf("\nRunning test %s", test.name);
1107 }
1108 test.proc(&reporter, &factory); 1101 test.proc(&reporter, &factory);
1109 } 1102 }
1110 done(now_ms()-timerStart, "unit", "test", "", test.name, note, ""); 1103 done(now_ms()-timerStart, "unit", "test", "", test.name, note, "");
1111 } 1104 }
1112 1105
1113 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ 1106 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/
1114 1107
1115 // Some runs (mostly, Valgrind) are so slow that the bot framework thinks we've hung. 1108 DEFINE_int32(status_sec, 15, "Print status this often (and if we crash).");
1116 // This prints something every once in a while so that it knows we're still work ing. 1109
1117 static void start_keepalive() { 1110 SkThread* start_status_thread() {
1118 struct Loop { 1111 auto thread = new SkThread([] (void*) {
1119 static void forever(void*) { 1112 for (;;) {
1120 for (;;) { 1113 print_status();
1121 static const int kSec = 300; 1114 #if defined(SK_BUILD_FOR_WIN)
1122 #if defined(SK_BUILD_FOR_WIN) 1115 Sleep(FLAGS_status_sec * 1000);
1123 Sleep(kSec * 1000); 1116 #else
1124 #else 1117 sleep(FLAGS_status_sec);
1125 sleep(kSec); 1118 #endif
1126 #endif
1127 SkString running;
1128 {
1129 SkAutoTAcquire<SkPODSpinlock> lock(gRunningAndTallyMutex);
1130 for (int i = 0; i < gRunning.count(); i++) {
1131 running.appendf("\n\t%s", gRunning[i].c_str());
1132 }
1133 }
1134 SkDebugf("\nCurrently running:%s\n", running.c_str());
1135 }
1136 } 1119 }
1137 }; 1120 });
1138 static SkThread* intentionallyLeaked = new SkThread(Loop::forever); 1121 thread->start();
1139 intentionallyLeaked->start(); 1122 return thread;
1140 } 1123 }
1141 1124
1142 #define PORTABLE_FONT_PREFIX "Toy Liberation " 1125 #define PORTABLE_FONT_PREFIX "Toy Liberation "
1143 1126
1144 static SkTypeface* create_from_name(const char familyName[], SkTypeface::Style s tyle) { 1127 static SkTypeface* create_from_name(const char familyName[], SkTypeface::Style s tyle) {
1145 if (familyName && strlen(familyName) > sizeof(PORTABLE_FONT_PREFIX) 1128 if (familyName && strlen(familyName) > sizeof(PORTABLE_FONT_PREFIX)
1146 && !strncmp(familyName, PORTABLE_FONT_PREFIX, sizeof(PORTABLE_FONT_P REFIX) - 1)) { 1129 && !strncmp(familyName, PORTABLE_FONT_PREFIX, sizeof(PORTABLE_FONT_P REFIX) - 1)) {
1147 return sk_tool_utils::create_portable_typeface(familyName, style); 1130 return sk_tool_utils::create_portable_typeface(familyName, style);
1148 } 1131 }
1149 return nullptr; 1132 return nullptr;
1150 } 1133 }
1151 1134
1152 #undef PORTABLE_FONT_PREFIX 1135 #undef PORTABLE_FONT_PREFIX
1153 1136
1154 extern SkTypeface* (*gCreateTypefaceDelegate)(const char [], SkTypeface::Style ) ; 1137 extern SkTypeface* (*gCreateTypefaceDelegate)(const char [], SkTypeface::Style ) ;
1155 1138
1156 int dm_main(); 1139 int dm_main();
1157 int dm_main() { 1140 int dm_main() {
1158 setup_crash_handler(); 1141 setup_crash_handler();
1142
1159 JsonWriter::DumpJson(); // It's handy for the bots to assume this is ~never missing. 1143 JsonWriter::DumpJson(); // It's handy for the bots to assume this is ~never missing.
1160 SkAutoGraphics ag; 1144 SkAutoGraphics ag;
1161 SkTaskGroup::Enabler enabled(FLAGS_threads); 1145 SkTaskGroup::Enabler enabled(FLAGS_threads);
1162 gCreateTypefaceDelegate = &create_from_name; 1146 gCreateTypefaceDelegate = &create_from_name;
1163 1147
1164 start_keepalive();
1165
1166 gather_gold(); 1148 gather_gold();
1167 gather_uninteresting_hashes(); 1149 gather_uninteresting_hashes();
1168 1150
1169 if (!gather_srcs()) { 1151 if (!gather_srcs()) {
1170 return 1; 1152 return 1;
1171 } 1153 }
1172 gather_sinks(); 1154 gather_sinks();
1173 gather_tests(); 1155 gather_tests();
1174 1156
1175 gPending = gSrcs.count() * gSinks.count() + gParallelTests.count() + gSerial Tests.count(); 1157 gPending = gSrcs.count() * gSinks.count() + gParallelTests.count() + gSerial Tests.count();
1176 SkDebugf("%d srcs * %d sinks + %d tests == %d tasks\n", 1158 SkDebugf("%d srcs * %d sinks + %d tests == %d tasks",
1177 gSrcs.count(), gSinks.count(), gParallelTests.count() + gSerialTest s.count(), gPending); 1159 gSrcs.count(), gSinks.count(), gParallelTests.count() + gSerialTest s.count(), gPending);
1160 SkAutoTDelete<SkThread> statusThread(start_status_thread());
1178 1161
1179 // Kick off as much parallel work as we can, making note of any serial work we'll need to do. 1162 // Kick off as much parallel work as we can, making note of any serial work we'll need to do.
1180 SkTaskGroup parallel; 1163 SkTaskGroup parallel;
1181 SkTArray<Task> serial; 1164 SkTArray<Task> serial;
1182 1165
1183 for (auto& sink : gSinks) 1166 for (auto& sink : gSinks)
1184 for (auto& src : gSrcs) { 1167 for (auto& src : gSrcs) {
1185 Task task(src, sink); 1168 Task task(src, sink);
1186 if (src->serial() || sink->serial()) { 1169 if (src->serial() || sink->serial()) {
1187 serial.push_back(task); 1170 serial.push_back(task);
(...skipping 25 matching lines...) Expand all
1213 1196
1214 SkDebugf("\n"); 1197 SkDebugf("\n");
1215 if (gFailures.count() > 0) { 1198 if (gFailures.count() > 0) {
1216 SkDebugf("Failures:\n"); 1199 SkDebugf("Failures:\n");
1217 for (int i = 0; i < gFailures.count(); i++) { 1200 for (int i = 0; i < gFailures.count(); i++) {
1218 SkDebugf("\t%s\n", gFailures[i].c_str()); 1201 SkDebugf("\t%s\n", gFailures[i].c_str());
1219 } 1202 }
1220 SkDebugf("%d failures\n", gFailures.count()); 1203 SkDebugf("%d failures\n", gFailures.count());
1221 return 1; 1204 return 1;
1222 } 1205 }
1223 if (gPending > 0) { 1206
1224 SkDebugf("Hrm, we didn't seem to run everything we intended to! Please file a bug.\n"); 1207 #ifdef SK_PDF_IMAGE_STATS
1225 return 1;
1226 }
1227 #ifdef SK_PDF_IMAGE_STATS
1228 SkPDFImageDumpStats(); 1208 SkPDFImageDumpStats();
1229 #endif // SK_PDF_IMAGE_STATS 1209 #endif // SK_PDF_IMAGE_STATS
1210
1211 print_status();
1230 SkDebugf("Finished!\n"); 1212 SkDebugf("Finished!\n");
1231 return 0; 1213 return 0;
1232 } 1214 }
1233 1215
1234 // TODO: currently many GPU tests are declared outside SK_SUPPORT_GPU guards. 1216 // TODO: currently many GPU tests are declared outside SK_SUPPORT_GPU guards.
1235 // Thus we export the empty RunWithGPUTestContexts when SK_SUPPORT_GPU=0. 1217 // Thus we export the empty RunWithGPUTestContexts when SK_SUPPORT_GPU=0.
1236 namespace skiatest { 1218 namespace skiatest {
1237 namespace { 1219 namespace {
1238 typedef void(*TestWithGrContext)(skiatest::Reporter*, GrContext*); 1220 typedef void(*TestWithGrContext)(skiatest::Reporter*, GrContext*);
1239 typedef void(*TestWithGrContextAndGLContext)(skiatest::Reporter*, GrContext*, Sk GLContext*); 1221 typedef void(*TestWithGrContextAndGLContext)(skiatest::Reporter*, GrContext*, Sk GLContext*);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1318 Reporter* reporter, 1300 Reporter* reporter,
1319 GrContextFactory* fac tory); 1301 GrContextFactory* fac tory);
1320 } // namespace skiatest 1302 } // namespace skiatest
1321 1303
1322 #if !defined(SK_BUILD_FOR_IOS) 1304 #if !defined(SK_BUILD_FOR_IOS)
1323 int main(int argc, char** argv) { 1305 int main(int argc, char** argv) {
1324 SkCommandLineFlags::Parse(argc, argv); 1306 SkCommandLineFlags::Parse(argc, argv);
1325 return dm_main(); 1307 return dm_main();
1326 } 1308 }
1327 #endif 1309 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698