#pragma once #include "../ds/bits.h" #include "../mem/allocconfig.h" #if defined(FreeBSD_KERNEL) extern "C" { # include # include # include # include # include # include } namespace snmalloc { class PALFreeBSDKernel { vm_offset_t get_vm_offset(uint_ptr_t p) { return static_cast(reinterpret_cast(p)); } public: /** * Bitmap of PalFeatures flags indicating the optional features that this * PAL supports. */ static constexpr uint64_t pal_features = AlignedAllocation; void error(const char* const str) { panic("snmalloc error: %s", str); } /// Notify platform that we will not be using these pages void notify_not_using(void* p, size_t size) { vm_offset_t addr = get_vm_offset(p); kmem_unback(kernel_object, addr, size); } /// Notify platform that we will be using these pages template void notify_using(void* p, size_t size) { vm_offset_t addr = get_vm_offset(p); int flags = M_WAITOK | ((zero_mem == YesZero) ? M_ZERO : 0); if (kmem_back(kernel_object, addr, size, flags) != KERN_SUCCESS) { error("Out of memory"); } } /// OS specific function for zeroing memory template void zero(void* p, size_t size) { ::bzero(p, size); } template void* reserve(size_t* size, size_t align) { size_t request = *size; vm_offset_t addr; if (vmem_xalloc( kernel_arena, request, align, 0, 0, VMEM_ADDR_MIN, VMEM_ADDR_MAX, M_BESTFIT, &addr)) { return nullptr; } if (committed) { if ( kmem_back(kernel_object, addr, request, M_ZERO | M_WAITOK) != KERN_SUCCESS) { vmem_xfree(kernel_arena, addr, request); return nullptr; } } return get_vm_offset(addr); } }; } #endif