Home | History | Annotate | Download | only in src
      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