Esempio n. 1
0
/*!
 * \brief Allocate a block from heap memory.
 *
 * This function simply calls NutHeapAlloc(). It overrides the function
 * of the runtime library, when the application is linked with nutcrt or
 * nutcrtf.
 *
 * \param len Size of the requested memory block.
 *
 * \return Pointer to the allocated memory block if the
 *         function is successful or NULL if the requested
 *         amount of memory is not available.
 */
void *dbg_malloc(size_t len, CONST char *file, int line)
{
    void *p;

    if ((p = NutHeapDebugRootAlloc(&heapFreeList, len, file, line)) == NULL) {
        errno = ENOMEM;
    }
    return p;
}
Esempio n. 2
0
void *NutHeapDebugRootAllocClear(HEAPNODE ** root, size_t size, const char *file, int line)
{
    void *ptr;

    if ((ptr = NutHeapDebugRootAlloc(root, size, file, line)) != 0)
        memset(ptr, 0, size);

    return ptr;
}
Esempio n. 3
0
void *NutHeapRootRealloc(HEAPNODE ** root, void *block, size_t size)
#endif
{
    HEAPNODE *node;
    HEAPNODE **npp;
    HEAPNODE *fnode;
    void *newmem;

#ifdef NUTDEBUG_HEAP
    /* With NULL pointer the call is equivalent to alloc. */
    if (block == NULL) {
        return NutHeapDebugRootAlloc(root, size, file, line);
    }
    /* With zero size the call is equivalent to free. */
    if (size == 0) {
        if (NutHeapDebugRootFree(root, block, file, line)) {
            return NULL;
        }
        return block;
    }

    /* Revive our node pointer. */
    fnode = (HEAPNODE *) ((uintptr_t) block - (NUT_HEAP_OVERHEAD + NUTMEM_GUARD_BYTES));

    /* Sanity check. */
    if (DebugValidateUserArea(fnode, file, line)) {
        return NULL;
    }
#else
    if (block == NULL) {
        return NutHeapRootAlloc(root, size);
    }
    if (size == 0) {
        if (NutHeapRootFree(root, block)) {
            return NULL;
        }
        return block;
    }
    fnode = (HEAPNODE *) ((uintptr_t) block - (NUT_HEAP_OVERHEAD + NUTMEM_GUARD_BYTES));
    if (ValidateUserArea(fnode)) {
        return NULL;
    }
#endif

    /* Determine the minimum size. Add optional guard and alignment bytes.
       Make sure that a HEAPNODE structure fits. */
    size += NUT_HEAP_OVERHEAD + NUTMEM_GUARD_BYTES * 2;
    if (size < sizeof(HEAPNODE)) {
        size = sizeof(HEAPNODE);
    }
    size = NUTMEM_TOP_ALIGN(size);

    /*
     * Expansion.
     */
    if (size > fnode->hn_size) {
        size_t size_miss = size - fnode->hn_size;

        /* Find the free node following next. */
        node = *root;
        npp = root;
        while (node && node < fnode) {
            npp = &node->hn_next;
            node = node->hn_next;
        }

        /* If we found a node and if this node is large enough and
           if it directly follows without a gap, then use it. */
        if (node && node->hn_size >= size_miss &&       /* */
            (uintptr_t) fnode + fnode->hn_size == (uintptr_t) node) {
            /* Check if the following node is large enough to be split. */
            if (node->hn_size - size_miss >= NUTMEM_HEAPNODE_MIN) {
                /* Adjust the allocated size. */
                fnode->hn_size += size_miss;
                /* Insert the remaining part into the free list. */
                *npp = (HEAPNODE *) ((uintptr_t) node + size_miss);
                /* Due to possible overlapping it is important to set
                   the pointer first, then the size. */
                (*npp)->hn_next = node->hn_next;
                (*npp)->hn_size = node->hn_size - size_miss;
                PrepareUserArea(fnode);
            } else {
                /* Adjust the allocated size. */
                fnode->hn_size += node->hn_size;
                PrepareUserArea(fnode);
                /* Remove the merged node from the free list. */
                *npp = node->hn_next;
            }
            /* Return the original pointer. */
            return block;
        }

        /* Relocate if no sufficiently large block follows. */
#ifdef NUTDEBUG_HEAP
        newmem = NutHeapDebugRootAlloc(root, size, file, line);
#else
        newmem = NutHeapRootAlloc(root, size);
#endif
        if (newmem) {
            memcpy(newmem, block,
                fnode->hn_size - NUT_HEAP_OVERHEAD - 2 * NUTMEM_GUARD_BYTES);
#ifdef NUTDEBUG_HEAP
            NutHeapDebugRootFree(root, block, file, line);
#else
            NutHeapRootFree(root, block);
#endif
        }
        return newmem;
    }

    /*
     * Reduction.
     */
    if (size < fnode->hn_size - NUTMEM_HEAPNODE_MIN) {
        /* Release the remaining part to the free list. */
        node = (HEAPNODE *) ((uintptr_t) fnode + size);
        node->hn_size = fnode->hn_size - size;
#ifdef NUTDEBUG_HEAP
        NutHeapDebugRootFree(root, PrepareUserArea(node), NULL, 0);
#else
        NutHeapRootFree(root, PrepareUserArea(node));
#endif
        /* Adjust the allocated size. */
        fnode->hn_size = size;
        PrepareUserArea(fnode);
    }
    return block;
}