1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Copyright (c) 2009 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdio.h> 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdlib.h> 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <algorithm> // for min() 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/atomicops.h" 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Number of bits in a size_t. 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic const int kSizeBits = 8 * sizeof(size_t); 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The maximum size of a size_t. 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic const size_t kMaxSize = ~static_cast<size_t>(0); 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Maximum positive size of a size_t if it were signed. 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic const size_t kMaxSignedSize = ((size_t(1) << (kSizeBits-1)) - 1); 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// An allocation size which is not too big to be reasonable. 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic const size_t kNotTooBig = 100000; 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// An allocation size which is just too big. 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic const size_t kTooBig = ~static_cast<size_t>(0); 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace { 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottusing std::min; 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Fill a buffer of the specified size with a predetermined pattern 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void Fill(unsigned char* buffer, int n) { 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < n; i++) { 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott buffer[i] = (i & 0xff); 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Check that the specified buffer has the predetermined pattern 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// generated by Fill() 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic bool Valid(unsigned char* buffer, int n) { 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < n; i++) { 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (buffer[i] != (i & 0xff)) { 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Check that a buffer is completely zeroed. 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic bool IsZeroed(unsigned char* buffer, int n) { 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < n; i++) { 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (buffer[i] != 0) { 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Check alignment 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void CheckAlignment(void* p, int align) { 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(0, reinterpret_cast<uintptr_t>(p) & (align-1)); 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Return the next interesting size/delta to check. Returns -1 if no more. 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int NextSize(int size) { 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (size < 100) 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return size+1; 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (size < 100000) { 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Find next power of two 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int power = 1; 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (power < size) 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott power <<= 1; 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Yield (power-1, power, power+1) 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (size < power-1) 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return power-1; 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (size == power-1) 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return power; 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott assert(size == power); 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return power+1; 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return -1; 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define GG_ULONGLONG(x) static_cast<uint64>(x) 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class AtomicType> 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void TestAtomicIncrement() { 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // For now, we just test single threaded execution 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // use a guard value to make sure the NoBarrier_AtomicIncrement doesn't go 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // outside the expected address bounds. This is in particular to 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // test that some future change to the asm code doesn't cause the 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 32-bit NoBarrier_AtomicIncrement to do the wrong thing on 64-bit machines. 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct { 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AtomicType prev_word; 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AtomicType count; 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AtomicType next_word; 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } s; 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AtomicType prev_word_value, next_word_value; 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(&prev_word_value, 0xFF, sizeof(AtomicType)); 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(&next_word_value, 0xEE, sizeof(AtomicType)); 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott s.prev_word = prev_word_value; 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott s.count = 0; 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott s.next_word = next_word_value; 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, 1), 1); 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.count, 1); 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.prev_word, prev_word_value); 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.next_word, next_word_value); 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, 2), 3); 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.count, 3); 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.prev_word, prev_word_value); 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.next_word, next_word_value); 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, 3), 6); 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.count, 6); 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.prev_word, prev_word_value); 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.next_word, next_word_value); 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -3), 3); 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.count, 3); 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.prev_word, prev_word_value); 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.next_word, next_word_value); 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -2), 1); 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.count, 1); 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.prev_word, prev_word_value); 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.next_word, next_word_value); 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -1), 0); 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.count, 0); 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.prev_word, prev_word_value); 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.next_word, next_word_value); 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -1), -1); 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.count, -1); 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.prev_word, prev_word_value); 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.next_word, next_word_value); 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -4), -5); 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.count, -5); 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.prev_word, prev_word_value); 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.next_word, next_word_value); 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, 5), 0); 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.count, 0); 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.prev_word, prev_word_value); 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(s.next_word, next_word_value); 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NUM_BITS(T) (sizeof(T) * 8) 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class AtomicType> 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void TestCompareAndSwap() { 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AtomicType value = 0; 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AtomicType prev = base::subtle::NoBarrier_CompareAndSwap(&value, 0, 1); 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(1, value); 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(0, prev); 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Use test value that has non-zero bits in both halves, more for testing 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 64-bit implementation on 32-bit platforms. 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const AtomicType k_test_val = (GG_ULONGLONG(1) << 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (NUM_BITS(AtomicType) - 2)) + 11; 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott value = k_test_val; 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott prev = base::subtle::NoBarrier_CompareAndSwap(&value, 0, 5); 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(k_test_val, value); 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(k_test_val, prev); 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott value = k_test_val; 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott prev = base::subtle::NoBarrier_CompareAndSwap(&value, k_test_val, 5); 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(5, value); 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(k_test_val, prev); 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class AtomicType> 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void TestAtomicExchange() { 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AtomicType value = 0; 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AtomicType new_value = base::subtle::NoBarrier_AtomicExchange(&value, 1); 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(1, value); 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(0, new_value); 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Use test value that has non-zero bits in both halves, more for testing 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 64-bit implementation on 32-bit platforms. 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const AtomicType k_test_val = (GG_ULONGLONG(1) << 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (NUM_BITS(AtomicType) - 2)) + 11; 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott value = k_test_val; 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new_value = base::subtle::NoBarrier_AtomicExchange(&value, k_test_val); 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(k_test_val, value); 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(k_test_val, new_value); 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott value = k_test_val; 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new_value = base::subtle::NoBarrier_AtomicExchange(&value, 5); 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(5, value); 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(k_test_val, new_value); 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class AtomicType> 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void TestAtomicIncrementBounds() { 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Test increment at the half-width boundary of the atomic type. 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // It is primarily for testing at the 32-bit boundary for 64-bit atomic type. 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AtomicType test_val = GG_ULONGLONG(1) << (NUM_BITS(AtomicType) / 2); 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AtomicType value = test_val - 1; 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AtomicType new_value = base::subtle::NoBarrier_AtomicIncrement(&value, 1); 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(test_val, value); 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(value, new_value); 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::subtle::NoBarrier_AtomicIncrement(&value, -1); 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(test_val - 1, value); 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This is a simple sanity check that values are correct. Not testing 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// atomicity 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class AtomicType> 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void TestStore() { 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const AtomicType kVal1 = static_cast<AtomicType>(0xa5a5a5a5a5a5a5a5LL); 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const AtomicType kVal2 = static_cast<AtomicType>(-1); 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AtomicType value; 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::subtle::NoBarrier_Store(&value, kVal1); 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(kVal1, value); 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::subtle::NoBarrier_Store(&value, kVal2); 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(kVal2, value); 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::subtle::Acquire_Store(&value, kVal1); 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(kVal1, value); 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::subtle::Acquire_Store(&value, kVal2); 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(kVal2, value); 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::subtle::Release_Store(&value, kVal1); 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(kVal1, value); 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::subtle::Release_Store(&value, kVal2); 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(kVal2, value); 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This is a simple sanity check that values are correct. Not testing 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// atomicity 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class AtomicType> 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void TestLoad() { 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const AtomicType kVal1 = static_cast<AtomicType>(0xa5a5a5a5a5a5a5a5LL); 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const AtomicType kVal2 = static_cast<AtomicType>(-1); 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AtomicType value; 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott value = kVal1; 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(kVal1, base::subtle::NoBarrier_Load(&value)); 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott value = kVal2; 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(kVal2, base::subtle::NoBarrier_Load(&value)); 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott value = kVal1; 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(kVal1, base::subtle::Acquire_Load(&value)); 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott value = kVal2; 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(kVal2, base::subtle::Acquire_Load(&value)); 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott value = kVal1; 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(kVal1, base::subtle::Release_Load(&value)); 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott value = kVal2; 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(kVal2, base::subtle::Release_Load(&value)); 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class AtomicType> 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void TestAtomicOps() { 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCompareAndSwap<AtomicType>(); 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestAtomicExchange<AtomicType>(); 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestAtomicIncrementBounds<AtomicType>(); 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestStore<AtomicType>(); 275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestLoad<AtomicType>(); 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void TestCalloc(size_t n, size_t s, bool ok) { 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char* p = reinterpret_cast<char*>(calloc(n, s)); 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!ok) { 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(NULL, p) << "calloc(n, s) should not succeed"; 282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_NE(reinterpret_cast<void*>(NULL), p) << 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "calloc(n, s) should succeed"; 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < n*s; i++) { 286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ('\0', p[i]); 287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(p); 289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A global test counter for number of times the NewHandler is called. 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int news_handled = 0; 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void TestNewHandler() { 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ++news_handled; 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott throw std::bad_alloc(); 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Because we compile without exceptions, we expect these will not throw. 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void TestOneNewWithoutExceptions(void* (*func)(size_t), 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool should_throw) { 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // success test 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott try { 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void* ptr = (*func)(kNotTooBig); 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_NE(reinterpret_cast<void*>(NULL), ptr) << 307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "allocation should not have failed."; 308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } catch(...) { 309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(0, 1) << "allocation threw unexpected exception."; 310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // failure test 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott try { 314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void* rv = (*func)(kTooBig); 315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(NULL, rv); 31672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_FALSE(should_throw) << "allocation should have thrown."; 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } catch(...) { 31872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_TRUE(should_throw) << "allocation threw unexpected exception."; 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void TestNothrowNew(void* (*func)(size_t)) { 323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott news_handled = 0; 324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // test without new_handler: 326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::new_handler saved_handler = std::set_new_handler(0); 327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestOneNewWithoutExceptions(func, false); 328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // test with new_handler: 330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::set_new_handler(TestNewHandler); 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestOneNewWithoutExceptions(func, true); 332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(news_handled, 1) << "nothrow new_handler was not called."; 333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::set_new_handler(saved_handler); 334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//----------------------------------------------------------------------------- 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(Atomics, AtomicIncrementWord) { 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestAtomicIncrement<AtomicWord>(); 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(Atomics, AtomicIncrement32) { 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestAtomicIncrement<Atomic32>(); 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(Atomics, AtomicOpsWord) { 349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestAtomicIncrement<AtomicWord>(); 350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(Atomics, AtomicOps32) { 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestAtomicIncrement<Atomic32>(); 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(Allocators, Malloc) { 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Try allocating data with a bunch of alignments and sizes 358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int size = 1; size < 1048576; size *= 2) { 359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned char* ptr = reinterpret_cast<unsigned char*>(malloc(size)); 360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CheckAlignment(ptr, 2); // Should be 2 byte aligned 361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Fill(ptr, size); 36272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_TRUE(Valid(ptr, size)); 363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(ptr); 364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(Allocators, Calloc) { 368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCalloc(0, 0, true); 369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCalloc(0, 1, true); 370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCalloc(1, 1, true); 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCalloc(1<<10, 0, true); 372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCalloc(1<<20, 0, true); 373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCalloc(0, 1<<10, true); 374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCalloc(0, 1<<20, true); 375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCalloc(1<<20, 2, true); 376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCalloc(2, 1<<20, true); 377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCalloc(1000, 1000, true); 378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCalloc(kMaxSize, 2, false); 380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCalloc(2, kMaxSize, false); 381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCalloc(kMaxSize, kMaxSize, false); 382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCalloc(kMaxSignedSize, 3, false); 384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCalloc(3, kMaxSignedSize, false); 385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestCalloc(kMaxSignedSize, kMaxSignedSize, false); 386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(Allocators, New) { 389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestNothrowNew(&::operator new); 390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TestNothrowNew(&::operator new[]); 391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This makes sure that reallocing a small number of bytes in either 394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// direction doesn't cause us to allocate new memory. 395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(Allocators, Realloc1) { 396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int start_sizes[] = { 100, 1000, 10000, 100000 }; 397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int deltas[] = { 1, -2, 4, -8, 16, -32, 64, -128 }; 398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int s = 0; s < sizeof(start_sizes)/sizeof(*start_sizes); ++s) { 400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void* p = malloc(start_sizes[s]); 401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CHECK(p); 402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The larger the start-size, the larger the non-reallocing delta. 403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int d = 0; d < s*2; ++d) { 404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void* new_p = realloc(p, start_sizes[s] + deltas[d]); 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK_EQ(p, new_p); // realloc should not allocate new memory 406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Test again, but this time reallocing smaller first. 408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int d = 0; d < s*2; ++d) { 409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void* new_p = realloc(p, start_sizes[s] - deltas[d]); 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK_EQ(p, new_p); // realloc should not allocate new memory 411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(p); 413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(Allocators, Realloc2) { 417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int src_size = 0; src_size >= 0; src_size = NextSize(src_size)) { 418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int dst_size = 0; dst_size >= 0; dst_size = NextSize(dst_size)) { 419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned char* src = reinterpret_cast<unsigned char*>(malloc(src_size)); 420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Fill(src, src_size); 421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned char* dst = 422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott reinterpret_cast<unsigned char*>(realloc(src, dst_size)); 42372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_TRUE(Valid(dst, min(src_size, dst_size))); 424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Fill(dst, dst_size); 42572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_TRUE(Valid(dst, dst_size)); 426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (dst != NULL) free(dst); 427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Now make sure realloc works correctly even when we overflow the 431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // packed cache, so some entries are evicted from the cache. 432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The cache has 2^12 entries, keyed by page number. 433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const int kNumEntries = 1 << 14; 434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int** p = reinterpret_cast<int**>(malloc(sizeof(*p) * kNumEntries)); 435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int sum = 0; 436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < kNumEntries; i++) { 437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // no page size is likely to be bigger than 8192? 438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott p[i] = reinterpret_cast<int*>(malloc(8192)); 439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott p[i][1000] = i; // use memory deep in the heart of p 440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < kNumEntries; i++) { 442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott p[i] = reinterpret_cast<int*>(realloc(p[i], 9000)); 443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < kNumEntries; i++) { 445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sum += p[i][1000]; 446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(p[i]); 447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(kNumEntries/2 * (kNumEntries - 1), sum); // assume kNE is even 449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(p); 450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(Allocators, ReallocZero) { 453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Test that realloc to zero does not return NULL. 454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int size = 0; size >= 0; size = NextSize(size)) { 455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char* ptr = reinterpret_cast<char*>(malloc(size)); 456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_NE(static_cast<char*>(NULL), ptr); 457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ptr = reinterpret_cast<char*>(realloc(ptr, 0)); 458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_NE(static_cast<char*>(NULL), ptr); 459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ptr) 460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(ptr); 461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef WIN32 465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test recalloc 466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(Allocators, Recalloc) { 467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int src_size = 0; src_size >= 0; src_size = NextSize(src_size)) { 468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int dst_size = 0; dst_size >= 0; dst_size = NextSize(dst_size)) { 469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned char* src = 470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott reinterpret_cast<unsigned char*>(_recalloc(NULL, 1, src_size)); 47172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_TRUE(IsZeroed(src, src_size)); 472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Fill(src, src_size); 473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned char* dst = 474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott reinterpret_cast<unsigned char*>(_recalloc(src, 1, dst_size)); 47572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_TRUE(Valid(dst, min(src_size, dst_size))); 476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Fill(dst, dst_size); 47772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_TRUE(Valid(dst, dst_size)); 478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (dst != NULL) 479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(dst); 480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint main(int argc, char** argv) { 487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott testing::InitGoogleTest(&argc, argv); 488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return RUN_ALL_TESTS(); 489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 490