// Copyright (c) 2004, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // --- // Author: Sanjay Ghemawat // // Test realloc() functionality #include "config_for_unittests.h" #include <assert.h> // for assert #include <stdio.h> #include <stddef.h> // for size_t, NULL #include <stdlib.h> // for free, malloc, realloc #include <algorithm> // for min #include "base/logging.h" using std::min; // Fill a buffer of the specified size with a predetermined pattern static void Fill(unsigned char* buffer, int n) { for (int i = 0; i < n; i++) { buffer[i] = (i & 0xff); } } // Check that the specified buffer has the predetermined pattern // generated by Fill() static bool Valid(unsigned char* buffer, int n) { for (int i = 0; i < n; i++) { if (buffer[i] != (i & 0xff)) { return false; } } return true; } // Return the next interesting size/delta to check. Returns -1 if no more. static int NextSize(int size) { if (size < 100) { return size+1; } else if (size < 100000) { // Find next power of two int power = 1; while (power < size) { power <<= 1; } // Yield (power-1, power, power+1) if (size < power-1) { return power-1; } else if (size == power-1) { return power; } else { assert(size == power); return power+1; } } else { return -1; } } int main(int argc, char** argv) { for (int src_size = 0; src_size >= 0; src_size = NextSize(src_size)) { for (int dst_size = 0; dst_size >= 0; dst_size = NextSize(dst_size)) { unsigned char* src = (unsigned char*) malloc(src_size); Fill(src, src_size); unsigned char* dst = (unsigned char*) realloc(src, dst_size); CHECK(Valid(dst, min(src_size, dst_size))); Fill(dst, dst_size); CHECK(Valid(dst, dst_size)); if (dst != NULL) free(dst); } } // Now make sure realloc works correctly even when we overflow the // packed cache, so some entries are evicted from the cache. // The cache has 2^12 entries, keyed by page number. const int kNumEntries = 1 << 14; int** p = (int**)malloc(sizeof(*p) * kNumEntries); int sum = 0; for (int i = 0; i < kNumEntries; i++) { p[i] = (int*)malloc(8192); // no page size is likely to be bigger p[i][1000] = i; // use memory deep in the heart of p } for (int i = 0; i < kNumEntries; i++) { p[i] = (int*)realloc(p[i], 9000); } for (int i = 0; i < kNumEntries; i++) { sum += p[i][1000]; free(p[i]); } CHECK_EQ(kNumEntries/2 * (kNumEntries - 1), sum); // assume kNE is even free(p); printf("PASS\n"); return 0; }