#pragma once #include "nalf_alloc.h" struct TNoHeapAlloc { void* operator new(size_t); void* operator new[](size_t); // implemented and available for gcc virtual destructors protected: void operator delete(void*) { Y_ABORT(); } void operator delete[](void*) { Y_ABORT(); } void operator delete(void*, const std::nothrow_t&) { Y_ABORT(); } void operator delete[](void*, const std::nothrow_t&) { Y_ABORT(); } }; template struct TSystemAllocHelper { // override new/delete to happen with system-alloc, system-free, useful for structures which could be allocated before allocator setup is complete // (allocator themself) void* operator new(size_t sz) { Y_ABORT_UNLESS(sz == sizeof(TFinal)); return NNumaAwareLockFreeAllocator::SystemAllocation(sz); } void* operator new[](size_t sz) { Y_ABORT_UNLESS(sz == sizeof(TFinal)); return NNumaAwareLockFreeAllocator::SystemAllocation(sz); } void operator delete(void* mem) { NNumaAwareLockFreeAllocator::SystemFree(mem, sizeof(TFinal)); } void operator delete[](void* mem) { NNumaAwareLockFreeAllocator::SystemFree(mem, sizeof(TFinal)); } void operator delete(void* mem, const std::nothrow_t&) { NNumaAwareLockFreeAllocator::SystemFree(mem, sizeof(TFinal)); } void operator delete[](void* mem, const std::nothrow_t&) { NNumaAwareLockFreeAllocator::SystemFree(mem, sizeof(TFinal)); } }; template struct TWithNalfAlloc { #if !defined(NALF_FORCE_MALLOC_FREE) // override new/delete to happen with nalf void* operator new(size_t sz) { return NNumaAwareLockFreeAllocator::Allocate(sz, H); } void* operator new[](size_t sz) { return NNumaAwareLockFreeAllocator::Allocate(sz, H); } void operator delete(void* mem) { NNumaAwareLockFreeAllocator::Free(mem); } void operator delete[](void* mem) { NNumaAwareLockFreeAllocator::Free(mem); } void operator delete(void* mem, const std::nothrow_t&) { NNumaAwareLockFreeAllocator::Free(mem); } void operator delete[](void* mem, const std::nothrow_t&) { NNumaAwareLockFreeAllocator::Free(mem); } #endif // NALF_FORCE_MALLOC_FREE }; struct TWithNalfIncrementalAlloc : TWithNalfAlloc {}; struct TWithNalfForceIncrementalAlloc : TWithNalfAlloc {}; struct TWithNalfChunkedAlloc : TWithNalfAlloc {}; struct TWithNalfForceChunkedAlloc : TWithNalfAlloc {}; struct TWithNalfSystemAlloc : TWithNalfAlloc {}; struct TWithNalfForceSystemAlloc : TWithNalfAlloc {}; using TAllocSwapIncremental = NNumaAwareLockFreeAllocator::TSwapHint; using TAllocSwapChunked = NNumaAwareLockFreeAllocator::TSwapHint; template struct TNalfAllocator { typedef Type value_type; typedef Type* pointer; typedef const Type* const_pointer; typedef Type& reference; typedef const Type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; TNalfAllocator() noexcept = default; ~TNalfAllocator() noexcept = default; template explicit TNalfAllocator(TNalfAllocator) noexcept {} template struct rebind { typedef TNalfAllocator other; }; static pointer allocate(size_type n, const void* = nullptr) { return static_cast(NNumaAwareLockFreeAllocator::Allocate(n * sizeof(value_type), Hint)); } static void deallocate(pointer p, size_type = 0U) { return NNumaAwareLockFreeAllocator::Free(p); } static constexpr size_type max_size() noexcept { return std::numeric_limits::max() / sizeof(value_type); } template static void construct(U* p, Args&&... args) { ::new ((void*)p) U(std::forward(args)...); } template static void destroy(U* p) { return p->~U(); } static pointer address(reference x) noexcept { return std::addressof(x); } static const_pointer address(const_reference x) noexcept { return std::addressof(x); } }; template using TNalfChunkedAllocator = TNalfAllocator; template using TNalfIncrementalAllocator = TNalfAllocator;