Commit ff7ab9d
Fix ParkingLot memory ordering bug
Summary:
```
auto x = std::atomic<std::uint64_t>{0};
auto y = std::atomic<std::uint64_t>{0};
// thread 1
x.store(1, std::memory_order_release);
auto one = y.load(std::memory_order_seq_cst);
// thread 2
y.fetch_add(1, std::memory_order_seq_cst);
auto two = x.load(std::memory_order_seq_cst);
```
Here it is possible for both `one` and `two` to end up with the value `0`. The
code in ParkingLot assumed that this would not be possible; and the counter used
to track the number of waiters could get reordered with respect to loads around
it. This diff adds a seq_cst fence to ensure unparking threads always sequence
their stores before parking _before_ the counter load globally.
Reviewed By: yfeldblum, ot
Differential Revision: D28972810
fbshipit-source-id: 06eb6a2e6df6b00bf07ac8454a79257a5276e1541 parent d418b5e commit ff7ab9d
2 files changed
Lines changed: 49 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
300 | 300 | | |
301 | 301 | | |
302 | 302 | | |
| 303 | + | |
303 | 304 | | |
304 | 305 | | |
305 | 306 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
64 | 112 | | |
65 | 113 | | |
66 | 114 | | |
| |||
0 commit comments