Passing global allocator to FFI

I need to pass an allocator to an external FFI:

const ALLOCATOR_COMMAND_MALLOC = 0;
const ALLOCATOR_COMMAND_CALLOC = 1;
const ALLOCATOR_COMMAND_REALLOC = 2;
const ALLOCATOR_COMMAND_FREE = 3;
extern "C" fn allocator(
    self_: *mut c_void,
    size: *mut usize,
    out_ptr: *mut *mut c_void,
    allocator_command_e: usize);

While malloc and realloc are straightforward to use; you can simply utilize the alloc module. However, when it comes to freeing the memory block, it necessitates the Layout of the memory block, which, according to the C API documentation, is "not provided by size when freeing."

I've attempted to allocate extra memory for each block to store the size information, but the C API mandates 16-byte aligned memory blocks. This means that storing the size at the front of the block would waste 16 bytes of memory per allocation...

Do you have any suggestions for this problem?

Is it a problem?

In addition, I'm struggling to understand how you arrived at 16 bytes wasted with a 16 byte alignment. Would it not be 14 or 12 or 8 bytes wasted?

Yeah, 8 bytes to be precise, but I was wondering if there is a more elegant way (e.g. Static hashmap of block size, or some way to free memory from just pointers?

A static hashmap might feel more elegant, but it's also going to be a big contention point and add loads of overhead.

I'd say to just store the Layout at the head of the allocation. It'll cost you 16 bytes per allocation (2x usize), but when the alternative is a global Mutex<HashMap<...>> or writing your own allocator that can free things by just using the pointer, I think that's a good trade-off.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.