parent
3359419d4f
commit
86db9ed965
197
src/memheap.c
197
src/memheap.c
|
@ -286,36 +286,37 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_uint32_t size)
|
||||||
}
|
}
|
||||||
RTM_EXPORT(rt_memheap_alloc);
|
RTM_EXPORT(rt_memheap_alloc);
|
||||||
|
|
||||||
void *rt_memheap_realloc(struct rt_memheap* heap, void* ptr, rt_size_t newsize)
|
void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize)
|
||||||
{
|
{
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
rt_size_t oldsize;
|
rt_size_t oldsize;
|
||||||
struct rt_memheap_item *header_ptr;
|
struct rt_memheap_item *header_ptr;
|
||||||
struct rt_memheap_item *new_ptr;
|
struct rt_memheap_item *new_ptr;
|
||||||
|
|
||||||
if (newsize == 0)
|
if (newsize == 0)
|
||||||
{
|
{
|
||||||
rt_memheap_free(ptr);
|
rt_memheap_free(ptr);
|
||||||
return RT_NULL;
|
|
||||||
}
|
|
||||||
/* align allocated size */
|
|
||||||
newsize = RT_ALIGN(newsize, RT_ALIGN_SIZE);
|
|
||||||
if (newsize < RT_MEMHEAP_MINIALLOC)
|
|
||||||
newsize = RT_MEMHEAP_MINIALLOC;
|
|
||||||
|
|
||||||
if (ptr == RT_NULL)
|
return RT_NULL;
|
||||||
{
|
}
|
||||||
return rt_memheap_alloc(heap, newsize);
|
/* align allocated size */
|
||||||
}
|
newsize = RT_ALIGN(newsize, RT_ALIGN_SIZE);
|
||||||
|
if (newsize < RT_MEMHEAP_MINIALLOC)
|
||||||
|
newsize = RT_MEMHEAP_MINIALLOC;
|
||||||
|
|
||||||
/* get memory block header and get the size of memory block */
|
if (ptr == RT_NULL)
|
||||||
header_ptr = (struct rt_memheap_item*)((rt_uint8_t *)ptr -
|
{
|
||||||
RT_MEMHEAP_SIZE);
|
return rt_memheap_alloc(heap, newsize);
|
||||||
oldsize = MEMITEM_SIZE(header_ptr);
|
}
|
||||||
|
|
||||||
|
/* get memory block header and get the size of memory block */
|
||||||
|
header_ptr = (struct rt_memheap_item *)
|
||||||
|
((rt_uint8_t *)ptr - RT_MEMHEAP_SIZE);
|
||||||
|
oldsize = MEMITEM_SIZE(header_ptr);
|
||||||
/* re-allocate memory */
|
/* re-allocate memory */
|
||||||
if (newsize > oldsize)
|
if (newsize > oldsize)
|
||||||
{
|
{
|
||||||
void* new_ptr;
|
void* new_ptr;
|
||||||
/* re-allocate a memory block */
|
/* re-allocate a memory block */
|
||||||
new_ptr = (void*)rt_memheap_alloc(heap, newsize);
|
new_ptr = (void*)rt_memheap_alloc(heap, newsize);
|
||||||
if (new_ptr != RT_NULL)
|
if (new_ptr != RT_NULL)
|
||||||
|
@ -327,74 +328,75 @@ void *rt_memheap_realloc(struct rt_memheap* heap, void* ptr, rt_size_t newsize)
|
||||||
return new_ptr;
|
return new_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* lock memheap */
|
/* lock memheap */
|
||||||
result = rt_sem_take(&(heap->lock), RT_WAITING_FOREVER);
|
result = rt_sem_take(&(heap->lock), RT_WAITING_FOREVER);
|
||||||
if (result != RT_EOK)
|
if (result != RT_EOK)
|
||||||
{
|
{
|
||||||
rt_set_errno(result);
|
rt_set_errno(result);
|
||||||
return RT_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* split the block. */
|
return RT_NULL;
|
||||||
new_ptr = (struct rt_memheap_item *)
|
}
|
||||||
(((rt_uint8_t *)header_ptr) + newsize + RT_MEMHEAP_SIZE);
|
|
||||||
|
|
||||||
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
|
/* split the block. */
|
||||||
("split: block[0x%08x] nextm[0x%08x] prevm[0x%08x] to new[0x%08x]",
|
new_ptr = (struct rt_memheap_item *)
|
||||||
header_ptr,
|
(((rt_uint8_t *)header_ptr) + newsize + RT_MEMHEAP_SIZE);
|
||||||
header_ptr->next,
|
|
||||||
header_ptr->prev,
|
|
||||||
new_ptr));
|
|
||||||
|
|
||||||
/* mark the new block as a memory block and freed. */
|
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
|
||||||
new_ptr->magic = RT_MEMHEAP_MAGIC;
|
("split: block[0x%08x] nextm[0x%08x] prevm[0x%08x] to new[0x%08x]",
|
||||||
/* put the pool pointer into the new block. */
|
header_ptr,
|
||||||
new_ptr->pool_ptr = heap;
|
header_ptr->next,
|
||||||
|
header_ptr->prev,
|
||||||
|
new_ptr));
|
||||||
|
|
||||||
/* break down the block list */
|
/* mark the new block as a memory block and freed. */
|
||||||
new_ptr->prev = header_ptr;
|
new_ptr->magic = RT_MEMHEAP_MAGIC;
|
||||||
new_ptr->next = header_ptr->next;
|
/* put the pool pointer into the new block. */
|
||||||
header_ptr->next->prev = new_ptr;
|
new_ptr->pool_ptr = heap;
|
||||||
header_ptr->next = new_ptr;
|
|
||||||
|
|
||||||
/* determine if the block can be merged with the next neighbor. */
|
/* break down the block list */
|
||||||
if (!RT_MEMHEAP_IS_USED(new_ptr->next))
|
new_ptr->prev = header_ptr;
|
||||||
{
|
new_ptr->next = header_ptr->next;
|
||||||
struct rt_memheap_item *free_ptr;
|
header_ptr->next->prev = new_ptr;
|
||||||
|
header_ptr->next = new_ptr;
|
||||||
|
|
||||||
/* merge block with next neighbor. */
|
/* determine if the block can be merged with the next neighbor. */
|
||||||
free_ptr = new_ptr->next;
|
if (!RT_MEMHEAP_IS_USED(new_ptr->next))
|
||||||
heap->available_size = heap->available_size - MEMITEM_SIZE(free_ptr);
|
{
|
||||||
|
struct rt_memheap_item *free_ptr;
|
||||||
|
|
||||||
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
|
/* merge block with next neighbor. */
|
||||||
("merge: right node 0x%08x, next_free 0x%08x, prev_free 0x%08x",
|
free_ptr = new_ptr->next;
|
||||||
header_ptr, header_ptr->next_free, header_ptr->prev_free));
|
heap->available_size = heap->available_size - MEMITEM_SIZE(free_ptr);
|
||||||
|
|
||||||
free_ptr->next->prev = new_ptr;
|
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
|
||||||
new_ptr->next = free_ptr->next;
|
("merge: right node 0x%08x, next_free 0x%08x, prev_free 0x%08x",
|
||||||
|
header_ptr, header_ptr->next_free, header_ptr->prev_free));
|
||||||
|
|
||||||
/* remove free ptr from free list */
|
free_ptr->next->prev = new_ptr;
|
||||||
free_ptr->next_free->prev_free = free_ptr->prev_free;
|
new_ptr->next = free_ptr->next;
|
||||||
free_ptr->prev_free->next_free = free_ptr->next_free;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* insert the split block to free list */
|
/* remove free ptr from free list */
|
||||||
new_ptr->next_free = heap->free_list->next_free;
|
free_ptr->next_free->prev_free = free_ptr->prev_free;
|
||||||
new_ptr->prev_free = heap->free_list;
|
free_ptr->prev_free->next_free = free_ptr->next_free;
|
||||||
heap->free_list->next_free->prev_free = new_ptr;
|
}
|
||||||
heap->free_list->next_free = new_ptr;
|
|
||||||
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new free ptr: next_free 0x%08x, prev_free 0x%08x",
|
|
||||||
new_ptr->next_free,
|
|
||||||
new_ptr->prev_free));
|
|
||||||
|
|
||||||
/* increment the available byte count. */
|
/* insert the split block to free list */
|
||||||
heap->available_size = heap->available_size + MEMITEM_SIZE(new_ptr);
|
new_ptr->next_free = heap->free_list->next_free;
|
||||||
|
new_ptr->prev_free = heap->free_list;
|
||||||
|
heap->free_list->next_free->prev_free = new_ptr;
|
||||||
|
heap->free_list->next_free = new_ptr;
|
||||||
|
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new free ptr: next_free 0x%08x, prev_free 0x%08x",
|
||||||
|
new_ptr->next_free,
|
||||||
|
new_ptr->prev_free));
|
||||||
|
|
||||||
|
/* increment the available byte count. */
|
||||||
|
heap->available_size = heap->available_size + MEMITEM_SIZE(new_ptr);
|
||||||
|
|
||||||
/* release lock */
|
/* release lock */
|
||||||
rt_sem_release(&(heap->lock));
|
rt_sem_release(&(heap->lock));
|
||||||
|
|
||||||
/* return the old memory block */
|
/* return the old memory block */
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
RTM_EXPORT(rt_memheap_realloc);
|
RTM_EXPORT(rt_memheap_realloc);
|
||||||
|
|
||||||
|
@ -408,8 +410,8 @@ void rt_memheap_free(void *ptr)
|
||||||
/* set initial status as OK */
|
/* set initial status as OK */
|
||||||
insert_header = 1;
|
insert_header = 1;
|
||||||
new_ptr = RT_NULL;
|
new_ptr = RT_NULL;
|
||||||
header_ptr = (struct rt_memheap_item *)((rt_uint8_t *)ptr -
|
header_ptr = (struct rt_memheap_item *)
|
||||||
RT_MEMHEAP_SIZE);
|
((rt_uint8_t *)ptr - RT_MEMHEAP_SIZE);
|
||||||
|
|
||||||
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("free memory: memory[0x%08x], block[0x%08x]",
|
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("free memory: memory[0x%08x], block[0x%08x]",
|
||||||
ptr, header_ptr));
|
ptr, header_ptr));
|
||||||
|
@ -425,6 +427,7 @@ void rt_memheap_free(void *ptr)
|
||||||
if (result != RT_EOK)
|
if (result != RT_EOK)
|
||||||
{
|
{
|
||||||
rt_set_errno(result);
|
rt_set_errno(result);
|
||||||
|
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,31 +551,35 @@ RTM_EXPORT(rt_free);
|
||||||
|
|
||||||
void *rt_realloc(void *rmem, rt_size_t newsize)
|
void *rt_realloc(void *rmem, rt_size_t newsize)
|
||||||
{
|
{
|
||||||
void *new_ptr;
|
void *new_ptr;
|
||||||
struct rt_memheap_item *header_ptr;
|
struct rt_memheap_item *header_ptr;
|
||||||
|
|
||||||
if (rmem == RT_NULL) return rt_malloc(newsize);
|
if (rmem == RT_NULL)
|
||||||
|
return rt_malloc(newsize);
|
||||||
|
|
||||||
/* get old memory item */
|
/* get old memory item */
|
||||||
header_ptr = (struct rt_memheap_item *)((rt_uint8_t *)rmem - RT_MEMHEAP_SIZE);
|
header_ptr = (struct rt_memheap_item *)
|
||||||
|
((rt_uint8_t *)rmem - RT_MEMHEAP_SIZE);
|
||||||
|
|
||||||
new_ptr = rt_memheap_realloc(header_ptr->pool_ptr, rmem, newsize);
|
new_ptr = rt_memheap_realloc(header_ptr->pool_ptr, rmem, newsize);
|
||||||
if (new_ptr == RT_NULL && newsize != 0)
|
if (new_ptr == RT_NULL && newsize != 0)
|
||||||
{
|
{
|
||||||
/* allocate memory block from other memheap */
|
/* allocate memory block from other memheap */
|
||||||
new_ptr = rt_malloc(newsize);
|
new_ptr = rt_malloc(newsize);
|
||||||
if (new_ptr != RT_NULL && rmem != RT_NULL)
|
if (new_ptr != RT_NULL && rmem != RT_NULL)
|
||||||
{
|
{
|
||||||
rt_size_t oldsize;
|
rt_size_t oldsize;
|
||||||
|
|
||||||
/* get the size of old memory block */
|
/* get the size of old memory block */
|
||||||
oldsize = MEMITEM_SIZE(header_ptr);
|
oldsize = MEMITEM_SIZE(header_ptr);
|
||||||
if (newsize > oldsize) rt_memcpy(new_ptr, rmem, oldsize);
|
if (newsize > oldsize)
|
||||||
else rt_memcpy(new_ptr, rmem, newsize);
|
rt_memcpy(new_ptr, rmem, oldsize);
|
||||||
}
|
else
|
||||||
}
|
rt_memcpy(new_ptr, rmem, newsize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new_ptr;
|
return new_ptr;
|
||||||
}
|
}
|
||||||
RTM_EXPORT(rt_realloc);
|
RTM_EXPORT(rt_realloc);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue