diff options
Diffstat (limited to 'Documentation/memory-barriers.txt')
-rw-r--r-- | Documentation/memory-barriers.txt | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index 22a969cdd476..f7fa63508aba 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt | |||
@@ -121,22 +121,22 @@ For example, consider the following sequence of events: | |||
121 | The set of accesses as seen by the memory system in the middle can be arranged | 121 | The set of accesses as seen by the memory system in the middle can be arranged |
122 | in 24 different combinations: | 122 | in 24 different combinations: |
123 | 123 | ||
124 | STORE A=3, STORE B=4, x=LOAD A->3, y=LOAD B->4 | 124 | STORE A=3, STORE B=4, y=LOAD A->3, x=LOAD B->4 |
125 | STORE A=3, STORE B=4, y=LOAD B->4, x=LOAD A->3 | 125 | STORE A=3, STORE B=4, x=LOAD B->4, y=LOAD A->3 |
126 | STORE A=3, x=LOAD A->3, STORE B=4, y=LOAD B->4 | 126 | STORE A=3, y=LOAD A->3, STORE B=4, x=LOAD B->4 |
127 | STORE A=3, x=LOAD A->3, y=LOAD B->2, STORE B=4 | 127 | STORE A=3, y=LOAD A->3, x=LOAD B->2, STORE B=4 |
128 | STORE A=3, y=LOAD B->2, STORE B=4, x=LOAD A->3 | 128 | STORE A=3, x=LOAD B->2, STORE B=4, y=LOAD A->3 |
129 | STORE A=3, y=LOAD B->2, x=LOAD A->3, STORE B=4 | 129 | STORE A=3, x=LOAD B->2, y=LOAD A->3, STORE B=4 |
130 | STORE B=4, STORE A=3, x=LOAD A->3, y=LOAD B->4 | 130 | STORE B=4, STORE A=3, y=LOAD A->3, x=LOAD B->4 |
131 | STORE B=4, ... | 131 | STORE B=4, ... |
132 | ... | 132 | ... |
133 | 133 | ||
134 | and can thus result in four different combinations of values: | 134 | and can thus result in four different combinations of values: |
135 | 135 | ||
136 | x == 1, y == 2 | 136 | x == 2, y == 1 |
137 | x == 1, y == 4 | 137 | x == 2, y == 3 |
138 | x == 3, y == 2 | 138 | x == 4, y == 1 |
139 | x == 3, y == 4 | 139 | x == 4, y == 3 |
140 | 140 | ||
141 | 141 | ||
142 | Furthermore, the stores committed by a CPU to the memory system may not be | 142 | Furthermore, the stores committed by a CPU to the memory system may not be |
@@ -694,6 +694,24 @@ Please note once again that the stores to 'b' differ. If they were | |||
694 | identical, as noted earlier, the compiler could pull this store outside | 694 | identical, as noted earlier, the compiler could pull this store outside |
695 | of the 'if' statement. | 695 | of the 'if' statement. |
696 | 696 | ||
697 | You must also be careful not to rely too much on boolean short-circuit | ||
698 | evaluation. Consider this example: | ||
699 | |||
700 | q = ACCESS_ONCE(a); | ||
701 | if (a || 1 > 0) | ||
702 | ACCESS_ONCE(b) = 1; | ||
703 | |||
704 | Because the second condition is always true, the compiler can transform | ||
705 | this example as following, defeating control dependency: | ||
706 | |||
707 | q = ACCESS_ONCE(a); | ||
708 | ACCESS_ONCE(b) = 1; | ||
709 | |||
710 | This example underscores the need to ensure that the compiler cannot | ||
711 | out-guess your code. More generally, although ACCESS_ONCE() does force | ||
712 | the compiler to actually emit code for a given load, it does not force | ||
713 | the compiler to use the results. | ||
714 | |||
697 | Finally, control dependencies do -not- provide transitivity. This is | 715 | Finally, control dependencies do -not- provide transitivity. This is |
698 | demonstrated by two related examples, with the initial values of | 716 | demonstrated by two related examples, with the initial values of |
699 | x and y both being zero: | 717 | x and y both being zero: |