| 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 |