source: trip-planner-front/node_modules/piscina/test/atomics-optimization.ts@ 8d391a1

Last change on this file since 8d391a1 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 2.5 KB
Line 
1import Piscina from '..';
2import { test } from 'tap';
3import { resolve } from 'path';
4
5test('coverage test for Atomics optimization', async ({ equal }) => {
6 const pool = new Piscina({
7 filename: resolve(__dirname, 'fixtures/notify-then-sleep-or.ts'),
8 minThreads: 2,
9 maxThreads: 2,
10 concurrentTasksPerWorker: 2
11 });
12
13 const tasks = [];
14 let v : number;
15
16 // Post 4 tasks, and wait for all of them to be ready.
17 const i32array = new Int32Array(new SharedArrayBuffer(4));
18 for (let index = 0; index < 4; index++) {
19 tasks.push(pool.runTask({ i32array, index }));
20 }
21
22 // Wait for 2 tasks to enter 'wait' state.
23 do {
24 v = Atomics.load(i32array, 0);
25 if (popcount8(v) >= 2) break;
26 Atomics.wait(i32array, 0, v);
27 } while (true);
28
29 // The check above could also be !== 2 but it's hard to get things right
30 // sometimes and this gives us a nice assertion. Basically, at this point
31 // exactly 2 tasks should be in Atomics.wait() state.
32 equal(popcount8(v), 2);
33 // Wake both tasks up as simultaneously as possible. The other 2 tasks should
34 // then start executing.
35 Atomics.store(i32array, 0, 0);
36 Atomics.notify(i32array, 0, Infinity);
37
38 // Wait for the other 2 tasks to enter 'wait' state.
39 do {
40 v = Atomics.load(i32array, 0);
41 if (popcount8(v) >= 2) break;
42 Atomics.wait(i32array, 0, v);
43 } while (true);
44
45 // At this point, the first two tasks are definitely finished and have
46 // definitely posted results back to the main thread, and the main thread
47 // has definitely not received them yet, meaning that the Atomics check will
48 // be used. Making sure that that works is the point of this test.
49
50 // Wake up the remaining 2 tasks in order to make sure that the test finishes.
51 // Do the same consistency check beforehand as above.
52 equal(popcount8(v), 2);
53 Atomics.store(i32array, 0, 0);
54 Atomics.notify(i32array, 0, Infinity);
55
56 await Promise.all(tasks);
57});
58
59// Inefficient but straightforward 8-bit popcount
60function popcount8 (v : number) : number {
61 v &= 0xff;
62 if (v & 0b11110000) return popcount8(v >>> 4) + popcount8(v & 0xb00001111);
63 if (v & 0b00001100) return popcount8(v >>> 2) + popcount8(v & 0xb00000011);
64 if (v & 0b00000010) return popcount8(v >>> 1) + popcount8(v & 0xb00000001);
65 return v;
66}
67
68test('avoids unbounded recursion', async () => {
69 const pool = new Piscina({
70 filename: resolve(__dirname, 'fixtures/simple-isworkerthread.ts'),
71 minThreads: 2,
72 maxThreads: 2
73 });
74
75 const tasks = [];
76 for (let i = 1; i <= 10000; i++) {
77 tasks.push(pool.runTask(null));
78 }
79
80 await Promise.all(tasks);
81});
Note: See TracBrowser for help on using the repository browser.