Пример #1
0
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
}
Пример #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();
    }
}
Пример #3
0
void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
{
  /* Is there a stack allocated? */

  if (dtcb->stack_alloc_ptr)
    {
#ifdef HAVE_KERNEL_HEAP
      /* Use the kernel allocator if this is a kernel thread */

      if (ttype == TCB_FLAG_TTYPE_KERNEL)
        {
          if (kmm_heapmember(dtcb->stack_alloc_ptr))
            {
              sched_kfree(dtcb->stack_alloc_ptr);
            }
        }
      else
#endif
        {
          /* Use the user-space allocator if this is a task or pthread */

          if (umm_heapmember(dtcb->stack_alloc_ptr))
            {
              sched_ufree(dtcb->stack_alloc_ptr);
            }
        }

      /* Mark the stack freed */

      dtcb->stack_alloc_ptr = NULL;
    }

  /* The size of the allocated stack is now zero */

  dtcb->adj_stack_size = 0;
}