chunked_memory_pool-inl.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #ifndef CHUNKED_MEMORY_POOL_INL_H_
  2. #error "Direct inclusion of this file is not allowed, include chunked_memory_pool.h"
  3. // For the sake of sane code completion.
  4. #include "chunked_memory_pool.h"
  5. #endif
  6. #include "serialize.h"
  7. #include <library/cpp/yt/malloc/malloc.h>
  8. #include <util/system/align.h>
  9. namespace NYT {
  10. ////////////////////////////////////////////////////////////////////////////////
  11. inline void TAllocationHolder::operator delete(void* ptr) noexcept
  12. {
  13. ::free(ptr);
  14. }
  15. inline TMutableRef TAllocationHolder::GetRef() const
  16. {
  17. return Ref_;
  18. }
  19. template <class TDerived>
  20. TDerived* TAllocationHolder::Allocate(size_t size, TRefCountedTypeCookie cookie)
  21. {
  22. auto requestedSize = sizeof(TDerived) + size;
  23. auto* ptr = ::malloc(requestedSize);
  24. #ifndef _win_
  25. auto allocatedSize = ::malloc_usable_size(ptr);
  26. if (allocatedSize) {
  27. size += allocatedSize - requestedSize;
  28. }
  29. #endif
  30. auto* instance = static_cast<TDerived*>(ptr);
  31. try {
  32. new (instance) TDerived(TMutableRef(instance + 1, size), cookie);
  33. } catch (const std::exception& ex) {
  34. // Do not forget to free the memory.
  35. ::free(ptr);
  36. throw;
  37. }
  38. return instance;
  39. }
  40. ////////////////////////////////////////////////////////////////////////////////
  41. inline TChunkedMemoryPool::TChunkedMemoryPool()
  42. : TChunkedMemoryPool(
  43. GetRefCountedTypeCookie<TDefaultChunkedMemoryPoolTag>())
  44. { }
  45. template <class TTag>
  46. inline TChunkedMemoryPool::TChunkedMemoryPool(
  47. TTag,
  48. size_t startChunkSize)
  49. : TChunkedMemoryPool(
  50. GetRefCountedTypeCookie<TTag>(),
  51. startChunkSize)
  52. { }
  53. inline char* TChunkedMemoryPool::AllocateUnaligned(size_t size)
  54. {
  55. // Fast path.
  56. if (FreeZoneEnd_ >= FreeZoneBegin_ + size) {
  57. FreeZoneEnd_ -= size;
  58. Size_ += size;
  59. return FreeZoneEnd_;
  60. }
  61. // Slow path.
  62. return AllocateUnalignedSlow(size);
  63. }
  64. inline char* TChunkedMemoryPool::AllocateAligned(size_t size, int align)
  65. {
  66. // NB: This can lead to FreeZoneBegin_ >= FreeZoneEnd_ in which case the chunk is full.
  67. FreeZoneBegin_ = AlignUp(FreeZoneBegin_, align);
  68. // Fast path.
  69. if (FreeZoneBegin_ + size <= FreeZoneEnd_) {
  70. char* result = FreeZoneBegin_;
  71. Size_ += size;
  72. FreeZoneBegin_ += size;
  73. return result;
  74. }
  75. // Slow path.
  76. return AllocateAlignedSlow(size, align);
  77. }
  78. template <class T>
  79. inline T* TChunkedMemoryPool::AllocateUninitialized(int n, int align)
  80. {
  81. return reinterpret_cast<T*>(AllocateAligned(sizeof(T) * n, align));
  82. }
  83. template <class T>
  84. inline TMutableRange<T> TChunkedMemoryPool::Capture(TRange<T> src, int align)
  85. {
  86. auto* dst = AllocateUninitialized<T>(src.Size(), align);
  87. ::memcpy(dst, src.Begin(), sizeof(T) * src.Size());
  88. return TMutableRange<T>(dst, src.Size());
  89. }
  90. inline void TChunkedMemoryPool::Free(char* from, char* to)
  91. {
  92. if (FreeZoneBegin_ == to) {
  93. FreeZoneBegin_ = from;
  94. }
  95. if (FreeZoneEnd_ == from) {
  96. FreeZoneEnd_ = to;
  97. }
  98. }
  99. inline void TChunkedMemoryPool::Clear()
  100. {
  101. Size_ = 0;
  102. if (Chunks_.empty()) {
  103. FreeZoneBegin_ = nullptr;
  104. FreeZoneEnd_ = nullptr;
  105. NextChunkIndex_ = 0;
  106. } else {
  107. FreeZoneBegin_ = Chunks_.front()->GetRef().Begin();
  108. FreeZoneEnd_ = Chunks_.front()->GetRef().End();
  109. NextChunkIndex_ = 1;
  110. }
  111. for (const auto& block : OtherBlocks_) {
  112. Capacity_ -= block->GetRef().Size();
  113. }
  114. OtherBlocks_.clear();
  115. }
  116. ////////////////////////////////////////////////////////////////////////////////
  117. } // namespace NYT