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

Side by Side Diff: test/mjsunit/harmony/futex.js

Issue 2143443002: [Atomics] Rename Atomics.futex*, remove Atomics.futexWakeOrRequeue (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: merge master Created 4 years, 5 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 | « test/cctest/test-api.cc ('k') | 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 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Flags: --allow-natives-syntax --harmony-sharedarraybuffer 5 // Flags: --allow-natives-syntax --harmony-sharedarraybuffer
6 6
7 (function TestFailsWithNonSharedArray() { 7 (function TestFailsWithNonSharedArray() {
8 var ab = new ArrayBuffer(16); 8 var ab = new ArrayBuffer(16);
9 9
10 var i8a = new Int8Array(ab); 10 var i8a = new Int8Array(ab);
11 var i16a = new Int16Array(ab); 11 var i16a = new Int16Array(ab);
12 var i32a = new Int32Array(ab); 12 var i32a = new Int32Array(ab);
13 var ui8a = new Uint8Array(ab); 13 var ui8a = new Uint8Array(ab);
14 var ui8ca = new Uint8ClampedArray(ab); 14 var ui8ca = new Uint8ClampedArray(ab);
15 var ui16a = new Uint16Array(ab); 15 var ui16a = new Uint16Array(ab);
16 var ui32a = new Uint32Array(ab); 16 var ui32a = new Uint32Array(ab);
17 var f32a = new Float32Array(ab); 17 var f32a = new Float32Array(ab);
18 var f64a = new Float64Array(ab); 18 var f64a = new Float64Array(ab);
19 19
20 [i8a, i16a, i32a, ui8a, ui8ca, ui16a, ui32a, f32a, f64a].forEach(function( 20 [i8a, i16a, i32a, ui8a, ui8ca, ui16a, ui32a, f32a, f64a].forEach(function(
21 ta) { 21 ta) {
22 assertThrows(function() { Atomics.futexWait(ta, 0, 0); }); 22 assertThrows(function() { Atomics.wait(ta, 0, 0); });
23 assertThrows(function() { Atomics.futexWake(ta, 0, 1); }); 23 assertThrows(function() { Atomics.wake(ta, 0, 1); });
24 assertThrows(function() { Atomics.futexWakeOrRequeue(ta, 0, 1, 0, 0); });
25 }); 24 });
26 })(); 25 })();
27 26
28 (function TestFailsWithNonSharedInt32Array() { 27 (function TestFailsWithNonSharedInt32Array() {
29 var sab = new SharedArrayBuffer(16); 28 var sab = new SharedArrayBuffer(16);
30 29
31 var i8a = new Int8Array(sab); 30 var i8a = new Int8Array(sab);
32 var i16a = new Int16Array(sab); 31 var i16a = new Int16Array(sab);
33 var ui8a = new Uint8Array(sab); 32 var ui8a = new Uint8Array(sab);
34 var ui8ca = new Uint8ClampedArray(sab); 33 var ui8ca = new Uint8ClampedArray(sab);
35 var ui16a = new Uint16Array(sab); 34 var ui16a = new Uint16Array(sab);
36 var ui32a = new Uint32Array(sab); 35 var ui32a = new Uint32Array(sab);
37 var f32a = new Float32Array(sab); 36 var f32a = new Float32Array(sab);
38 var f64a = new Float64Array(sab); 37 var f64a = new Float64Array(sab);
39 38
40 [i8a, i16a, ui8a, ui8ca, ui16a, ui32a, f32a, f64a].forEach(function( 39 [i8a, i16a, ui8a, ui8ca, ui16a, ui32a, f32a, f64a].forEach(function(
41 ta) { 40 ta) {
42 assertThrows(function() { Atomics.futexWait(ta, 0, 0); }); 41 assertThrows(function() { Atomics.wait(ta, 0, 0); });
43 assertThrows(function() { Atomics.futexWake(ta, 0, 1); }); 42 assertThrows(function() { Atomics.wake(ta, 0, 1); });
44 assertThrows(function() { Atomics.futexWakeOrRequeue(ta, 0, 1, 0, 0); });
45 }); 43 });
46 })(); 44 })();
47 45
48 (function TestInvalidIndex() { 46 (function TestInvalidIndex() {
49 var sab = new SharedArrayBuffer(16); 47 var sab = new SharedArrayBuffer(16);
50 var i32a = new Int32Array(sab); 48 var i32a = new Int32Array(sab);
51 49
52 // Valid indexes are 0-3. 50 // Valid indexes are 0-3.
53 [-1, 4, 100].forEach(function(invalidIndex) { 51 [-1, 4, 100].forEach(function(invalidIndex) {
54 assertThrows(function() { 52 assertThrows(function() {
55 Atomics.futexWait(i32a, invalidIndex, 0); 53 Atomics.wait(i32a, invalidIndex, 0);
56 }, RangeError); 54 }, RangeError);
57 assertThrows(function() { 55 assertThrows(function() {
58 Atomics.futexWake(i32a, invalidIndex, 0); 56 Atomics.wake(i32a, invalidIndex, 0);
59 }, RangeError); 57 }, RangeError);
60 var validIndex = 0; 58 var validIndex = 0;
61 assertThrows(function() {
62 Atomics.futexWakeOrRequeue(i32a, invalidIndex, 0, 0, validIndex);
63 }, RangeError);
64 assertThrows(function() {
65 Atomics.futexWakeOrRequeue(i32a, validIndex, 0, 0, invalidIndex);
66 }, RangeError);
67 }); 59 });
68 60
69 i32a = new Int32Array(sab, 8); 61 i32a = new Int32Array(sab, 8);
70 [-1, 2, 100].forEach(function(invalidIndex) { 62 [-1, 2, 100].forEach(function(invalidIndex) {
71 assertThrows(function() { 63 assertThrows(function() {
72 Atomics.futexWait(i32a, invalidIndex, 0); 64 Atomics.wait(i32a, invalidIndex, 0);
73 }, RangeError); 65 }, RangeError);
74 assertThrows(function() { 66 assertThrows(function() {
75 Atomics.futexWake(i32a, invalidIndex, 0); 67 Atomics.wake(i32a, invalidIndex, 0);
76 }, RangeError); 68 }, RangeError);
77 var validIndex = 0; 69 var validIndex = 0;
78 assertThrows(function() {
79 Atomics.futexWakeOrRequeue(i32a, invalidIndex, 0, 0, validIndex);
80 }, RangeError);
81 assertThrows(function() {
82 Atomics.futexWakeOrRequeue(i32a, validIndex, 0, 0, invalidIndex);
83 }, RangeError);
84 }); 70 });
85 })(); 71 })();
86 72
87 (function TestWaitTimeout() { 73 (function TestWaitTimeout() {
88 var i32a = new Int32Array(new SharedArrayBuffer(16)); 74 var i32a = new Int32Array(new SharedArrayBuffer(16));
89 var waitMs = 100; 75 var waitMs = 100;
90 var startTime = new Date(); 76 var startTime = new Date();
91 assertEquals(Atomics.TIMEDOUT, Atomics.futexWait(i32a, 0, 0, waitMs)); 77 assertEquals("timed-out", Atomics.wait(i32a, 0, 0, waitMs));
92 var endTime = new Date(); 78 var endTime = new Date();
93 assertTrue(endTime - startTime >= waitMs); 79 assertTrue(endTime - startTime >= waitMs);
94 })(); 80 })();
95 81
96 (function TestWaitNotEqual() { 82 (function TestWaitNotEqual() {
97 var sab = new SharedArrayBuffer(16); 83 var sab = new SharedArrayBuffer(16);
98 var i32a = new Int32Array(sab); 84 var i32a = new Int32Array(sab);
99 assertEquals(Atomics.NOTEQUAL, Atomics.futexWait(i32a, 0, 42)); 85 assertEquals("not-equal", Atomics.wait(i32a, 0, 42));
100 86
101 i32a = new Int32Array(sab, 8); 87 i32a = new Int32Array(sab, 8);
102 i32a[0] = 1; 88 i32a[0] = 1;
103 assertEquals(Atomics.NOTEQUAL, Atomics.futexWait(i32a, 0, 0)); 89 assertEquals("not-equal", Atomics.wait(i32a, 0, 0));
104 })(); 90 })();
105 91
106 (function TestWaitNegativeTimeout() { 92 (function TestWaitNegativeTimeout() {
107 var i32a = new Int32Array(new SharedArrayBuffer(16)); 93 var i32a = new Int32Array(new SharedArrayBuffer(16));
108 assertEquals(Atomics.TIMEDOUT, Atomics.futexWait(i32a, 0, 0, -1)); 94 assertEquals("timed-out", Atomics.wait(i32a, 0, 0, -1));
109 assertEquals(Atomics.TIMEDOUT, Atomics.futexWait(i32a, 0, 0, -Infinity)); 95 assertEquals("timed-out", Atomics.wait(i32a, 0, 0, -Infinity));
110 })(); 96 })();
111 97
112 //// WORKER ONLY TESTS 98 //// WORKER ONLY TESTS
113 99
114 if (this.Worker) { 100 if (this.Worker) {
115 101
116 var TestWaitWithTimeout = function(timeout) { 102 var TestWaitWithTimeout = function(timeout) {
117 var sab = new SharedArrayBuffer(16); 103 var sab = new SharedArrayBuffer(16);
118 var i32a = new Int32Array(sab); 104 var i32a = new Int32Array(sab);
119 105
120 var workerScript = 106 var workerScript =
121 `onmessage = function(msg) { 107 `onmessage = function(msg) {
122 var i32a = new Int32Array(msg.sab, msg.offset); 108 var i32a = new Int32Array(msg.sab, msg.offset);
123 var result = Atomics.futexWait(i32a, 0, 0, ${timeout}); 109 var result = Atomics.wait(i32a, 0, 0, ${timeout});
124 postMessage(result); 110 postMessage(result);
125 };`; 111 };`;
126 112
127 var worker = new Worker(workerScript); 113 var worker = new Worker(workerScript);
128 worker.postMessage({sab: sab, offset: offset}, [sab]); 114 worker.postMessage({sab: sab, offset: offset}, [sab]);
129 115
130 // Spin until the worker is waiting on the futex. 116 // Spin until the worker is waiting on the futex.
131 while (%AtomicsFutexNumWaitersForTesting(i32a, 0) != 1) {} 117 while (%AtomicsNumWaitersForTesting(i32a, 0) != 1) {}
132 118
133 Atomics.futexWake(i32a, 0, 1); 119 Atomics.wake(i32a, 0, 1);
134 assertEquals(Atomics.OK, worker.getMessage()); 120 assertEquals("ok", worker.getMessage());
135 worker.terminate(); 121 worker.terminate();
136 122
137 var worker2 = new Worker(workerScript); 123 var worker2 = new Worker(workerScript);
138 var offset = 8; 124 var offset = 8;
139 var i32a2 = new Int32Array(sab, offset); 125 var i32a2 = new Int32Array(sab, offset);
140 worker2.postMessage({sab: sab, offset: offset}, [sab]); 126 worker2.postMessage({sab: sab, offset: offset}, [sab]);
141 127
142 // Spin until the worker is waiting on the futex. 128 // Spin until the worker is waiting on the futex.
143 while (%AtomicsFutexNumWaitersForTesting(i32a2, 0) != 1) {} 129 while (%AtomicsNumWaitersForTesting(i32a2, 0) != 1) {}
144 Atomics.futexWake(i32a2, 0, 1); 130 Atomics.wake(i32a2, 0, 1);
145 assertEquals(Atomics.OK, worker2.getMessage()); 131 assertEquals("ok", worker2.getMessage());
146 worker2.terminate(); 132 worker2.terminate();
147 133
148 // Futex should work when index and buffer views are different, but 134 // Futex should work when index and buffer views are different, but
149 // the real address is the same. 135 // the real address is the same.
150 var worker3 = new Worker(workerScript); 136 var worker3 = new Worker(workerScript);
151 i32a2 = new Int32Array(sab, 4); 137 i32a2 = new Int32Array(sab, 4);
152 worker3.postMessage({sab: sab, offset: 8}, [sab]); 138 worker3.postMessage({sab: sab, offset: 8}, [sab]);
153 139
154 // Spin until the worker is waiting on the futex. 140 // Spin until the worker is waiting on the futex.
155 while (%AtomicsFutexNumWaitersForTesting(i32a2, 1) != 1) {} 141 while (%AtomicsNumWaitersForTesting(i32a2, 1) != 1) {}
156 Atomics.futexWake(i32a2, 1, 1); 142 Atomics.wake(i32a2, 1, 1);
157 assertEquals(Atomics.OK, worker3.getMessage()); 143 assertEquals("ok", worker3.getMessage());
158 worker3.terminate(); 144 worker3.terminate();
159 }; 145 };
160 146
161 // Test various infinite timeouts 147 // Test various infinite timeouts
162 TestWaitWithTimeout(undefined); 148 TestWaitWithTimeout(undefined);
163 TestWaitWithTimeout(NaN); 149 TestWaitWithTimeout(NaN);
164 TestWaitWithTimeout(Infinity); 150 TestWaitWithTimeout(Infinity);
165 151
166 152
167 (function TestWakeMulti() { 153 (function TestWakeMulti() {
168 var sab = new SharedArrayBuffer(20); 154 var sab = new SharedArrayBuffer(20);
169 var i32a = new Int32Array(sab); 155 var i32a = new Int32Array(sab);
170 156
171 // SAB values: 157 // SAB values:
172 // i32a[id], where id in range [0, 3]: 158 // i32a[id], where id in range [0, 3]:
173 // 0 => Worker |id| is still waiting on the futex 159 // 0 => Worker |id| is still waiting on the futex
174 // 1 => Worker |id| is not waiting on futex, but has not be reaped by the 160 // 1 => Worker |id| is not waiting on futex, but has not be reaped by the
175 // main thread. 161 // main thread.
176 // 2 => Worker |id| has been reaped. 162 // 2 => Worker |id| has been reaped.
177 // 163 //
178 // i32a[4]: 164 // i32a[4]:
179 // always 0. Each worker is waiting on this index. 165 // always 0. Each worker is waiting on this index.
180 166
181 var workerScript = 167 var workerScript =
182 `onmessage = function(msg) { 168 `onmessage = function(msg) {
183 var id = msg.id; 169 var id = msg.id;
184 var i32a = new Int32Array(msg.sab); 170 var i32a = new Int32Array(msg.sab);
185 171
186 // Wait on i32a[4] (should be zero). 172 // Wait on i32a[4] (should be zero).
187 var result = Atomics.futexWait(i32a, 4, 0); 173 var result = Atomics.wait(i32a, 4, 0);
188 // Set i32a[id] to 1 to notify the main thread which workers were 174 // Set i32a[id] to 1 to notify the main thread which workers were
189 // woken up. 175 // woken up.
190 Atomics.store(i32a, id, 1); 176 Atomics.store(i32a, id, 1);
191 postMessage(result); 177 postMessage(result);
192 };`; 178 };`;
193 179
194 var id; 180 var id;
195 var workers = []; 181 var workers = [];
196 for (id = 0; id < 4; id++) { 182 for (id = 0; id < 4; id++) {
197 workers[id] = new Worker(workerScript); 183 workers[id] = new Worker(workerScript);
198 workers[id].postMessage({sab: sab, id: id}, [sab]); 184 workers[id].postMessage({sab: sab, id: id}, [sab]);
199 } 185 }
200 186
201 // Spin until all workers are waiting on the futex. 187 // Spin until all workers are waiting on the futex.
202 while (%AtomicsFutexNumWaitersForTesting(i32a, 4) != 4) {} 188 while (%AtomicsNumWaitersForTesting(i32a, 4) != 4) {}
203 189
204 // Wake up three waiters. 190 // Wake up three waiters.
205 assertEquals(3, Atomics.futexWake(i32a, 4, 3)); 191 assertEquals(3, Atomics.wake(i32a, 4, 3));
206 192
207 var wokenCount = 0; 193 var wokenCount = 0;
208 var waitingId = 0 + 1 + 2 + 3; 194 var waitingId = 0 + 1 + 2 + 3;
209 while (wokenCount < 3) { 195 while (wokenCount < 3) {
210 for (id = 0; id < 4; id++) { 196 for (id = 0; id < 4; id++) {
211 // Look for workers that have not yet been reaped. Set i32a[id] to 2 197 // Look for workers that have not yet been reaped. Set i32a[id] to 2
212 // when they've been processed so we don't look at them again. 198 // when they've been processed so we don't look at them again.
213 if (Atomics.compareExchange(i32a, id, 1, 2) == 1) { 199 if (Atomics.compareExchange(i32a, id, 1, 2) == 1) {
214 assertEquals(Atomics.OK, workers[id].getMessage()); 200 assertEquals("ok", workers[id].getMessage());
215 workers[id].terminate(); 201 workers[id].terminate();
216 waitingId -= id; 202 waitingId -= id;
217 wokenCount++; 203 wokenCount++;
218 } 204 }
219 } 205 }
220 } 206 }
221 207
222 assertEquals(3, wokenCount); 208 assertEquals(3, wokenCount);
223 assertEquals(0, Atomics.load(i32a, waitingId)); 209 assertEquals(0, Atomics.load(i32a, waitingId));
224 assertEquals(1, %AtomicsFutexNumWaitersForTesting(i32a, 4)); 210 assertEquals(1, %AtomicsNumWaitersForTesting(i32a, 4));
225 211
226 // Finally wake the last waiter. 212 // Finally wake the last waiter.
227 assertEquals(1, Atomics.futexWake(i32a, 4, 1)); 213 assertEquals(1, Atomics.wake(i32a, 4, 1));
228 assertEquals(Atomics.OK, workers[waitingId].getMessage()); 214 assertEquals("ok", workers[waitingId].getMessage());
229 workers[waitingId].terminate(); 215 workers[waitingId].terminate();
230 216
231 assertEquals(0, %AtomicsFutexNumWaitersForTesting(i32a, 4)); 217 assertEquals(0, %AtomicsNumWaitersForTesting(i32a, 4));
232 218
233 })(); 219 })();
234 220
235 (function TestWakeOrRequeue() {
236 var sab = new SharedArrayBuffer(24);
237 var i32a = new Int32Array(sab);
238
239 // SAB values:
240 // i32a[id], where id in range [0, 3]:
241 // 0 => Worker |id| is still waiting on the futex
242 // 1 => Worker |id| is not waiting on futex, but has not be reaped by the
243 // main thread.
244 // 2 => Worker |id| has been reaped.
245 //
246 // i32a[4]:
247 // always 0. Each worker will initially wait on this index.
248 //
249 // i32a[5]:
250 // always 0. Requeued workers will wait on this index.
251
252 var workerScript =
253 `onmessage = function(msg) {
254 var id = msg.id;
255 var i32a = new Int32Array(msg.sab);
256
257 var result = Atomics.futexWait(i32a, 4, 0, Infinity);
258 Atomics.store(i32a, id, 1);
259 postMessage(result);
260 };`;
261
262 var workers = [];
263 for (id = 0; id < 4; id++) {
264 workers[id] = new Worker(workerScript);
265 workers[id].postMessage({sab: sab, id: id}, [sab]);
266 }
267
268 // Spin until all workers are waiting on the futex.
269 while (%AtomicsFutexNumWaitersForTesting(i32a, 4) != 4) {}
270
271 var index1 = 4;
272 var index2 = 5;
273
274 // If futexWakeOrRequeue is called with the incorrect value, it shouldn't
275 // wake any waiters.
276 assertEquals(Atomics.NOTEQUAL,
277 Atomics.futexWakeOrRequeue(i32a, index1, 1, 42, index2));
278
279 assertEquals(4, %AtomicsFutexNumWaitersForTesting(i32a, index1));
280 assertEquals(0, %AtomicsFutexNumWaitersForTesting(i32a, index2));
281
282 // Now wake with the correct value.
283 assertEquals(1, Atomics.futexWakeOrRequeue(i32a, index1, 1, 0, index2));
284
285 // The workers that are still waiting should atomically be transferred to
286 // the new index.
287 assertEquals(3, %AtomicsFutexNumWaitersForTesting(i32a, index2));
288
289 // The woken worker may not have been scheduled yet. Look for which thread
290 // has set its i32a value to 1.
291 var wokenCount = 0;
292 while (wokenCount < 1) {
293 for (id = 0; id < 4; id++) {
294 if (Atomics.compareExchange(i32a, id, 1, 2) == 1) {
295 wokenCount++;
296 }
297 }
298 }
299
300 assertEquals(0, %AtomicsFutexNumWaitersForTesting(i32a, index1));
301
302 // Wake the remaining waiters.
303 assertEquals(3, Atomics.futexWake(i32a, index2, 3));
304
305 // As above, wait until the workers have been scheduled.
306 wokenCount = 0;
307 while (wokenCount < 3) {
308 for (id = 0; id < 4; id++) {
309 if (Atomics.compareExchange(i32a, id, 1, 2) == 1) {
310 wokenCount++;
311 }
312 }
313 }
314
315 assertEquals(0, %AtomicsFutexNumWaitersForTesting(i32a, index1));
316 assertEquals(0, %AtomicsFutexNumWaitersForTesting(i32a, index2));
317
318 for (id = 0; id < 4; ++id) {
319 assertEquals(Atomics.OK, workers[id].getMessage());
320 }
321
322 // Test futexWakeOrRequeue on offset typed array
323 var offset = 16;
324 sab = new SharedArrayBuffer(24);
325 i32a = new Int32Array(sab);
326 var i32a2 = new Int32Array(sab, offset);
327
328 for (id = 0; id < 4; id++) {
329 workers[id].postMessage({sab: sab, id: id}, [sab]);
330 }
331
332 while (%AtomicsFutexNumWaitersForTesting(i32a2, 0) != 4) { }
333
334 index1 = 0;
335 index2 = 1;
336 assertEquals(4, %AtomicsFutexNumWaitersForTesting(i32a2, index1));
337 assertEquals(0, %AtomicsFutexNumWaitersForTesting(i32a2, index2));
338
339 assertEquals(2, Atomics.futexWakeOrRequeue(i32a2, index1, 2, 0, index2));
340 assertEquals(2, %AtomicsFutexNumWaitersForTesting(i32a2, index2));
341 assertEquals(0, %AtomicsFutexNumWaitersForTesting(i32a2, index1));
342
343 assertEquals(2, Atomics.futexWake(i32a2, index2, 2));
344
345 for (id = 0; id < 4; ++id) {
346 assertEquals(Atomics.OK, workers[id].getMessage());
347 workers[id].terminate();
348 }
349
350 })();
351
352 } 221 }
OLDNEW
« no previous file with comments | « test/cctest/test-api.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698