Ordering constraints for alloc?

cppreference says the following about malloc

A previous call to free or realloc that deallocates a region of memory synchronizes-with a call to malloc that allocates the same or a part of the same region of memory. This synchronization occurs after any access to the memory by the deallocating function and before any access to the memory by malloc.

Does Rust assume similar synchronization requirements around alloc/dealloc? I am not sure if the definition of malloc falls under the C11 memory model.

1 Like

If your question is equivalent to this:

Would it break any existing correct code if I made a custom allocator that didn't introduce synchronization?

Then I believe the answer is no, because calls to the allocator methods are allowed to be optimized out: GlobalAlloc in std::alloc - Rust

You may generally not rely on heap allocations happening if they can be removed without changing program behavior.

As far as I'm aware, it's impossible to implement an allocator without satisfying this condition. Note that the synchronizes-with relation is only established in the case of address reuse, and if an address is reused, the dealloc must be ordered before the alloc to ensure that accesses to the previously allocated place do not race with accesses to the newly allocated place.

Whether this strictly holds true depends on details of the memory model which aren't fully nailed down yet, namely whether non zero sized allocations can exist at the same address without aliasing. Relying on this ordering for synchronization of a resource other than the memory range itself is perhaps ill advised, but is likely to be valid.

(I am a member of T-opsem but am not speaking for the team or with any extra weight.)

2 Likes

Thank you for the answers.

@drewtato I agree with your line of reasoning

@CAD97 I interpreted "a part of the same region of memory" as something more than just pointer reuse.

Assume the main thread allocates the size of the entire heap (say size of the heap segment) in one go and frees it immediately. Then every thread allocating in the future has to synchronize with the main thread because it would allocate a part of the same region of memory.

As far as I'm aware, it's impossible to implement an allocator without satisfying this condition

How about an allocator with this behavior? If frees were a no-op, and each thread has a fixed region of the heap it uses for allocs, then I should be able to implement alloc and free without synchronization.

whether non zero sized allocations can exist at the same address without aliasing

Is there a scenario where overlapping-in-time non-ZST allocations can use the same address without aliasing?

I think when they say "part of the same region" they mean an overlapping range. So if you deallocate addresses 0-10 then allocate addresses 8-12, they need to synchronize. That would make separate pools for separate threads not apply.

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.