#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_FAIL(); } void operator delete[](void*) { Y_FAIL(); } void operator delete(void*, const std::nothrow_t&) { Y_FAIL(); } void operator delete[](void*, const std::nothrow_t&) { Y_FAIL(); } }; template <typename TFinal> 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_VERIFY(sz == sizeof(TFinal)); return NNumaAwareLockFreeAllocator::SystemAllocation(sz); } void* operator new[](size_t sz) { Y_VERIFY(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 <NNumaAwareLockFreeAllocator::TAllocHint::EHint H> 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<NNumaAwareLockFreeAllocator::TAllocHint::Incremental> {}; struct TWithNalfForceIncrementalAlloc : TWithNalfAlloc<NNumaAwareLockFreeAllocator::TAllocHint::ForceIncremental> {}; struct TWithNalfChunkedAlloc : TWithNalfAlloc<NNumaAwareLockFreeAllocator::TAllocHint::Chunked> {}; struct TWithNalfForceChunkedAlloc : TWithNalfAlloc<NNumaAwareLockFreeAllocator::TAllocHint::ForceChunked> {}; struct TWithNalfSystemAlloc : TWithNalfAlloc<NNumaAwareLockFreeAllocator::TAllocHint::System> {}; struct TWithNalfForceSystemAlloc : TWithNalfAlloc<NNumaAwareLockFreeAllocator::TAllocHint::ForceSystem> {}; using TAllocSwapIncremental = NNumaAwareLockFreeAllocator::TSwapHint<NNumaAwareLockFreeAllocator::TAllocHint::Incremental>; using TAllocSwapChunked = NNumaAwareLockFreeAllocator::TSwapHint<NNumaAwareLockFreeAllocator::TAllocHint::Chunked>; template <typename Type, NNumaAwareLockFreeAllocator::TAllocHint::EHint Hint> 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 <typename U> explicit TNalfAllocator(TNalfAllocator<U, Hint>) noexcept {} template <typename U> struct rebind { typedef TNalfAllocator<U, Hint> other; }; static pointer allocate(size_type n, const void* = nullptr) { return static_cast<pointer>(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<size_type>::max() / sizeof(value_type); } template <typename U, typename... Args> static void construct(U* p, Args&&... args) { ::new ((void*)p) U(std::forward<Args>(args)...); } template <typename U> 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 <typename Type> using TNalfChunkedAllocator = TNalfAllocator<Type, NNumaAwareLockFreeAllocator::TAllocHint::Chunked>; template <typename Type> using TNalfIncrementalAllocator = TNalfAllocator<Type, NNumaAwareLockFreeAllocator::TAllocHint::Incremental>;