huge_allocator.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // Copyright 2019 The TCMalloc Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. //
  15. // Tracking information for the available range of hugepages,
  16. // and a basic allocator for unmapped hugepages.
  17. #ifndef TCMALLOC_HUGE_ALLOCATOR_H_
  18. #define TCMALLOC_HUGE_ALLOCATOR_H_
  19. #include <stddef.h>
  20. #include "tcmalloc/common.h"
  21. #include "tcmalloc/huge_address_map.h"
  22. #include "tcmalloc/huge_pages.h"
  23. #include "tcmalloc/stats.h"
  24. GOOGLE_MALLOC_SECTION_BEGIN
  25. namespace tcmalloc {
  26. namespace tcmalloc_internal {
  27. // these typedefs allow replacement of tcmalloc::System* for tests.
  28. typedef void *(*MemoryAllocFunction)(size_t bytes, size_t *actual,
  29. size_t align);
  30. typedef void *(*MetadataAllocFunction)(size_t bytes);
  31. // This tracks available ranges of hugepages and fulfills requests for
  32. // usable memory, allocating more from the system as needed. All
  33. // hugepages are treated as (and assumed to be) unbacked.
  34. class HugeAllocator {
  35. public:
  36. constexpr HugeAllocator(MemoryAllocFunction allocate,
  37. MetadataAllocFunction meta_allocate)
  38. : free_(meta_allocate), allocate_(allocate) {}
  39. // Obtain a range of n unbacked hugepages, distinct from all other
  40. // calls to Get (other than those that have been Released.)
  41. HugeRange Get(HugeLength n);
  42. // Returns a range of hugepages for reuse by subsequent Gets().
  43. // REQUIRES: <r> is the return value (or a subrange thereof) of a previous
  44. // call to Get(); neither <r> nor any overlapping range has been released
  45. // since that Get().
  46. void Release(HugeRange r);
  47. // Total memory requested from the system, whether in use or not,
  48. HugeLength system() const { return from_system_; }
  49. // Unused memory in the allocator.
  50. HugeLength size() const { return from_system_ - in_use_; }
  51. void AddSpanStats(SmallSpanStats *small, LargeSpanStats *large,
  52. PageAgeHistograms *ages) const;
  53. BackingStats stats() const {
  54. BackingStats s;
  55. s.system_bytes = system().in_bytes();
  56. s.free_bytes = 0;
  57. s.unmapped_bytes = size().in_bytes();
  58. return s;
  59. }
  60. void Print(Printer *out);
  61. void PrintInPbtxt(PbtxtRegion *hpaa) const;
  62. private:
  63. // We're constrained in several ways by existing code. Hard requirements:
  64. // * no radix tree or similar O(address space) external space tracking
  65. // * support sub releasing
  66. // * low metadata overhead
  67. // * no pre-allocation.
  68. // * reasonable space overhead
  69. //
  70. // We use a treap ordered on addresses to track. This isn't the most
  71. // efficient thing ever but we're about to hit 100usec+/hugepage
  72. // backing costs if we've gotten this far; the last few bits of performance
  73. // don't matter, and most of the simple ideas can't hit all of the above
  74. // requirements.
  75. HugeAddressMap free_;
  76. HugeAddressMap::Node *Find(HugeLength n);
  77. void CheckFreelist();
  78. void DebugCheckFreelist() {
  79. #ifndef NDEBUG
  80. CheckFreelist();
  81. #endif
  82. }
  83. HugeLength from_system_{NHugePages(0)};
  84. HugeLength in_use_{NHugePages(0)};
  85. MemoryAllocFunction allocate_;
  86. HugeRange AllocateRange(HugeLength n);
  87. };
  88. } // namespace tcmalloc_internal
  89. } // namespace tcmalloc
  90. GOOGLE_MALLOC_SECTION_END
  91. #endif // TCMALLOC_HUGE_ALLOCATOR_H_