OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 26 matching lines...) Expand all Loading... |
37 #define CHECK_EQU(v1, v2) \ | 37 #define CHECK_EQU(v1, v2) \ |
38 CHECK_EQ(static_cast<int64_t>(v1), static_cast<int64_t>(v2)) | 38 CHECK_EQ(static_cast<int64_t>(v1), static_cast<int64_t>(v2)) |
39 | 39 |
40 #define NUM_BITS(T) (sizeof(T) * 8) | 40 #define NUM_BITS(T) (sizeof(T) * 8) |
41 | 41 |
42 | 42 |
43 template <class AtomicType> | 43 template <class AtomicType> |
44 static void TestAtomicIncrement() { | 44 static void TestAtomicIncrement() { |
45 // For now, we just test the single-threaded execution. | 45 // For now, we just test the single-threaded execution. |
46 | 46 |
47 // Use a guard value to make sure that NoBarrier_AtomicIncrement doesn't | 47 // Use a guard value to make sure that Relaxed_AtomicIncrement doesn't |
48 // go outside the expected address bounds. This is to test that the | 48 // go outside the expected address bounds. This is to test that the |
49 // 32-bit NoBarrier_AtomicIncrement doesn't do the wrong thing on 64-bit | 49 // 32-bit Relaxed_AtomicIncrement doesn't do the wrong thing on 64-bit |
50 // machines. | 50 // machines. |
51 struct { | 51 struct { |
52 AtomicType prev_word; | 52 AtomicType prev_word; |
53 AtomicType count; | 53 AtomicType count; |
54 AtomicType next_word; | 54 AtomicType next_word; |
55 } s; | 55 } s; |
56 | 56 |
57 AtomicType prev_word_value, next_word_value; | 57 AtomicType prev_word_value, next_word_value; |
58 memset(&prev_word_value, 0xFF, sizeof(AtomicType)); | 58 memset(&prev_word_value, 0xFF, sizeof(AtomicType)); |
59 memset(&next_word_value, 0xEE, sizeof(AtomicType)); | 59 memset(&next_word_value, 0xEE, sizeof(AtomicType)); |
60 | 60 |
61 s.prev_word = prev_word_value; | 61 s.prev_word = prev_word_value; |
62 s.count = 0; | 62 s.count = 0; |
63 s.next_word = next_word_value; | 63 s.next_word = next_word_value; |
64 | 64 |
65 CHECK_EQU(NoBarrier_AtomicIncrement(&s.count, 1), 1); | 65 CHECK_EQU(Relaxed_AtomicIncrement(&s.count, 1), 1); |
66 CHECK_EQU(s.count, 1); | 66 CHECK_EQU(s.count, 1); |
67 CHECK_EQU(s.prev_word, prev_word_value); | 67 CHECK_EQU(s.prev_word, prev_word_value); |
68 CHECK_EQU(s.next_word, next_word_value); | 68 CHECK_EQU(s.next_word, next_word_value); |
69 | 69 |
70 CHECK_EQU(NoBarrier_AtomicIncrement(&s.count, 2), 3); | 70 CHECK_EQU(Relaxed_AtomicIncrement(&s.count, 2), 3); |
71 CHECK_EQU(s.count, 3); | 71 CHECK_EQU(s.count, 3); |
72 CHECK_EQU(s.prev_word, prev_word_value); | 72 CHECK_EQU(s.prev_word, prev_word_value); |
73 CHECK_EQU(s.next_word, next_word_value); | 73 CHECK_EQU(s.next_word, next_word_value); |
74 | 74 |
75 CHECK_EQU(NoBarrier_AtomicIncrement(&s.count, 3), 6); | 75 CHECK_EQU(Relaxed_AtomicIncrement(&s.count, 3), 6); |
76 CHECK_EQU(s.count, 6); | 76 CHECK_EQU(s.count, 6); |
77 CHECK_EQU(s.prev_word, prev_word_value); | 77 CHECK_EQU(s.prev_word, prev_word_value); |
78 CHECK_EQU(s.next_word, next_word_value); | 78 CHECK_EQU(s.next_word, next_word_value); |
79 | 79 |
80 CHECK_EQU(NoBarrier_AtomicIncrement(&s.count, -3), 3); | 80 CHECK_EQU(Relaxed_AtomicIncrement(&s.count, -3), 3); |
81 CHECK_EQU(s.count, 3); | 81 CHECK_EQU(s.count, 3); |
82 CHECK_EQU(s.prev_word, prev_word_value); | 82 CHECK_EQU(s.prev_word, prev_word_value); |
83 CHECK_EQU(s.next_word, next_word_value); | 83 CHECK_EQU(s.next_word, next_word_value); |
84 | 84 |
85 CHECK_EQU(NoBarrier_AtomicIncrement(&s.count, -2), 1); | 85 CHECK_EQU(Relaxed_AtomicIncrement(&s.count, -2), 1); |
86 CHECK_EQU(s.count, 1); | 86 CHECK_EQU(s.count, 1); |
87 CHECK_EQU(s.prev_word, prev_word_value); | 87 CHECK_EQU(s.prev_word, prev_word_value); |
88 CHECK_EQU(s.next_word, next_word_value); | 88 CHECK_EQU(s.next_word, next_word_value); |
89 | 89 |
90 CHECK_EQU(NoBarrier_AtomicIncrement(&s.count, -1), 0); | 90 CHECK_EQU(Relaxed_AtomicIncrement(&s.count, -1), 0); |
91 CHECK_EQU(s.count, 0); | 91 CHECK_EQU(s.count, 0); |
92 CHECK_EQU(s.prev_word, prev_word_value); | 92 CHECK_EQU(s.prev_word, prev_word_value); |
93 CHECK_EQU(s.next_word, next_word_value); | 93 CHECK_EQU(s.next_word, next_word_value); |
94 | 94 |
95 CHECK_EQU(NoBarrier_AtomicIncrement(&s.count, -1), -1); | 95 CHECK_EQU(Relaxed_AtomicIncrement(&s.count, -1), -1); |
96 CHECK_EQU(s.count, -1); | 96 CHECK_EQU(s.count, -1); |
97 CHECK_EQU(s.prev_word, prev_word_value); | 97 CHECK_EQU(s.prev_word, prev_word_value); |
98 CHECK_EQU(s.next_word, next_word_value); | 98 CHECK_EQU(s.next_word, next_word_value); |
99 | 99 |
100 CHECK_EQU(NoBarrier_AtomicIncrement(&s.count, -4), -5); | 100 CHECK_EQU(Relaxed_AtomicIncrement(&s.count, -4), -5); |
101 CHECK_EQU(s.count, -5); | 101 CHECK_EQU(s.count, -5); |
102 CHECK_EQU(s.prev_word, prev_word_value); | 102 CHECK_EQU(s.prev_word, prev_word_value); |
103 CHECK_EQU(s.next_word, next_word_value); | 103 CHECK_EQU(s.next_word, next_word_value); |
104 | 104 |
105 CHECK_EQU(NoBarrier_AtomicIncrement(&s.count, 5), 0); | 105 CHECK_EQU(Relaxed_AtomicIncrement(&s.count, 5), 0); |
106 CHECK_EQU(s.count, 0); | 106 CHECK_EQU(s.count, 0); |
107 CHECK_EQU(s.prev_word, prev_word_value); | 107 CHECK_EQU(s.prev_word, prev_word_value); |
108 CHECK_EQU(s.next_word, next_word_value); | 108 CHECK_EQU(s.next_word, next_word_value); |
109 } | 109 } |
110 | 110 |
111 | 111 |
112 template <class AtomicType> | 112 template <class AtomicType> |
113 static void TestCompareAndSwap() { | 113 static void TestCompareAndSwap() { |
114 AtomicType value = 0; | 114 AtomicType value = 0; |
115 AtomicType prev = NoBarrier_CompareAndSwap(&value, 0, 1); | 115 AtomicType prev = Relaxed_CompareAndSwap(&value, 0, 1); |
116 CHECK_EQU(1, value); | 116 CHECK_EQU(1, value); |
117 CHECK_EQU(0, prev); | 117 CHECK_EQU(0, prev); |
118 | 118 |
119 // Use a test value that has non-zero bits in both halves, for testing | 119 // Use a test value that has non-zero bits in both halves, for testing |
120 // the 64-bit implementation on 32-bit platforms. | 120 // the 64-bit implementation on 32-bit platforms. |
121 const AtomicType k_test_val = | 121 const AtomicType k_test_val = |
122 (static_cast<AtomicType>(1) << (NUM_BITS(AtomicType) - 2)) + 11; | 122 (static_cast<AtomicType>(1) << (NUM_BITS(AtomicType) - 2)) + 11; |
123 value = k_test_val; | 123 value = k_test_val; |
124 prev = NoBarrier_CompareAndSwap(&value, 0, 5); | 124 prev = Relaxed_CompareAndSwap(&value, 0, 5); |
125 CHECK_EQU(k_test_val, value); | 125 CHECK_EQU(k_test_val, value); |
126 CHECK_EQU(k_test_val, prev); | 126 CHECK_EQU(k_test_val, prev); |
127 | 127 |
128 value = k_test_val; | 128 value = k_test_val; |
129 prev = NoBarrier_CompareAndSwap(&value, k_test_val, 5); | 129 prev = Relaxed_CompareAndSwap(&value, k_test_val, 5); |
130 CHECK_EQU(5, value); | 130 CHECK_EQU(5, value); |
131 CHECK_EQU(k_test_val, prev); | 131 CHECK_EQU(k_test_val, prev); |
132 } | 132 } |
133 | 133 |
134 | 134 |
135 template <class AtomicType> | 135 template <class AtomicType> |
136 static void TestAtomicExchange() { | 136 static void TestAtomicExchange() { |
137 AtomicType value = 0; | 137 AtomicType value = 0; |
138 AtomicType new_value = NoBarrier_AtomicExchange(&value, 1); | 138 AtomicType new_value = Relaxed_AtomicExchange(&value, 1); |
139 CHECK_EQU(1, value); | 139 CHECK_EQU(1, value); |
140 CHECK_EQU(0, new_value); | 140 CHECK_EQU(0, new_value); |
141 | 141 |
142 // Use a test value that has non-zero bits in both halves, for testing | 142 // Use a test value that has non-zero bits in both halves, for testing |
143 // the 64-bit implementation on 32-bit platforms. | 143 // the 64-bit implementation on 32-bit platforms. |
144 const AtomicType k_test_val = | 144 const AtomicType k_test_val = |
145 (static_cast<AtomicType>(1) << (NUM_BITS(AtomicType) - 2)) + 11; | 145 (static_cast<AtomicType>(1) << (NUM_BITS(AtomicType) - 2)) + 11; |
146 value = k_test_val; | 146 value = k_test_val; |
147 new_value = NoBarrier_AtomicExchange(&value, k_test_val); | 147 new_value = Relaxed_AtomicExchange(&value, k_test_val); |
148 CHECK_EQU(k_test_val, value); | 148 CHECK_EQU(k_test_val, value); |
149 CHECK_EQU(k_test_val, new_value); | 149 CHECK_EQU(k_test_val, new_value); |
150 | 150 |
151 value = k_test_val; | 151 value = k_test_val; |
152 new_value = NoBarrier_AtomicExchange(&value, 5); | 152 new_value = Relaxed_AtomicExchange(&value, 5); |
153 CHECK_EQU(5, value); | 153 CHECK_EQU(5, value); |
154 CHECK_EQU(k_test_val, new_value); | 154 CHECK_EQU(k_test_val, new_value); |
155 } | 155 } |
156 | 156 |
157 | 157 |
158 template <class AtomicType> | 158 template <class AtomicType> |
159 static void TestAtomicIncrementBounds() { | 159 static void TestAtomicIncrementBounds() { |
160 // Test at 32-bit boundary for 64-bit atomic type. | 160 // Test at 32-bit boundary for 64-bit atomic type. |
161 AtomicType test_val = static_cast<AtomicType>(1) | 161 AtomicType test_val = static_cast<AtomicType>(1) |
162 << (NUM_BITS(AtomicType) / 2); | 162 << (NUM_BITS(AtomicType) / 2); |
163 AtomicType value = test_val - 1; | 163 AtomicType value = test_val - 1; |
164 AtomicType new_value = NoBarrier_AtomicIncrement(&value, 1); | 164 AtomicType new_value = Relaxed_AtomicIncrement(&value, 1); |
165 CHECK_EQU(test_val, value); | 165 CHECK_EQU(test_val, value); |
166 CHECK_EQU(value, new_value); | 166 CHECK_EQU(value, new_value); |
167 | 167 |
168 NoBarrier_AtomicIncrement(&value, -1); | 168 Relaxed_AtomicIncrement(&value, -1); |
169 CHECK_EQU(test_val - 1, value); | 169 CHECK_EQU(test_val - 1, value); |
170 } | 170 } |
171 | 171 |
172 | 172 |
173 // Return an AtomicType with the value 0xa5a5a5.. | 173 // Return an AtomicType with the value 0xa5a5a5.. |
174 template <class AtomicType> | 174 template <class AtomicType> |
175 static AtomicType TestFillValue() { | 175 static AtomicType TestFillValue() { |
176 AtomicType val = 0; | 176 AtomicType val = 0; |
177 memset(&val, 0xa5, sizeof(AtomicType)); | 177 memset(&val, 0xa5, sizeof(AtomicType)); |
178 return val; | 178 return val; |
179 } | 179 } |
180 | 180 |
181 | 181 |
182 // This is a simple sanity check to ensure that values are correct. | 182 // This is a simple sanity check to ensure that values are correct. |
183 // Not testing atomicity. | 183 // Not testing atomicity. |
184 template <class AtomicType> | 184 template <class AtomicType> |
185 static void TestStore() { | 185 static void TestStore() { |
186 const AtomicType kVal1 = TestFillValue<AtomicType>(); | 186 const AtomicType kVal1 = TestFillValue<AtomicType>(); |
187 const AtomicType kVal2 = static_cast<AtomicType>(-1); | 187 const AtomicType kVal2 = static_cast<AtomicType>(-1); |
188 | 188 |
189 AtomicType value; | 189 AtomicType value; |
190 | 190 |
191 NoBarrier_Store(&value, kVal1); | 191 Relaxed_Store(&value, kVal1); |
192 CHECK_EQU(kVal1, value); | 192 CHECK_EQU(kVal1, value); |
193 NoBarrier_Store(&value, kVal2); | 193 Relaxed_Store(&value, kVal2); |
194 CHECK_EQU(kVal2, value); | 194 CHECK_EQU(kVal2, value); |
195 | 195 |
196 Release_Store(&value, kVal1); | 196 Release_Store(&value, kVal1); |
197 CHECK_EQU(kVal1, value); | 197 CHECK_EQU(kVal1, value); |
198 Release_Store(&value, kVal2); | 198 Release_Store(&value, kVal2); |
199 CHECK_EQU(kVal2, value); | 199 CHECK_EQU(kVal2, value); |
200 } | 200 } |
201 | 201 |
202 | 202 |
203 // Merge this test with TestStore as soon as we have Atomic8 acquire | 203 // Merge this test with TestStore as soon as we have Atomic8 acquire |
204 // and release stores. | 204 // and release stores. |
205 static void TestStoreAtomic8() { | 205 static void TestStoreAtomic8() { |
206 const Atomic8 kVal1 = TestFillValue<Atomic8>(); | 206 const Atomic8 kVal1 = TestFillValue<Atomic8>(); |
207 const Atomic8 kVal2 = static_cast<Atomic8>(-1); | 207 const Atomic8 kVal2 = static_cast<Atomic8>(-1); |
208 | 208 |
209 Atomic8 value; | 209 Atomic8 value; |
210 | 210 |
211 NoBarrier_Store(&value, kVal1); | 211 Relaxed_Store(&value, kVal1); |
212 CHECK_EQU(kVal1, value); | 212 CHECK_EQU(kVal1, value); |
213 NoBarrier_Store(&value, kVal2); | 213 Relaxed_Store(&value, kVal2); |
214 CHECK_EQU(kVal2, value); | 214 CHECK_EQU(kVal2, value); |
215 } | 215 } |
216 | 216 |
217 | 217 |
218 // This is a simple sanity check to ensure that values are correct. | 218 // This is a simple sanity check to ensure that values are correct. |
219 // Not testing atomicity. | 219 // Not testing atomicity. |
220 template <class AtomicType> | 220 template <class AtomicType> |
221 static void TestLoad() { | 221 static void TestLoad() { |
222 const AtomicType kVal1 = TestFillValue<AtomicType>(); | 222 const AtomicType kVal1 = TestFillValue<AtomicType>(); |
223 const AtomicType kVal2 = static_cast<AtomicType>(-1); | 223 const AtomicType kVal2 = static_cast<AtomicType>(-1); |
224 | 224 |
225 AtomicType value; | 225 AtomicType value; |
226 | 226 |
227 value = kVal1; | 227 value = kVal1; |
228 CHECK_EQU(kVal1, NoBarrier_Load(&value)); | 228 CHECK_EQU(kVal1, Relaxed_Load(&value)); |
229 value = kVal2; | 229 value = kVal2; |
230 CHECK_EQU(kVal2, NoBarrier_Load(&value)); | 230 CHECK_EQU(kVal2, Relaxed_Load(&value)); |
231 | 231 |
232 value = kVal1; | 232 value = kVal1; |
233 CHECK_EQU(kVal1, Acquire_Load(&value)); | 233 CHECK_EQU(kVal1, Acquire_Load(&value)); |
234 value = kVal2; | 234 value = kVal2; |
235 CHECK_EQU(kVal2, Acquire_Load(&value)); | 235 CHECK_EQU(kVal2, Acquire_Load(&value)); |
236 } | 236 } |
237 | 237 |
238 | 238 |
239 // Merge this test with TestLoad as soon as we have Atomic8 acquire | 239 // Merge this test with TestLoad as soon as we have Atomic8 acquire |
240 // and release loads. | 240 // and release loads. |
241 static void TestLoadAtomic8() { | 241 static void TestLoadAtomic8() { |
242 const Atomic8 kVal1 = TestFillValue<Atomic8>(); | 242 const Atomic8 kVal1 = TestFillValue<Atomic8>(); |
243 const Atomic8 kVal2 = static_cast<Atomic8>(-1); | 243 const Atomic8 kVal2 = static_cast<Atomic8>(-1); |
244 | 244 |
245 Atomic8 value; | 245 Atomic8 value; |
246 | 246 |
247 value = kVal1; | 247 value = kVal1; |
248 CHECK_EQU(kVal1, NoBarrier_Load(&value)); | 248 CHECK_EQU(kVal1, Relaxed_Load(&value)); |
249 value = kVal2; | 249 value = kVal2; |
250 CHECK_EQU(kVal2, NoBarrier_Load(&value)); | 250 CHECK_EQU(kVal2, Relaxed_Load(&value)); |
251 } | 251 } |
252 | 252 |
253 | 253 |
254 TEST(AtomicIncrement) { | 254 TEST(AtomicIncrement) { |
255 TestAtomicIncrement<Atomic32>(); | 255 TestAtomicIncrement<Atomic32>(); |
256 TestAtomicIncrement<AtomicWord>(); | 256 TestAtomicIncrement<AtomicWord>(); |
257 } | 257 } |
258 | 258 |
259 | 259 |
260 TEST(CompareAndSwap) { | 260 TEST(CompareAndSwap) { |
(...skipping 19 matching lines...) Expand all Loading... |
280 TestStore<Atomic32>(); | 280 TestStore<Atomic32>(); |
281 TestStore<AtomicWord>(); | 281 TestStore<AtomicWord>(); |
282 } | 282 } |
283 | 283 |
284 | 284 |
285 TEST(Load) { | 285 TEST(Load) { |
286 TestLoadAtomic8(); | 286 TestLoadAtomic8(); |
287 TestLoad<Atomic32>(); | 287 TestLoad<Atomic32>(); |
288 TestLoad<AtomicWord>(); | 288 TestLoad<AtomicWord>(); |
289 } | 289 } |
OLD | NEW |