| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 library MandelIsolateTest; | |
| 6 import 'dart:async'; | |
| 7 import 'dart:isolate'; | |
| 8 import 'dart:math'; | |
| 9 import '../../pkg/unittest/lib/unittest.dart'; | |
| 10 | |
| 11 const TERMINATION_MESSAGE = -1; | |
| 12 const N = 100; | |
| 13 const ISOLATES = 20; | |
| 14 | |
| 15 main() { | |
| 16 // Test is really slow in debug builds of the VM. | |
| 17 unittestConfiguration.timeout = const Duration(seconds: 480); | |
| 18 test("Render Mandelbrot in parallel", () { | |
| 19 final state = new MandelbrotState(); | |
| 20 state._validated.future.then(expectAsync1((result) { | |
| 21 expect(result, isTrue); | |
| 22 })); | |
| 23 for (int i = 0; i < min(ISOLATES, N); i++) state.startClient(i); | |
| 24 }); | |
| 25 } | |
| 26 | |
| 27 | |
| 28 class MandelbrotState { | |
| 29 | |
| 30 MandelbrotState() { | |
| 31 _result = new List<List<int>>(N); | |
| 32 _lineProcessedBy = new List<LineProcessorClient>(N); | |
| 33 _sent = 0; | |
| 34 _missing = N; | |
| 35 _validated = new Completer<bool>(); | |
| 36 } | |
| 37 | |
| 38 void startClient(int id) { | |
| 39 assert(_sent < N); | |
| 40 final client = new LineProcessorClient(this, id); | |
| 41 client.processLine(_sent++); | |
| 42 } | |
| 43 | |
| 44 void notifyProcessedLine(LineProcessorClient client, int y, List<int> line) { | |
| 45 assert(_result[y] == null); | |
| 46 _result[y] = line; | |
| 47 _lineProcessedBy[y] = client; | |
| 48 | |
| 49 if (_sent != N) { | |
| 50 client.processLine(_sent++); | |
| 51 } else { | |
| 52 client.shutdown(); | |
| 53 } | |
| 54 | |
| 55 // If all lines have been computed, validate the result. | |
| 56 if (--_missing == 0) { | |
| 57 _printResult(); | |
| 58 _validateResult(); | |
| 59 } | |
| 60 } | |
| 61 | |
| 62 void _validateResult() { | |
| 63 // TODO(ngeoffray): Implement this. | |
| 64 _validated.complete(true); | |
| 65 } | |
| 66 | |
| 67 void _printResult() { | |
| 68 var output = new StringBuffer(); | |
| 69 for (int i = 0; i < _result.length; i++) { | |
| 70 List<int> line = _result[i]; | |
| 71 for (int j = 0; j < line.length; j++) { | |
| 72 if (line[j] < 10) output.write("0"); | |
| 73 output.write(line[j]); | |
| 74 } | |
| 75 output.write("\n"); | |
| 76 } | |
| 77 // print(output); | |
| 78 } | |
| 79 | |
| 80 List<List<int>> _result; | |
| 81 List<LineProcessorClient> _lineProcessedBy; | |
| 82 int _sent; | |
| 83 int _missing; | |
| 84 Completer<bool> _validated; | |
| 85 } | |
| 86 | |
| 87 | |
| 88 class LineProcessorClient { | |
| 89 | |
| 90 LineProcessorClient(MandelbrotState this._state, int this._id) { | |
| 91 _sink = streamSpawnFunction(processLines); | |
| 92 _box = new MessageBox(); | |
| 93 _sink.add(_box.sink); | |
| 94 _box.stream.listen((List<int> message) { | |
| 95 _state.notifyProcessedLine(this, _currentLine, message); | |
| 96 }); | |
| 97 } | |
| 98 | |
| 99 void processLine(int y) { | |
| 100 _currentLine = y; | |
| 101 _sink.add(y); | |
| 102 } | |
| 103 | |
| 104 void shutdown() { | |
| 105 _sink.close(); | |
| 106 _box.stream.close(); | |
| 107 } | |
| 108 | |
| 109 MandelbrotState _state; | |
| 110 int _id; | |
| 111 IsolateSink _sink; | |
| 112 int _currentLine; | |
| 113 MessageBox _box; | |
| 114 } | |
| 115 | |
| 116 List<int> processLine(int y) { | |
| 117 double inverseN = 2.0 / N; | |
| 118 double Civ = y * inverseN - 1.0; | |
| 119 List<int> result = new List<int>(N); | |
| 120 for (int x = 0; x < N; x++) { | |
| 121 double Crv = x * inverseN - 1.5; | |
| 122 | |
| 123 double Zrv = Crv; | |
| 124 double Ziv = Civ; | |
| 125 | |
| 126 double Trv = Crv * Crv; | |
| 127 double Tiv = Civ * Civ; | |
| 128 | |
| 129 int i = 49; | |
| 130 do { | |
| 131 Ziv = (Zrv * Ziv) + (Zrv * Ziv) + Civ; | |
| 132 Zrv = Trv - Tiv + Crv; | |
| 133 | |
| 134 Trv = Zrv * Zrv; | |
| 135 Tiv = Ziv * Ziv; | |
| 136 } while (((Trv + Tiv) <= 4.0) && (--i > 0)); | |
| 137 | |
| 138 result[x] = i; | |
| 139 } | |
| 140 return result; | |
| 141 } | |
| 142 | |
| 143 void processLines() { | |
| 144 bool isFirst = true; | |
| 145 IsolateSink replyTo; | |
| 146 | |
| 147 stream.listen((message) { | |
| 148 if (isFirst) { | |
| 149 isFirst = false; | |
| 150 replyTo = message; | |
| 151 return; | |
| 152 } | |
| 153 replyTo.add(processLine(message)); | |
| 154 }); | |
| 155 } | |
| OLD | NEW |