arximboldi / immer

Postmodern immutable and persistent data structures for C++ — value semantics at scale
https://sinusoid.es/immer
Boost Software License 1.0
2.48k stars 177 forks source link

free_list_heap_policy just uses debug_size_heap instead #286

Open colugomusic opened 1 month ago

colugomusic commented 1 month ago

I'm not sure if I am just being stupid but I can't figure out how to use immer's free list heap policy at all.

The implementation of free_list_heap_policy is:

template <typename Heap, std::size_t Limit = default_free_list_size>
struct free_list_heap_policy
{
    using type = debug_size_heap<Heap>;

    template <std::size_t Size>
    struct optimized
    {
        using type =
            split_heap<Size,
                       with_free_list_node<thread_local_free_list_heap<
                           Size,
                           Limit,
                           free_list_heap<Size, Limit, debug_size_heap<Heap>>>>,
                       debug_size_heap<Heap>>;
    };
};

This is very confusing because it seems optimized::type is not referenced anywhere else, so using free_list_heap_policy just results in debug_size_heap and so every deallocate simply calls delete, in both debug and release builds.

This means that immer's default memory policy doesn't use the free list (while the documentation sort of implies that it does.)

I'm also not sure if it is even possible to define a custom heap policy which actually uses the free list instead of debug_size_heap. If it is then the documentation doesn't show how to do it.

colugomusic commented 1 month ago

Alright I think I understand where my confusion is now. optimized::type is referenced, but only in rbts::node. It's not used in, for example, immer::box, which just uses heap::type instead.

The reason I am looking at this is since it has an atomic reference count, I thought I would be able to use immer::box to perform a kind of realtime-safe thread synchronization where I can allow the final reference to the object to go out of scope in the audio thread without worrying about a memory deallocation happening.

I assume I could achieve this by writing a custom memory policy which defines type as free_list_heap_policy::optimized::type and using that with box. Would that work? Is there some important reason why box does not use the free list by default?