Unified · Split
| @@ -185,7 +185,7 @@ As a further example, consider this sequence of events: · 184 unmodified lines | |||
| 185 | =============== =============== | 185 | =============== =============== |
| 186 | { A == 1, B == 2, C == 3, P == &A, Q == &C } | 186 | { A == 1, B == 2, C == 3, P == &A, Q == &C } |
| 187 | B = 4; Q = P; | 187 | B = 4; Q = P; |
| 188 | P = &B D = *Q; | 188 | P = &B; D = *Q; |
| 189 | 189 | ||
| 190 | There is an obvious data dependency here, as the value loaded into D depends on | 190 | There is an obvious data dependency here, as the value loaded into D depends on |
| 191 | the address retrieved from P by CPU 2. At the end of the sequence, any of the | 191 | the address retrieved from P by CPU 2. At the end of the sequence, any of the |
| @@ -569,7 +569,7 @@ following sequence of events: · 377 unmodified lines | |||
| 569 | { A == 1, B == 2, C == 3, P == &A, Q == &C } | 569 | { A == 1, B == 2, C == 3, P == &A, Q == &C } |
| 570 | B = 4; | 570 | B = 4; |
| 571 | <write barrier> | 571 | <write barrier> |
| 572 | WRITE_ONCE(P, &B) | 572 | WRITE_ONCE(P, &B); |
| 573 | Q = READ_ONCE(P); | 573 | Q = READ_ONCE(P); |
| 574 | D = *Q; | 574 | D = *Q; |
| 575 | 575 | ||
| @@ -1721,7 +1721,7 @@ of optimizations: · 1145 unmodified lines | |||
| 1721 | and WRITE_ONCE() are more selective: With READ_ONCE() and | 1721 | and WRITE_ONCE() are more selective: With READ_ONCE() and |
| 1722 | WRITE_ONCE(), the compiler need only forget the contents of the | 1722 | WRITE_ONCE(), the compiler need only forget the contents of the |
| 1723 | indicated memory locations, while with barrier() the compiler must | 1723 | indicated memory locations, while with barrier() the compiler must |
| 1724 | discard the value of all memory locations that it has currented | 1724 | discard the value of all memory locations that it has currently |
| 1725 | cached in any machine registers. Of course, the compiler must also | 1725 | cached in any machine registers. Of course, the compiler must also |
| 1726 | respect the order in which the READ_ONCE()s and WRITE_ONCE()s occur, | 1726 | respect the order in which the READ_ONCE()s and WRITE_ONCE()s occur, |
| 1727 | though the CPU of course need not do so. | 1727 | though the CPU of course need not do so. |
| @@ -1833,7 +1833,7 @@ Aside: In the case of data dependencies, the compiler would be expected · 105 unmodified lines | |||
| 1833 | to issue the loads in the correct order (eg. `a[b]` would have to load | 1833 | to issue the loads in the correct order (eg. `a[b]` would have to load |
| 1834 | the value of b before loading a[b]), however there is no guarantee in | 1834 | the value of b before loading a[b]), however there is no guarantee in |
| 1835 | the C specification that the compiler may not speculate the value of b | 1835 | the C specification that the compiler may not speculate the value of b |
| 1836 | (eg. is equal to 1) and load a before b (eg. tmp = a[1]; if (b != 1) | 1836 | (eg. is equal to 1) and load a[b] before b (eg. tmp = a[1]; if (b != 1) |
| 1837 | tmp = a[b]; ). There is also the problem of a compiler reloading b after | 1837 | tmp = a[b]; ). There is also the problem of a compiler reloading b after |
| 1838 | having loaded a[b], thus having a newer copy of b than a[b]. A consensus | 1838 | having loaded a[b], thus having a newer copy of b than a[b]. A consensus |
| 1839 | has not yet been reached about these problems, however the READ_ONCE() | 1839 | has not yet been reached about these problems, however the READ_ONCE() |