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