Dart: Faster 'gen' command for mojom.dart tool
On my machine:
$ ./mojo/dart/tools/bindings/generate.py -f
Goes from ~45-50s to ~5-6s.
R=johnmccutchan@google.com
Review URL: https://codereview.chromium.org/1970573003 .
diff --git a/mojo/dart/packages/mojom/lib/src/generate.dart b/mojo/dart/packages/mojom/lib/src/generate.dart
index 46fc014..331963a 100644
--- a/mojo/dart/packages/mojom/lib/src/generate.dart
+++ b/mojo/dart/packages/mojom/lib/src/generate.dart
@@ -20,6 +20,55 @@
const String mojoTestPackage = '_mojo_for_test_only';
+// A class for running as many generation tasks in parallel as there are cores
+// on the machine. Supposing `tasks` is a list of functions of type
+// `Future f()`, used as:
+// var runner = new _GenerationTaskRunner(tasks);
+// await runner.run();
+// No result is returned.
+class _GenerationTaskRunner {
+ List<Function> _tasks;
+ List<Future> _futures;
+ Completer _completer;
+ int _numCpus;
+ int _nextTaskIndex;
+ int _futuresOutstanding;
+
+ _GenerationTaskRunner(this._tasks) {
+ _numCpus = Platform.numberOfProcessors;
+ _futures = new List<Future>();
+ _completer = new Completer();
+ _nextTaskIndex = 0;
+ _futuresOutstanding = 0;
+ }
+
+ Future run() {
+ while ((_nextTaskIndex < _numCpus) && (_nextTaskIndex < _tasks.length)) {
+ int idx = _nextTaskIndex;
+ _futures.add(_tasks[_nextTaskIndex]().then((_) {
+ _addNewTask(idx);
+ }));
+ _nextTaskIndex++;
+ _futuresOutstanding++;
+ }
+ return _completer.future;
+ }
+
+ void _addNewTask(int idx) {
+ if (_nextTaskIndex < _tasks.length) {
+ _futures[idx] = _tasks[_nextTaskIndex]().then((_) {
+ _addNewTask(idx);
+ });
+ _nextTaskIndex++;
+ } else {
+ _futuresOutstanding--;
+ if (_futuresOutstanding == 0) {
+ _completer.complete(null);
+ }
+ }
+ }
+}
+
class MojomGenerator {
static dev.Counter _genMs;
final bool _errorOnDuplicate;
@@ -71,10 +120,14 @@
// newer than the oldest .mojom.dart file, then regenerate.
if (_force || (mojomDartCount < mojomCount) ||
_shouldRegenerate(newestMojomTime, oldestMojomDartTime)) {
+ var tasks = new List();
for (File mojom in info.mojomFiles) {
- await _generateForMojom(
- mojom, info.importDir, info.packageDir, info.name);
+ tasks.add(() => _generateForMojom(
+ mojom, info.importDir, info.packageDir, info.name));
}
+ var runner = new _GenerationTaskRunner(tasks);
+ await runner.run();
+
// Delete any .mojom.dart files that are still older than mojomTime.
await _deleteOldMojomDart(info.packageDir, newestMojomTime);
}