Skip to content
This repository was archived by the owner on Jan 25, 2022. It is now read-only.

Commit da11157

Browse files
committed
Create FAQ.md, issue #40
1 parent b5a6107 commit da11157

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

FAQ.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Frequently asked questions
2+
3+
## My racy program does not do what I expect it to do
4+
5+
Consider two threads where one is busy-waiting on the other:
6+
7+
```js
8+
// Thread 1 // Thread 2
9+
while (mem[n] == 0) { ...
10+
/* do nothing */ mem[n] = 1
11+
} ...
12+
print("Hi")
13+
```
14+
15+
The programmer's intent is clear: the loop in Thread 1
16+
waits until a flag is set, and eventually Thread 2 sets the flag,
17+
signaling for Thread 1 to leave the loop.
18+
19+
Thread 1 may never print "Hi", or it may only sometimes print "Hi"
20+
and sometimes not. (When it does not it will loop forever.) The reason
21+
is that the read in the loop does not synchronize with the write, and may
22+
therefore be lifted out of the loop by the compiler, like this:
23+
24+
```js
25+
// Thread 1
26+
let temp = mem[n];
27+
while (temp == 0) {
28+
/* do nothing */
29+
}
30+
print("Hi")
31+
```
32+
33+
If the write by Thread 2 is visible to Thread 1 at the time Thread 1 performs the
34+
read then the loop is skipped, but if the write comes later then it is not seen at all
35+
and the loop runs forever.
36+
37+
The Firefox JavaScript compiler performs that optimization, so the program
38+
will run fine when it runs in the interpreter but will stop working
39+
once the code becomes compiled.
40+
41+
The solution is to use proper synchronization:
42+
43+
```js
44+
// Thread 1 // Thread 2
45+
while (Atomics.load(mem, n) == 0) { ...
46+
/* do nothing */ Atomics.store(mem, n, 1);
47+
} ...
48+
print("Hi")
49+
```

0 commit comments

Comments
 (0)