bridge.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. #include "core-inl.h"
  2. #include <util/system/compiler.h>
  3. #include <library/cpp/malloc/api/malloc.h>
  4. #include <library/cpp/yt/memory/memory_tag.h>
  5. namespace NYT::NYTAlloc {
  6. ////////////////////////////////////////////////////////////////////////////////
  7. // YTAlloc public API
  8. #ifdef YT_ALLOC_ENABLED
  9. void* Allocate(size_t size)
  10. {
  11. return AllocateInline(size);
  12. }
  13. void* AllocateSmall(size_t rank)
  14. {
  15. return AllocateSmallInline(rank);
  16. }
  17. void* AllocatePageAligned(size_t size)
  18. {
  19. return AllocatePageAlignedInline(size);
  20. }
  21. void Free(void* ptr)
  22. {
  23. FreeInline(ptr);
  24. }
  25. void FreeNonNull(void* ptr)
  26. {
  27. FreeNonNullInline(ptr);
  28. }
  29. size_t GetAllocationSize(const void* ptr)
  30. {
  31. return GetAllocationSizeInline(ptr);
  32. }
  33. size_t GetAllocationSize(size_t size)
  34. {
  35. return GetAllocationSizeInline(size);
  36. }
  37. #endif
  38. ////////////////////////////////////////////////////////////////////////////////
  39. } // namespace NYT::NYTAlloc
  40. namespace NYT {
  41. using namespace NYTAlloc;
  42. ////////////////////////////////////////////////////////////////////////////////
  43. // Memory tags API bridge
  44. TMemoryTag GetCurrentMemoryTag()
  45. {
  46. return NYTAlloc::TThreadManager::GetCurrentMemoryTag();
  47. }
  48. void SetCurrentMemoryTag(TMemoryTag tag)
  49. {
  50. TThreadManager::SetCurrentMemoryTag(tag);
  51. }
  52. void GetMemoryUsageForTags(const TMemoryTag* tags, size_t count, size_t* results)
  53. {
  54. InitializeGlobals();
  55. StatisticsManager->GetTaggedMemoryUsage(tags, count, results);
  56. }
  57. size_t GetMemoryUsageForTag(TMemoryTag tag)
  58. {
  59. size_t result;
  60. GetMemoryUsageForTags(&tag, 1, &result);
  61. return result;
  62. }
  63. ////////////////////////////////////////////////////////////////////////////////
  64. } // namespace NYT
  65. namespace NYT::NYTAlloc {
  66. ////////////////////////////////////////////////////////////////////////////////
  67. // Memory zone API bridge
  68. void SetCurrentMemoryZone(EMemoryZone zone)
  69. {
  70. TThreadManager::SetCurrentMemoryZone(zone);
  71. }
  72. EMemoryZone GetCurrentMemoryZone()
  73. {
  74. return TThreadManager::GetCurrentMemoryZone();
  75. }
  76. EMemoryZone GetAllocationMemoryZone(const void* ptr)
  77. {
  78. auto uintptr = reinterpret_cast<uintptr_t>(ptr);
  79. if (uintptr >= MinUntaggedSmallPtr && uintptr < MaxUntaggedSmallPtr ||
  80. uintptr >= MinTaggedSmallPtr && uintptr < MaxTaggedSmallPtr ||
  81. uintptr >= DumpableLargeZoneStart && uintptr < DumpableLargeZoneEnd)
  82. {
  83. return EMemoryZone::Normal;
  84. } else if (uintptr >= UndumpableLargeZoneStart && uintptr < UndumpableLargeZoneEnd) {
  85. return EMemoryZone::Undumpable;
  86. } else {
  87. return EMemoryZone::Unknown;
  88. }
  89. }
  90. ////////////////////////////////////////////////////////////////////////////////
  91. // Fiber id API
  92. void SetCurrentFiberId(TFiberId id)
  93. {
  94. TThreadManager::SetCurrentFiberId(id);
  95. }
  96. TFiberId GetCurrentFiberId()
  97. {
  98. return TThreadManager::GetCurrentFiberId();
  99. }
  100. ////////////////////////////////////////////////////////////////////////////////
  101. } // namespace NYT::NYTAlloc
  102. ////////////////////////////////////////////////////////////////////////////////
  103. // Libc malloc bridge
  104. #ifdef YT_ALLOC_ENABLED
  105. using namespace NYT::NYTAlloc;
  106. extern "C" void* malloc(size_t size)
  107. {
  108. return AllocateInline(size);
  109. }
  110. extern "C" void* valloc(size_t size)
  111. {
  112. return AllocatePageAlignedInline(size);
  113. }
  114. extern "C" void* aligned_alloc(size_t alignment, size_t size)
  115. {
  116. // Alignment must be a power of two.
  117. Y_ABORT_UNLESS((alignment & (alignment - 1)) == 0);
  118. // Alignment must not exceed the page size.
  119. Y_ABORT_UNLESS(alignment <= PageSize);
  120. if (alignment <= 16) {
  121. // Proper alignment here is automatic.
  122. return Allocate(size);
  123. } else {
  124. return AllocatePageAligned(size);
  125. }
  126. }
  127. extern "C" void* pvalloc(size_t size)
  128. {
  129. return valloc(AlignUp(size, PageSize));
  130. }
  131. extern "C" int posix_memalign(void** ptrPtr, size_t alignment, size_t size)
  132. {
  133. *ptrPtr = aligned_alloc(alignment, size);
  134. return 0;
  135. }
  136. extern "C" void* memalign(size_t alignment, size_t size)
  137. {
  138. return aligned_alloc(alignment, size);
  139. }
  140. extern "C" void* __libc_memalign(size_t alignment, size_t size)
  141. {
  142. return aligned_alloc(alignment, size);
  143. }
  144. extern "C" void free(void* ptr)
  145. {
  146. FreeInline(ptr);
  147. }
  148. extern "C" void* calloc(size_t n, size_t elemSize)
  149. {
  150. // Overflow check.
  151. auto size = n * elemSize;
  152. if (elemSize != 0 && size / elemSize != n) {
  153. return nullptr;
  154. }
  155. void* result = Allocate(size);
  156. ::memset(result, 0, size);
  157. return result;
  158. }
  159. extern "C" void cfree(void* ptr)
  160. {
  161. Free(ptr);
  162. }
  163. extern "C" void* realloc(void* oldPtr, size_t newSize)
  164. {
  165. if (!oldPtr) {
  166. return Allocate(newSize);
  167. }
  168. if (newSize == 0) {
  169. Free(oldPtr);
  170. return nullptr;
  171. }
  172. void* newPtr = Allocate(newSize);
  173. size_t oldSize = GetAllocationSize(oldPtr);
  174. ::memcpy(newPtr, oldPtr, std::min(oldSize, newSize));
  175. Free(oldPtr);
  176. return newPtr;
  177. }
  178. extern "C" size_t malloc_usable_size(void* ptr) noexcept
  179. {
  180. return GetAllocationSize(ptr);
  181. }
  182. extern "C" size_t nallocx(size_t size, int /* flags */) noexcept
  183. {
  184. return GetAllocationSize(size);
  185. }
  186. #endif
  187. namespace NMalloc {
  188. ////////////////////////////////////////////////////////////////////////////////
  189. // Arcadia malloc API bridge
  190. TMallocInfo MallocInfo()
  191. {
  192. TMallocInfo info;
  193. info.Name = "ytalloc";
  194. return info;
  195. }
  196. ////////////////////////////////////////////////////////////////////////////////
  197. } // namespace NMalloc