How to use the cleanup functions

  1. 3 weeks ago

    Hello,

    i am using lfds711 queue bss but i have troubles freeing the allocated data.

    As i understood it, i need to call the lfds711_queue_bss_cleanup with a callback that will call free for each elements i allocated, however i keep getting segfault by doing that.

    Here is the simple implementation of my callbacks:

    void q_element_cleanup_callback(struct lfds711_queue_bss_state *qbsss, void *key, void *value) {
        free(value);
    }

    Initialization:

        struct lfds711_queue_bss_element *synth_commands_queue_element =
            aligned_alloc(fas_commands_queue_size, sizeof(struct lfds711_queue_bss_element) * fas_commands_queue_size);
        lfds711_queue_bss_init_valid_on_current_logical_core(&synth_commands_queue_state, synth_commands_queue_element, fas_commands_queue_size, NULL);

    Allocation:

    // usd->synth is allocated with a generic malloc just before this
    lfds711_queue_bss_enqueue(&synth_commands_queue_state, NULL, (void *)usd->synth);

    Maybe i misundertood how you can free the data, i am also using a freelist for the ringbuffer and calling lfds711_freelist_cleanup work fine so i just don't know why doing this just crash?

    Thank you for this great library btw.

  2. admin

    Feb 27 Administrator

    Hi, Mammoth.

    I may be wrong, but I think the problem you're running into with the queue is that when initializing, all of the store for queue elements is allocated in one single block of memory, but then when cleaning up, the cleanup function presents you with *each element* in turn.

    If you then try to free each element, it will crash, because what should actually be happening is that there is only a *single* call to free, which is passed the pointer to the single block of memory which was allocated when the queue was initialized.

    The cleanup function allows you if you need to, to perform cleanup work *related to whatever it is you were doing* - so, for example, say we were using the queue to buffer network packets or something like that, and when the application shut down, we want to handle all outstanding enqueued elements. In this case, the cleanup function lets us process the data in those elements.

    To actually free the memory of the queue elements, you keep track of the pointer to single allocation holding all the queue elements and free that after the queue cleanup function has returned.

    So in your case, once the queue cleanu has returned, you free "synth_commands_queue_element".

    Note however the queue only calls the cleanup function *for enqueue elements which are still in the queue*. It does NOT call the cleanup function with EVERY element which was given to the queue (when the queue was initialized).

    So if you have a malloc per queue element, you would for example after the queue cleanup function is called iterate over the elements in the single allocation of all elements and *there* call free() on usd->synth, for all of them, and not call free for that at all in the cleanup function, because f you did call free for usd->synth in the cleanup function, it would only be called on those queue elements which were still enqueued at the time the queue was cleanedup.

    Thankyou for your kind words about the library :-)

  3. 2 weeks ago

    Thank for the answer, somehow forgot how the whole thing worked! :)

 

or Sign Up to reply!