| OLD | NEW |
| 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 } |
| OLD | NEW |