1 // Copyright (c) 2008, Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 // --- 31 // Author: Sanjay Ghemawat <opensource (at) google.com> 32 33 #ifndef TCMALLOC_PAGE_HEAP_ALLOCATOR_H_ 34 #define TCMALLOC_PAGE_HEAP_ALLOCATOR_H_ 35 36 #include <stddef.h> // for NULL, size_t 37 38 #include "common.h" // for MetaDataAlloc 39 #include "internal_logging.h" // for ASSERT 40 41 namespace tcmalloc { 42 43 // Simple allocator for objects of a specified type. External locking 44 // is required before accessing one of these objects. 45 template <class T> 46 class PageHeapAllocator { 47 public: 48 // We use an explicit Init function because these variables are statically 49 // allocated and their constructors might not have run by the time some 50 // other static variable tries to allocate memory. 51 void Init() { 52 ASSERT(sizeof(T) <= kAllocIncrement); 53 inuse_ = 0; 54 free_area_ = NULL; 55 free_avail_ = 0; 56 free_list_ = NULL; 57 // Reserve some space at the beginning to avoid fragmentation. 58 Delete(New()); 59 } 60 61 T* New() { 62 // Consult free list 63 void* result; 64 if (free_list_ != NULL) { 65 result = free_list_; 66 free_list_ = *(reinterpret_cast<void**>(result)); 67 } else { 68 if (free_avail_ < sizeof(T)) { 69 // Need more room. We assume that MetaDataAlloc returns 70 // suitably aligned memory. 71 free_area_ = reinterpret_cast<char*>(MetaDataAlloc(kAllocIncrement)); 72 if (free_area_ == NULL) { 73 Log(kCrash, __FILE__, __LINE__, 74 "FATAL ERROR: Out of memory trying to allocate internal " 75 "tcmalloc data (bytes, object-size)", 76 kAllocIncrement, sizeof(T)); 77 } 78 free_avail_ = kAllocIncrement; 79 } 80 result = free_area_; 81 free_area_ += sizeof(T); 82 free_avail_ -= sizeof(T); 83 } 84 inuse_++; 85 return reinterpret_cast<T*>(result); 86 } 87 88 void Delete(T* p) { 89 *(reinterpret_cast<void**>(p)) = free_list_; 90 free_list_ = p; 91 inuse_--; 92 } 93 94 int inuse() const { return inuse_; } 95 96 private: 97 // How much to allocate from system at a time 98 static const int kAllocIncrement = 128 << 10; 99 100 // Free area from which to carve new objects 101 char* free_area_; 102 size_t free_avail_; 103 104 // Free list of already carved objects 105 void* free_list_; 106 107 // Number of allocated but unfreed objects 108 int inuse_; 109 }; 110 111 } // namespace tcmalloc 112 113 #endif // TCMALLOC_PAGE_HEAP_ALLOCATOR_H_ 114