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 }
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(); } }