15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> // for min() 8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/atomicops.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Number of bits in a size_t. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kSizeBits = 8 * sizeof(size_t); 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The maximum size of a size_t. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kMaxSize = ~static_cast<size_t>(0); 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Maximum positive size of a size_t if it were signed. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kMaxSignedSize = ((size_t(1) << (kSizeBits-1)) - 1); 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An allocation size which is not too big to be reasonable. 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kNotTooBig = 100000; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An allocation size which is just too big. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kTooBig = ~static_cast<size_t>(0); 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::min; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fill a buffer of the specified size with a predetermined pattern 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void Fill(unsigned char* buffer, int n) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < n; i++) { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer[i] = (i & 0xff); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that the specified buffer has the predetermined pattern 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// generated by Fill() 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool Valid(unsigned char* buffer, int n) { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < n; i++) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer[i] != (i & 0xff)) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that a buffer is completely zeroed. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool IsZeroed(unsigned char* buffer, int n) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < n; i++) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer[i] != 0) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check alignment 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void CheckAlignment(void* p, int align) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, reinterpret_cast<uintptr_t>(p) & (align-1)); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Return the next interesting size/delta to check. Returns -1 if no more. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int NextSize(int size) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size < 100) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size+1; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size < 100000) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find next power of two 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int power = 1; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (power < size) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power <<= 1; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Yield (power-1, power, power+1) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size < power-1) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return power-1; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size == power-1) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return power; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(size == power); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return power+1; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class AtomicType> 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TestAtomicIncrement() { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For now, we just test single threaded execution 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // use a guard value to make sure the NoBarrier_AtomicIncrement doesn't go 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // outside the expected address bounds. This is in particular to 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // test that some future change to the asm code doesn't cause the 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 32-bit NoBarrier_AtomicIncrement to do the wrong thing on 64-bit machines. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AtomicType prev_word; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AtomicType count; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AtomicType next_word; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } s; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AtomicType prev_word_value, next_word_value; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&prev_word_value, 0xFF, sizeof(AtomicType)); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&next_word_value, 0xEE, sizeof(AtomicType)); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.prev_word = prev_word_value; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.count = 0; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.next_word = next_word_value; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, 1), 1); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.count, 1); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.prev_word, prev_word_value); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.next_word, next_word_value); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, 2), 3); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.count, 3); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.prev_word, prev_word_value); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.next_word, next_word_value); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, 3), 6); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.count, 6); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.prev_word, prev_word_value); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.next_word, next_word_value); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -3), 3); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.count, 3); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.prev_word, prev_word_value); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.next_word, next_word_value); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -2), 1); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.count, 1); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.prev_word, prev_word_value); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.next_word, next_word_value); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -1), 0); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.count, 0); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.prev_word, prev_word_value); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.next_word, next_word_value); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -1), -1); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.count, -1); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.prev_word, prev_word_value); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.next_word, next_word_value); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -4), -5); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.count, -5); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.prev_word, prev_word_value); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.next_word, next_word_value); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, 5), 0); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.count, 0); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.prev_word, prev_word_value); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(s.next_word, next_word_value); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NUM_BITS(T) (sizeof(T) * 8) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class AtomicType> 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TestCompareAndSwap() { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AtomicType value = 0; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AtomicType prev = base::subtle::NoBarrier_CompareAndSwap(&value, 0, 1); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, value); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, prev); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use test value that has non-zero bits in both halves, more for testing 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 64-bit implementation on 32-bit platforms. 166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const AtomicType k_test_val = (static_cast<uint64_t>(1) << 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (NUM_BITS(AtomicType) - 2)) + 11; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = k_test_val; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev = base::subtle::NoBarrier_CompareAndSwap(&value, 0, 5); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(k_test_val, value); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(k_test_val, prev); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = k_test_val; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev = base::subtle::NoBarrier_CompareAndSwap(&value, k_test_val, 5); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(5, value); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(k_test_val, prev); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class AtomicType> 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TestAtomicExchange() { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AtomicType value = 0; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AtomicType new_value = base::subtle::NoBarrier_AtomicExchange(&value, 1); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, value); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, new_value); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use test value that has non-zero bits in both halves, more for testing 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 64-bit implementation on 32-bit platforms. 189c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const AtomicType k_test_val = (static_cast<uint64_t>(1) << 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (NUM_BITS(AtomicType) - 2)) + 11; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = k_test_val; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_value = base::subtle::NoBarrier_AtomicExchange(&value, k_test_val); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(k_test_val, value); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(k_test_val, new_value); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = k_test_val; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_value = base::subtle::NoBarrier_AtomicExchange(&value, 5); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(5, value); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(k_test_val, new_value); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class AtomicType> 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TestAtomicIncrementBounds() { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test increment at the half-width boundary of the atomic type. 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It is primarily for testing at the 32-bit boundary for 64-bit atomic type. 207c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AtomicType test_val = static_cast<uint64_t>(1) << (NUM_BITS(AtomicType) / 2); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AtomicType value = test_val - 1; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AtomicType new_value = base::subtle::NoBarrier_AtomicIncrement(&value, 1); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(test_val, value); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(value, new_value); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::subtle::NoBarrier_AtomicIncrement(&value, -1); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(test_val - 1, value); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is a simple sanity check that values are correct. Not testing 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// atomicity 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class AtomicType> 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TestStore() { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AtomicType kVal1 = static_cast<AtomicType>(0xa5a5a5a5a5a5a5a5LL); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AtomicType kVal2 = static_cast<AtomicType>(-1); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AtomicType value; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::subtle::NoBarrier_Store(&value, kVal1); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kVal1, value); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::subtle::NoBarrier_Store(&value, kVal2); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kVal2, value); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::subtle::Acquire_Store(&value, kVal1); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kVal1, value); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::subtle::Acquire_Store(&value, kVal2); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kVal2, value); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::subtle::Release_Store(&value, kVal1); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kVal1, value); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::subtle::Release_Store(&value, kVal2); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kVal2, value); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is a simple sanity check that values are correct. Not testing 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// atomicity 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class AtomicType> 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TestLoad() { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AtomicType kVal1 = static_cast<AtomicType>(0xa5a5a5a5a5a5a5a5LL); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AtomicType kVal2 = static_cast<AtomicType>(-1); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AtomicType value; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = kVal1; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kVal1, base::subtle::NoBarrier_Load(&value)); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = kVal2; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kVal2, base::subtle::NoBarrier_Load(&value)); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = kVal1; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kVal1, base::subtle::Acquire_Load(&value)); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = kVal2; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kVal2, base::subtle::Acquire_Load(&value)); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = kVal1; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kVal1, base::subtle::Release_Load(&value)); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = kVal2; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kVal2, base::subtle::Release_Load(&value)); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class AtomicType> 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TestAtomicOps() { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompareAndSwap<AtomicType>(); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestAtomicExchange<AtomicType>(); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestAtomicIncrementBounds<AtomicType>(); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestStore<AtomicType>(); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestLoad<AtomicType>(); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TestCalloc(size_t n, size_t s, bool ok) { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* p = reinterpret_cast<char*>(calloc(n, s)); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ok) { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(NULL, p) << "calloc(n, s) should not succeed"; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(reinterpret_cast<void*>(NULL), p) << 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "calloc(n, s) should succeed"; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < n*s; i++) { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ('\0', p[i]); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(p); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// MSVC C4530 complains about exception handler usage when exceptions are 2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// disabled. Temporarily disable that warning so we can test that they are, in 2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// fact, disabled. 2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_WIN) 2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#pragma warning(push) 2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#pragma warning(disable: 4530) 2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A global test counter for number of times the NewHandler is called. 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int news_handled = 0; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TestNewHandler() { 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++news_handled; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw std::bad_alloc(); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Because we compile without exceptions, we expect these will not throw. 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TestOneNewWithoutExceptions(void* (*func)(size_t), 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool should_throw) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // success test 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* ptr = (*func)(kNotTooBig); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(reinterpret_cast<void*>(NULL), ptr) << 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "allocation should not have failed."; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } catch(...) { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, 1) << "allocation threw unexpected exception."; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // failure test 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* rv = (*func)(kTooBig); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(NULL, rv); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(should_throw) << "allocation should have thrown."; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } catch(...) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(should_throw) << "allocation threw unexpected exception."; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TestNothrowNew(void* (*func)(size_t)) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) news_handled = 0; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // test without new_handler: 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::new_handler saved_handler = std::set_new_handler(0); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestOneNewWithoutExceptions(func, false); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // test with new_handler: 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set_new_handler(TestNewHandler); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestOneNewWithoutExceptions(func, true); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(news_handled, 1) << "nothrow new_handler was not called."; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set_new_handler(saved_handler); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_WIN) 3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#pragma warning(pop) 3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//----------------------------------------------------------------------------- 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Atomics, AtomicIncrementWord) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestAtomicIncrement<AtomicWord>(); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Atomics, AtomicIncrement32) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestAtomicIncrement<Atomic32>(); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Atomics, AtomicOpsWord) { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestAtomicIncrement<AtomicWord>(); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Atomics, AtomicOps32) { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestAtomicIncrement<Atomic32>(); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Allocators, Malloc) { 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try allocating data with a bunch of alignments and sizes 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int size = 1; size < 1048576; size *= 2) { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char* ptr = reinterpret_cast<unsigned char*>(malloc(size)); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckAlignment(ptr, 2); // Should be 2 byte aligned 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Fill(ptr, size); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(Valid(ptr, size)); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(ptr); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Allocators, Calloc) { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCalloc(0, 0, true); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCalloc(0, 1, true); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCalloc(1, 1, true); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCalloc(1<<10, 0, true); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCalloc(1<<20, 0, true); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCalloc(0, 1<<10, true); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCalloc(0, 1<<20, true); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCalloc(1<<20, 2, true); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCalloc(2, 1<<20, true); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCalloc(1000, 1000, true); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCalloc(kMaxSize, 2, false); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCalloc(2, kMaxSize, false); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCalloc(kMaxSize, kMaxSize, false); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCalloc(kMaxSignedSize, 3, false); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCalloc(3, kMaxSignedSize, false); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCalloc(kMaxSignedSize, kMaxSignedSize, false); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Allocators, New) { 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestNothrowNew(&::operator new); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestNothrowNew(&::operator new[]); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This makes sure that reallocing a small number of bytes in either 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// direction doesn't cause us to allocate new memory. 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Allocators, Realloc1) { 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int start_sizes[] = { 100, 1000, 10000, 100000 }; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int deltas[] = { 1, -2, 4, -8, 16, -32, 64, -128 }; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int s = 0; s < sizeof(start_sizes)/sizeof(*start_sizes); ++s) { 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* p = malloc(start_sizes[s]); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(p); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The larger the start-size, the larger the non-reallocing delta. 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int d = 0; d < s*2; ++d) { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* new_p = realloc(p, start_sizes[s] + deltas[d]); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(p, new_p); // realloc should not allocate new memory 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test again, but this time reallocing smaller first. 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int d = 0; d < s*2; ++d) { 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* new_p = realloc(p, start_sizes[s] - deltas[d]); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(p, new_p); // realloc should not allocate new memory 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(p); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Allocators, Realloc2) { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int src_size = 0; src_size >= 0; src_size = NextSize(src_size)) { 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int dst_size = 0; dst_size >= 0; dst_size = NextSize(dst_size)) { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char* src = reinterpret_cast<unsigned char*>(malloc(src_size)); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Fill(src, src_size); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char* dst = 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<unsigned char*>(realloc(src, dst_size)); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(Valid(dst, min(src_size, dst_size))); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Fill(dst, dst_size); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(Valid(dst, dst_size)); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dst != NULL) free(dst); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now make sure realloc works correctly even when we overflow the 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // packed cache, so some entries are evicted from the cache. 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The cache has 2^12 entries, keyed by page number. 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kNumEntries = 1 << 14; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int** p = reinterpret_cast<int**>(malloc(sizeof(*p) * kNumEntries)); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sum = 0; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kNumEntries; i++) { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // no page size is likely to be bigger than 8192? 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p[i] = reinterpret_cast<int*>(malloc(8192)); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p[i][1000] = i; // use memory deep in the heart of p 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kNumEntries; i++) { 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p[i] = reinterpret_cast<int*>(realloc(p[i], 9000)); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kNumEntries; i++) { 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sum += p[i][1000]; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(p[i]); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kNumEntries/2 * (kNumEntries - 1), sum); // assume kNE is even 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(p); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Allocators, ReallocZero) { 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that realloc to zero does not return NULL. 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int size = 0; size >= 0; size = NextSize(size)) { 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* ptr = reinterpret_cast<char*>(malloc(size)); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(static_cast<char*>(NULL), ptr); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr = reinterpret_cast<char*>(realloc(ptr, 0)); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(static_cast<char*>(NULL), ptr); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ptr) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(ptr); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WIN32 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test recalloc 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Allocators, Recalloc) { 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int src_size = 0; src_size >= 0; src_size = NextSize(src_size)) { 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int dst_size = 0; dst_size >= 0; dst_size = NextSize(dst_size)) { 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char* src = 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<unsigned char*>(_recalloc(NULL, 1, src_size)); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(IsZeroed(src, src_size)); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Fill(src, src_size); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char* dst = 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<unsigned char*>(_recalloc(src, 1, dst_size)); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(Valid(dst, min(src_size, dst_size))); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Fill(dst, dst_size); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(Valid(dst, dst_size)); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dst != NULL) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(dst); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test windows specific _aligned_malloc() and _aligned_free() methods. 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Allocators, AlignedMalloc) { 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try allocating data with a bunch of alignments and sizes 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kTestAlignments[] = {8, 16, 256, 4096, 8192, 16384}; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int size = 1; size > 0; size = NextSize(size)) { 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < ARRAYSIZE(kTestAlignments); ++i) { 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char* ptr = static_cast<unsigned char*>( 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _aligned_malloc(size, kTestAlignments[i])); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckAlignment(ptr, kTestAlignments[i]); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Fill(ptr, size); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(Valid(ptr, size)); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a second allocation of the same size and alignment to prevent 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // allocators from passing this test by accident. Per jar, tcmalloc 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // provides allocations for new (never before seen) sizes out of a thread 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // local heap of a given "size class." Each time the test requests a new 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size, it will usually get the first element of a span, which is a 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 4K aligned allocation. 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char* ptr2 = static_cast<unsigned char*>( 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _aligned_malloc(size, kTestAlignments[i])); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckAlignment(ptr2, kTestAlignments[i]); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Fill(ptr2, size); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(Valid(ptr2, size)); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Should never happen, but sanity check just in case. 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(ptr, ptr2); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _aligned_free(ptr); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _aligned_free(ptr2); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, char** argv) { 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testing::InitGoogleTest(&argc, argv); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return RUN_ALL_TESTS(); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 532