abl_heap.c

来自「SHARP_ARM720T_LH79524/5软件开发包_支持TFT_LCD_N」· C语言 代码 · 共 742 行 · 第 1/2 页

C
742
字号
                if (prev_ptr != HEAP_POINTER_NULL)
                {
                    prev_ptr->prev_descriptor = found_ptr;

                    /* Update size of this entry */
                    found_ptr->entry_size = (UNS_32) prev_ptr -
                        (UNS_32) found_ptr;
                }
                else
                {
                    /* This entry is the only entry in the list */
                    found_ptr->entry_size = heap_size_saved;
                }
            }
        }

        /* Last entry cases */
        else if (next_ptr == HEAP_POINTER_NULL)
        {
            prev_ptr = found_ptr->prev_descriptor;
            if (prev_ptr->entry_size == 0)
            {
                /* Previous descriptor is used, so just clear the
                   present entry */
                found_ptr->entry_size = 0;
            }
            else
            {
                /* Previous entry is not used, so merge this entry
                   and the previous entry */
                prev_ptr->entry_size = heap_size_saved -
                    ((UNS_32) prev_ptr - (UNS_32) heap_base);

                /* Previous entry is now the last entry */
                prev_ptr->next_descriptor = HEAP_POINTER_NULL;
            }
        }

        /* Other entry cases (not first or last entry) */
        else
        {
            prev_ptr = found_ptr->prev_descriptor;
            if ((prev_ptr->entry_size == 0) &&
                (next_ptr->entry_size == 0))
            {
                /* Both previous and next entries are allocated, so
                   just clear this entry */
                found_ptr->entry_size = (UNS_32) next_ptr -
                    (UNS_32) found_ptr;
            }
            else if ((prev_ptr->entry_size != 0) &&
                (next_ptr->entry_size == 0))
            {
                /* Previous entry not used, next entry is used, so
                   merge this entry and the previous entry */

                /* Point previous entry to next entry */
                prev_ptr->next_descriptor = next_ptr;

                /* Set previous entry's sze to include this size */
                prev_ptr->entry_size = (UNS_32) next_ptr -
                    (UNS_32) prev_ptr;

                /* Set next entry to point to new previous entry */
                next_ptr->prev_descriptor = prev_ptr;
            }
            else if ((prev_ptr->entry_size == 0) &&
                (next_ptr->entry_size != 0))
            {
                /* Previous entry used, next entry not used, so
                   merge this entry and the next entry */

                /* Does an entry exist after the next entry? */
                saved_ptr = next_ptr->next_descriptor;
                if (saved_ptr == HEAP_POINTER_NULL)
                {
                    /* No entry after the next entry, so this entry
                       will become the last entry */
                    found_ptr->entry_size = heap_size_saved -
                        ((UNS_32) found_ptr - (UNS_32) heap_base);
                    found_ptr->next_descriptor = HEAP_POINTER_NULL;
                }
                else
                {
                    /* An entry exists after the next entry, so
                       merge the two entries and update links */
                    found_ptr->entry_size =
                        (UNS_32) saved_ptr - (UNS_32) found_ptr;

                    /* Update next descriptor */
                    found_ptr->next_descriptor = saved_ptr;

                    /* Reset previous descriptor link */
                    saved_ptr->prev_descriptor = found_ptr;
                }
            }
            else
            {
                /* Previous and next entry are both not used, so
                   all three entries have to be merged */

                /* Does an entry exist after the next entry? */
                saved_ptr = next_ptr->next_descriptor;
                if (saved_ptr == HEAP_POINTER_NULL)
                {
                    /* No entry after the next entry, so this entry
                       will become the last entry */
                    prev_ptr->entry_size = heap_size_saved -
                        ((UNS_32) prev_ptr - (UNS_32) heap_base);
                    prev_ptr->next_descriptor = HEAP_POINTER_NULL;
                }
                else
                {
                    /* An entry exists after the next entry, so
                       merge all three entries and update links */
                    prev_ptr->entry_size = (UNS_32) saved_ptr -
                        (UNS_32) prev_ptr;

                    /* Update next and previous links */
                    prev_ptr->next_descriptor = saved_ptr;
                    saved_ptr->prev_descriptor = prev_ptr;
                }
            }
        }

        /* Return a good status */
        status = 1;
    }

    return status;
}

/***********************************************************************
 * Public functions
 **********************************************************************/

/***********************************************************************
 *
 * Function: abl_get_heapsize
 *
 * Purpose: Returns the size of the heap.
 *
 * Processing:
 *     See function.
 *
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: The size of the heap area in bytes.
 *
 * Notes: None
 *
 **********************************************************************/
UNS_32 abl_get_heapsize (void)
{
    return heap_size_saved;
}

/***********************************************************************
 *
 * Function: abl_get_largest_chunk
 *
 * Purpose:
 *     Returns the largest available chunk in the heap.
 *
 * Processing:
 *     This function traverses through the heap list. If an entry has an
 *     available size of greater than 0 bytes, then the entry is assumed
 *     as free and the size of the chunk is compared to the running size
 *     count. If the size is larger, the running size count is updated
 *     with the new size.
 *
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: The size of the largest chunk available in the heap area
 *          in bytes.
 *
 * Notes: None
 *
 **********************************************************************/
UNS_32 abl_get_largest_chunk (void)
{
    HEAP_DESCRIPTOR_T *heap_ptr;
    UNS_32 max_chunk_size = 0;

    /* Start at top of heap list */
    heap_ptr = heap_base;

    /* Go through all the entries */
    while (heap_ptr != HEAP_POINTER_NULL)
    {
        if (heap_ptr->entry_size > max_chunk_size)
        {
            /* This chunk is larger than the last saved chunk size */
            max_chunk_size = heap_ptr->entry_size;
        }

        /* Next heap entry */
        heap_ptr = heap_ptr->next_descriptor;
    }

    /* Largest available chunk size is adjusted by the required space
       needed for the heap descriptor */
    return max_chunk_size;
}

/***********************************************************************
 *
 * Function: abl_get_allocated_count
 *
 * Purpose:
 *     Return the number of allocated items in the heap.
 *
 * Processing:
 *     This function traverses through the heap list. If an entry has
 *     an available size of 0 bytes, then the entry is assumed as
 *     allocated and the allocated count is incremented.
 *
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: The number of allocated heap entries.
 *
 * Notes: None
 *
 **********************************************************************/
UNS_32 abl_get_allocated_count (void)
{
    HEAP_DESCRIPTOR_T *heap_ptr;
    UNS_32 heap_entries = 0;

    /* Start at top of heap list */
    heap_ptr = heap_base;

    /* Go through all the entries */
    while (heap_ptr != HEAP_POINTER_NULL)
    {
        if (heap_ptr->entry_size == 0)
        {
            /* This is an used chunk */
            heap_entries++;
        }

        /* Next heap entry */
        heap_ptr = heap_ptr->next_descriptor;
    }

    /* Largest available chunk size is adjusted by the required space
       needed for the heap descriptor */
    return heap_entries;
}

/***********************************************************************
 *
 * Function: abl_get_heap_base
 *
 * Purpose: Return the heap base address.
 *
 * Processing:
 *     See function.
 *
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: The base address of where heap memory starts.
 *
 * Notes: None
 *
 **********************************************************************/
void *abl_get_heap_base (void)
{
    return heap_base;
}

/***********************************************************************
 *
 * Function: abl_heap_init
 *
 * Purpose: Setup the heap area.
 *
 * Processing:
 *     The heap base address and size counters are set with the passed
 *     parameter values. The first entry of the heap is set up with an
 *     unallocated heap list entry.
 *
 * Parameters:
 *     base_addr : Base address of where heap starts
 *     heap_size : Size of heap area in bytes
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
void abl_heap_init (void *base_addr, UNS_32 heap_size)
{
    HEAP_DESCRIPTOR_T *heap_ptr;

    /* Save heap base address and size */
    heap_base = (HEAP_DESCRIPTOR_T *) base_addr;
    heap_size_saved = heap_size;

    /* Setup first link in heap list */
    heap_ptr = (HEAP_DESCRIPTOR_T *) base_addr;

   /* Setup next heap entry pointer */
    heap_ptr->next_descriptor = HEAP_POINTER_NULL;

    /* Previous entry just points to itself (end of list) */
    heap_ptr->prev_descriptor = base_addr;

    /* Size of heap area (not including the descriptor) */
    heap_ptr->entry_size = heap_size;
}

/***********************************************************************
 *
 * Function: abl_new
 *
 * Purpose: Get an allocated area from the heap.
 *
 * Processing:
 *     See function.
 *
 * Parameters:
 *     size_in_bytes : Byte size of the requested allocation chunk
 *
 * Outputs: None
 *
 * Returns: A pointer to the allocated chunk, or '0' if no room is
 *          available.
 *
 * Notes: None
 *
 **********************************************************************/
void *abl_new(UNS_32 size_in_bytes)
{
    return (void *) abl_heap_insert_entry(size_in_bytes);
}

/***********************************************************************
 *
 * Function: abl_free
 *
 * Purpose: Returns an allocated entry of memory to the heap.
 *
 * Processing:
 *     See function.
 *
 * Parameters:
 *     free_addr : Address of allocated entry to return to heap
 *
 * Outputs: None
 *
 * Returns: '1' if the entry was deleted, otherwise '0'.
 *
 * Notes: None
 *
 **********************************************************************/
INT_32 abl_free(void *free_addr)
{
    return abl_remove_entry(free_addr);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?