void sched_ufree(FAR void *address)
{
#ifdef CONFIG_BUILD_KERNEL
    /* REVISIT:  It is not safe to defer user allocation in the kernel mode
     * build.  Why?  Because the correct user context is in place now but
     * will not be in place when the deferred de-allocation is performed.  In
     * order to make this work, we would need to do something like:  (1) move
     * g_delayed_kufree into the group structure, then traverse the groups to
     * collect garbage on a group-by-group basis.
     */

    ASSERT(!up_interrupt_context());
    kumm_free(address);

#else
    /* Check if this is an attempt to deallocate memory from an exception
     * handler.  If this function is called from the IDLE task, then we
     * must have exclusive access to the memory manager to do this.
     */

    if (up_interrupt_context() || kumm_trysemaphore() != 0)
    {
        irqstate_t flags;

        /* Yes.. Make sure that this is not a attempt to free kernel memory
         * using the user deallocator.
         */

        flags = irqsave();
#if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \
     defined(CONFIG_MM_KERNEL_HEAP)
        DEBUGASSERT(!kmm_heapmember(address));
#endif

        /* Delay the deallocation until a more appropriate time. */

        sq_addlast((FAR sq_entry_t *)address,
                   (FAR sq_queue_t *)&g_delayed_kufree);

        /* Signal the worker thread that is has some clean up to do */

#ifdef CONFIG_SCHED_WORKQUEUE
        work_signal(LPWORK);
#endif
        irqrestore(flags);
    }
    else
    {
        /* No.. just deallocate the memory now. */

        kumm_free(address);
        kumm_givesemaphore();
    }
#endif
}
Exemple #2
0
void sched_ufree(FAR void *address)
{
    irqstate_t flags;

    /* Check if this is an attempt to deallocate memory from an exception
     * handler.  If this function is called from the IDLE task, then we
     * must have exclusive access to the memory manager to do this.
     */

    if (up_interrupt_context() || kumm_trysemaphore() != 0)
    {
        /* Yes.. Make sure that this is not a attempt to free kernel memory
         * using the user deallocator.
         */

        flags = irqsave();
#if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \
     defined(CONFIG_MM_KERNEL_HEAP)
        DEBUGASSERT(!kmm_heapmember(address));
#endif

        /* Delay the deallocation until a more appropriate time. */

        sq_addlast((FAR sq_entry_t*)address, (sq_queue_t*)&g_delayed_kufree);

        /* Signal the worker thread that is has some clean up to do */

#ifdef CONFIG_SCHED_WORKQUEUE
        work_signal(LPWORK);
#endif
        irqrestore(flags);
    }
    else
    {
        /* No.. just deallocate the memory now. */

        kumm_free(address);
        kumm_givesemaphore();
    }
}