diff options
| author | [email protected] <[email protected]> | 2012-12-29 12:29:03 +0000 |
|---|---|---|
| committer | [email protected] <[email protected]> | 2012-12-29 12:29:03 +0000 |
| commit | 975610477e9b168858f90cc399d91eb962072f1d (patch) | |
| tree | b4b9dab47aea9f00c3b89291e030567331fee572 /src | |
| parent | 7db8d2939bf9833587fcff84f040a8e4f9410e6f (diff) | |
Add RT_USING_MEMHEAP_AS_HEAP feature: system can use "heap" memheap as system default memory heap.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2554 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'src')
| -rw-r--r-- | src/SConscript | 2 | ||||
| -rw-r--r-- | src/idle.c | 3 | ||||
| -rw-r--r-- | src/mem.c | 6 | ||||
| -rw-r--r-- | src/memheap.c | 162 | ||||
| -rw-r--r-- | src/scheduler.c | 2 | ||||
| -rw-r--r-- | src/thread.c | 3 |
6 files changed, 152 insertions, 26 deletions
diff --git a/src/SConscript b/src/SConscript index f9c7de573d..0eda61b1ef 100644 --- a/src/SConscript +++ b/src/SConscript @@ -24,6 +24,8 @@ if GetDepend('RT_USING_MEMPOOL') == False: if GetDepend('RT_USING_MEMHEAP') == False: SrcRemove(src, ['memheap.c']) + if GetDepend('RT_USING_MEMHEAP_AS_HEAP'): + SrcRemove(src, ['mem.c']) if GetDepend('RT_USING_DEVICE') == False: SrcRemove(src, ['device.c']) diff --git a/src/idle.c b/src/idle.c index 083b180fe6..f03b53724d 100644 --- a/src/idle.c +++ b/src/idle.c @@ -11,6 +11,7 @@ * Date Author Notes * 2006-03-23 Bernard the first version * 2010-11-10 Bernard add cleanup callback function in thread exit. + * 2012-12-29 Bernard fix compiling warning. */ #include <rthw.h> @@ -46,7 +47,7 @@ static void (*rt_thread_idle_hook)(); * * @note the hook function must be simple and never be blocked or suspend. */ -void rt_thread_idle_sethook(void (*hook)()) +void rt_thread_idle_sethook(void (*hook)(void)) { rt_thread_idle_hook = hook; } @@ -52,6 +52,8 @@ #include <rthw.h> #include <rtthread.h> +#ifndef RT_USING_MEMHEAP_AS_HEAP + /* #define RT_MEM_DEBUG */ #define RT_MEM_STATS @@ -574,4 +576,6 @@ FINSH_FUNCTION_EXPORT(list_mem, list memory usage information) /*@}*/ -#endif +#endif /* end of RT_USING_HEAP */ +#endif /* end of RT_USING_MEMHEAP_AS_HEAP */ + diff --git a/src/memheap.c b/src/memheap.c index 03f67fd0ad..32f68bc622 100644 --- a/src/memheap.c +++ b/src/memheap.c @@ -11,8 +11,11 @@ * Date Author Notes * 2012-04-10 Bernard first implementation * 2012-10-16 Bernard add the mutex lock for heap object. + * 2012-12-29 Bernard memheap can be used as system heap. + * change mutex lock to semaphore lock. */ +#include <rthw.h> #include <rtthread.h> #ifdef RT_USING_MEMHEAP @@ -26,7 +29,8 @@ #define RT_MEMHEAP_IS_USED(i) ((i)->magic & RT_MEMHEAP_USED) #define RT_MEMHEAP_MINIALLOC 12 -#define RT_MEMHEAP_SIZE RT_ALIGN(sizeof(struct rt_memheap_item), RT_ALIGN_SIZE) +#define RT_MEMHEAP_SIZE RT_ALIGN(sizeof(struct rt_memheap_item), RT_ALIGN_SIZE) +#define MEMITEM_SIZE(item) ((rt_uint32_t)item->next - (rt_uint32_t)item - RT_MEMHEAP_SIZE) /* * The initialized memory pool will be: @@ -54,6 +58,7 @@ rt_err_t rt_memheap_init(struct rt_memheap *memheap, memheap->start_addr = start_addr; memheap->pool_size = RT_ALIGN_DOWN(size, RT_ALIGN_SIZE); memheap->available_size = memheap->pool_size - (2 * RT_MEMHEAP_SIZE); + memheap->max_used_size = memheap->pool_size - memheap->available_size; /* initialize the free list header */ item = &(memheap->free_header); @@ -101,8 +106,8 @@ rt_err_t rt_memheap_init(struct rt_memheap *memheap, /* not in free list */ item->next_free = item->prev_free = RT_NULL; - /* initialize mutex lock */ - rt_mutex_init(&(memheap->lock), name, RT_IPC_FLAG_FIFO); + /* initialize semaphore lock */ + rt_sem_init(&(memheap->lock), name, 1, RT_IPC_FLAG_FIFO); RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("memory heap: start addr 0x%08x, size %d, free list header 0x%08x", @@ -137,7 +142,7 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_uint32_t size) if (size < RT_MEMHEAP_MINIALLOC) size = RT_MEMHEAP_MINIALLOC; - RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("allocate %d", size)); + RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("allocate %d on heap:%8.*s", size, RT_NAME_MAX, heap->parent.name)); if (size < heap->available_size) { @@ -145,7 +150,7 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_uint32_t size) free_size = 0; /* lock memheap */ - result = rt_mutex_take(&(heap->lock), RT_WAITING_FOREVER); + result = rt_sem_take(&(heap->lock), RT_WAITING_FOREVER); if (result != RT_EOK) { rt_set_errno(result); @@ -184,7 +189,7 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_uint32_t size) (((rt_uint8_t *)header_ptr) + size + RT_MEMHEAP_SIZE); RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, - ("split: h[0x%08x] nm[0x%08x] pm[0x%08x] to n[0x%08x]", + ("split: block[0x%08x] nextm[0x%08x] prevm[0x%08x] to new[0x%08x]", header_ptr, header_ptr->next, header_ptr->prev, @@ -213,7 +218,7 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_uint32_t size) 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 ptr: nf 0x%08x, pf 0x%08x", + RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new ptr: next_free 0x%08x, prev_free 0x%08x", new_ptr->next_free, new_ptr->prev_free)); @@ -221,15 +226,19 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_uint32_t size) heap->available_size = heap->available_size - size - RT_MEMHEAP_SIZE; + if (heap->pool_size - heap->available_size > heap->max_used_size) + heap->max_used_size = heap->pool_size - heap->available_size; } else { /* decrement the entire free size from the available bytes count. */ heap->available_size = heap->available_size - free_size; + if (heap->pool_size - heap->available_size > heap->max_used_size) + heap->max_used_size = heap->pool_size - heap->available_size; /* remove header_ptr from free list */ RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, - ("one block: h[0x%08x], nf 0x%08x, pf 0x%08x", + ("one block: block[0x%08x], next_free 0x%08x, prev_free 0x%08x", header_ptr, header_ptr->next_free, header_ptr->prev_free)); @@ -240,15 +249,15 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_uint32_t size) header_ptr->prev_free = RT_NULL; } - /* release lock */ - rt_mutex_release(&(heap->lock)); - /* Mark the allocated block as not available. */ header_ptr->magic |= RT_MEMHEAP_USED; + /* release lock */ + rt_sem_release(&(heap->lock)); + /* Return a memory address to the caller. */ RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, - ("am: m[0x%08x], h[0x%08x], size: %d", + ("alloc mem: memory[0x%08x], heap[0x%08x], size: %d", (void *)((rt_uint8_t *)header_ptr + RT_MEMHEAP_SIZE), header_ptr, size); @@ -257,7 +266,7 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_uint32_t size) } /* release lock */ - rt_mutex_release(&(heap->lock)); + rt_sem_release(&(heap->lock)); } RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("allocate memory: failed\n")); @@ -280,7 +289,7 @@ void rt_memheap_free(void *ptr) header_ptr = (struct rt_memheap_item *)((rt_uint8_t *)ptr - RT_MEMHEAP_SIZE); - RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("free memory: m[0x%08x], h[0x%08x]", + RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("free memory: memory[0x%08x], block[0x%08x]", ptr, header_ptr)); /* check magic */ @@ -290,7 +299,7 @@ void rt_memheap_free(void *ptr) heap = header_ptr->pool_ptr; /* lock memheap */ - result = rt_mutex_take(&(heap->lock), RT_WAITING_FOREVER); + result = rt_sem_take(&(heap->lock), RT_WAITING_FOREVER); if (result != RT_EOK) { rt_set_errno(result); @@ -302,10 +311,7 @@ void rt_memheap_free(void *ptr) header_ptr->magic &= ~RT_MEMHEAP_USED; /* Adjust the available number of bytes. */ - heap->available_size = - heap->available_size + - ((rt_uint32_t)(header_ptr->next) - (rt_uint32_t)header_ptr) - - RT_MEMHEAP_SIZE; + heap->available_size = heap->available_size + MEMITEM_SIZE(header_ptr); /* Determine if the block can be merged with the previous neighbor. */ if (!RT_MEMHEAP_IS_USED(header_ptr->prev)) @@ -336,7 +342,7 @@ void rt_memheap_free(void *ptr) new_ptr = header_ptr->next; RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, - ("merge: right node 0x%08x, nf 0x%08x, pf 0x%08x", + ("merge: right node 0x%08x, next_free 0x%08x, prev_free 0x%08x", new_ptr, new_ptr->next_free, new_ptr->prev_free)); new_ptr->next->prev = header_ptr; @@ -356,13 +362,125 @@ void rt_memheap_free(void *ptr) heap->free_list->next_free = header_ptr; RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, - ("insert to free list: nf 0x%08x, pf 0x%08x", + ("insert to free list: next_free 0x%08x, prev_free 0x%08x", header_ptr->next_free, header_ptr->prev_free)); } /* release lock */ - rt_mutex_release(&(heap->lock)); + rt_sem_release(&(heap->lock)); } RTM_EXPORT(rt_memheap_free); +#ifdef RT_USING_MEMHEAP_AS_HEAP +static struct rt_memheap _heap; + +void rt_system_heap_init(void *begin_addr, void *end_addr) +{ + /* initialize a default heap in the system */ + rt_memheap_init(&_heap, "heap", begin_addr, (rt_uint32_t)end_addr - (rt_uint32_t)begin_addr); +} + +void *rt_malloc(rt_size_t size) +{ + void* ptr; + + /* try to allocate in system heap */ + ptr = rt_memheap_alloc(&_heap, size); + if (ptr == RT_NULL) + { + struct rt_object *object; + struct rt_list_node *node; + struct rt_memheap *heap; + struct rt_object_information *information; + extern struct rt_object_information rt_object_container[]; + + /* try to allocate on other memory heap */ + information = &rt_object_container[RT_Object_Class_MemHeap]; + for (node = information->object_list.next; node != &(information->object_list); node = node->next) + { + object = rt_list_entry(node, struct rt_object, list); + heap = (struct rt_memheap*) object; + + /* not allocate in the default system heap */ + if (heap == &_heap) continue; + + ptr = rt_memheap_alloc(heap, size); + if (ptr != RT_NULL) break; + } + } + + return ptr; +} +RTM_EXPORT(rt_malloc); + +void rt_free(void *rmem) +{ + rt_memheap_free(rmem); +} +RTM_EXPORT(rt_free); + +void *rt_realloc(void *rmem, rt_size_t newsize) +{ + rt_size_t size; + void *nmem = RT_NULL; + struct rt_memheap_item *header_ptr; + + RT_DEBUG_NOT_IN_INTERRUPT; + + /* alignment size */ + newsize = RT_ALIGN(newsize, RT_ALIGN_SIZE); + + /* allocate a memory */ + if (rmem == RT_NULL) + { + return rt_malloc(newsize); + } + + /* release memory */ + if (newsize == 0) + { + rt_free(rmem); + return RT_NULL; + } + + /* get old memory item */ + header_ptr = (struct rt_memheap_item *)((rt_uint8_t *)rmem - RT_MEMHEAP_SIZE); + size = MEMITEM_SIZE(header_ptr); + if (newsize > size || newsize < size - RT_MEMHEAP_SIZE) /* re-allocate memory */ + { + /* re-allocate a memory block */ + nmem = (void*)rt_malloc(newsize); + if (nmem != RT_NULL) + { + rt_memcpy(nmem, rmem, size < newsize ? size : newsize); + rt_free(rmem); + } + + return nmem; + } + + /* use the old memory block */ + return rmem; +} +RTM_EXPORT(rt_realloc); + +void *rt_calloc(rt_size_t count, rt_size_t size) +{ + void *ptr; + rt_size_t total_size; + + total_size = count * size; + ptr = rt_malloc(total_size); + if (ptr != RT_NULL) + { + /* clean memory */ + rt_memset(ptr, 0, total_size); + } + + return ptr; +} +RTM_EXPORT(rt_calloc); + +#endif + #endif diff --git a/src/scheduler.c b/src/scheduler.c index dc66380e45..03423c9f5d 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -268,7 +268,7 @@ void rt_schedule(void) /* if the destination thread is not the same as current thread */ if (to_thread != rt_current_thread) { - rt_current_priority = highest_ready_priority; + rt_current_priority = (rt_uint8_t)highest_ready_priority; from_thread = rt_current_thread; rt_current_thread = to_thread; diff --git a/src/thread.c b/src/thread.c index 942136adaf..6a0927eb0b 100644 --- a/src/thread.c +++ b/src/thread.c @@ -24,6 +24,7 @@ * 2011-09-01 Bernard fixed rt_thread_exit issue when the current * thread preempted, which reported by Jiaxing Lee. * 2011-09-08 Bernard fixed the scheduling issue in rt_thread_startup. + * 2012-12-29 Bernard fixed compiling warning. */ #include <rtthread.h> @@ -88,7 +89,7 @@ static rt_err_t _rt_thread_init(struct rt_thread *thread, /* stack init */ thread->stack_addr = stack_start; - thread->stack_size = stack_size; + thread->stack_size = (rt_uint16_t)stack_size; /* init thread stack */ rt_memset(thread->stack_addr, '#', thread->stack_size); |
