From cea21370a40d8b9ace858c477d5cedf214cdf520 Mon Sep 17 00:00:00 2001 From: "qiuyiuestc@gmail.com" Date: Mon, 4 Jul 2011 23:48:07 +0000 Subject: [PATCH] rewrite module memory allocator git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1618 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- include/rtdef.h | 4 +- include/rtthread.h | 6 + src/idle.c | 6 +- src/ipc.c | 4 +- src/mempool.c | 2 +- src/module.c | 470 ++++++++++++++++++++++++++++++---------- src/object.c | 2 +- src/rtm.c | 527 +++++++++++++++++++++++---------------------- src/slab.c | 59 ++--- 9 files changed, 653 insertions(+), 427 deletions(-) diff --git a/include/rtdef.h b/include/rtdef.h index e1dddcdcc2..2b60914e46 100644 --- a/include/rtdef.h +++ b/include/rtdef.h @@ -759,8 +759,8 @@ struct rt_module /* module memory allocator */ void* mem_list; /**< module's free memory list */ - rt_list_t page_list; /**< module's using page list */ - rt_mp_t mpool; /**< module's memory pool */ + void* page_array; /**< module's using pages */ + rt_uint32_t page_cnt; /**< module's using pages count */ rt_uint32_t nsym; /**< number of symbol in the module */ struct rt_module_symtab *symtab; /**< module symbol table */ diff --git a/include/rtthread.h b/include/rtthread.h index c3bc0516b5..27c6c97b7d 100644 --- a/include/rtthread.h +++ b/include/rtthread.h @@ -317,6 +317,12 @@ void rt_module_free(rt_module_t module, void *addr); rt_module_t rt_module_self (void); rt_err_t rt_module_set (rt_module_t module); rt_module_t rt_module_find(const char* name); + +#ifdef RT_USING_HOOK +void rt_module_load_sethook(void (*hook)(rt_module_t module)); +void rt_module_unload_sethook(void (*hook)(rt_module_t module)); +#endif + #endif /*@}*/ diff --git a/src/idle.c b/src/idle.c index cae3f34f1a..7bda4dc69b 100644 --- a/src/idle.c +++ b/src/idle.c @@ -115,7 +115,7 @@ void rt_thread_idle_excute(void) rt_hw_interrupt_enable(lock); #ifdef RT_USING_HEAP -#ifdef RT_USING_MODULE +#if defined(RT_USING_MODULE) && defined(RT_USING_SLAB) /* the thread belongs to an application module */ if(thread->flags & RT_OBJECT_FLAG_MODULE) rt_module_free((rt_module_t)thread->module_id, thread->stack_addr); @@ -125,6 +125,7 @@ void rt_thread_idle_excute(void) rt_free(thread->stack_addr); /* delete thread object */ rt_object_delete((rt_object_t)thread); +#endif #ifdef RT_USING_MODULE if(module != RT_NULL) @@ -138,8 +139,7 @@ void rt_thread_idle_excute(void) } /* unload module */ - if(module->nref == 0) rt_module_unload(module); -#endif + if(module->nref == 0) rt_module_unload(module); #endif } } diff --git a/src/ipc.c b/src/ipc.c index b6ad7246a1..99f2f7fe27 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -1286,7 +1286,7 @@ rt_err_t rt_mb_delete (rt_mailbox_t mb) /* also resume all mailbox private suspended thread */ rt_ipc_list_resume_all(&(mb->suspend_sender_thread)); -#ifdef RT_USING_MODULE +#if defined(RT_USING_MODULE) && defined(RT_USING_SLAB) /* the mb object belongs to an application module */ if(mb->parent.parent.flag & RT_OBJECT_FLAG_MODULE) rt_module_free(mb->parent.parent.module_id, mb->msg_pool); @@ -1761,7 +1761,7 @@ rt_err_t rt_mq_delete (rt_mq_t mq) /* resume all suspended thread */ rt_ipc_list_resume_all(&(mq->parent.suspend_thread)); -#ifdef RT_USING_MODULE +#if defined(RT_USING_MODULE) && defined(RT_USING_SLAB) /* the mq object belongs to an application module */ if(mq->parent.parent.flag & RT_OBJECT_FLAG_MODULE) rt_module_free(mq->parent.parent.module_id, mq->msg_pool); diff --git a/src/mempool.c b/src/mempool.c index d1a1527b9c..df6ece85fe 100644 --- a/src/mempool.c +++ b/src/mempool.c @@ -267,7 +267,7 @@ rt_err_t rt_mp_delete(rt_mp_t mp) rt_hw_interrupt_enable(temp); } -#ifdef RT_USING_MODULE +#if defined(RT_USING_MODULE) && defined(RT_USING_SLAB) /* the mp object belongs to an application module */ if(mp->parent.flag & RT_OBJECT_FLAG_MODULE) rt_module_free(mp->parent.module_id, mp->start_address); diff --git a/src/module.c b/src/module.c index a80918250c..9c326def0b 100644 --- a/src/module.c +++ b/src/module.c @@ -11,7 +11,9 @@ * Date Author Notes * 2010-01-09 Bernard first version * 2010-04-09 yi.qiu implement based on first version - * 2010-10-23 yi.qiu implement module memory allocator + * 2010-10-23 yi.qiu implement module memory allocator + * 2011-05-25 yi.qiu implement module hook function + * 2011-06-23 yi.qiu rewrite module memory allocator */ #include @@ -36,13 +38,7 @@ #define IS_AX(s) ((s.sh_flags & SHF_ALLOC) && (s.sh_flags & SHF_EXECINSTR)) #define IS_AW(s) ((s.sh_flags & SHF_ALLOC) && (s.sh_flags & SHF_WRITE)) -/* module memory allocator */ -struct rt_module_page -{ - rt_uint8_t *ptr; /* address of memory block */ - rt_size_t npage; /* number of pages */ - rt_list_t list; -}; +#define PAGE_COUNT_MAX 256 /* module memory allocator */ struct rt_mem_head @@ -51,12 +47,43 @@ struct rt_mem_head struct rt_mem_head *next; /* next valid memory block */ }; -extern void *rt_malloc_page(rt_size_t npages); -extern void rt_free_page(void *page_ptr, rt_size_t npages); +struct rt_page_info +{ + rt_uint32_t *page_ptr; + rt_uint32_t npage; +}; + +static void *rt_module_malloc_page(rt_size_t npages); +static void rt_module_free_page(void *page_ptr, rt_size_t npages); static rt_module_t rt_current_module = RT_NULL; +static struct rt_semaphore mod_sem; +static struct rt_module_symtab *_rt_module_symtab_begin = RT_NULL, *_rt_module_symtab_end = RT_NULL; rt_list_t rt_module_symbol_list; -struct rt_module_symtab *_rt_module_symtab_begin = RT_NULL, *_rt_module_symtab_end = RT_NULL; + +static char* _strip_name(const char* string) +{ + int i = 0, p = 0, q = 0; + const char* str = string; + char* dest = RT_NULL; + + while(*str != '\n' && *str != '\0') + { + if(*str =='/' ) p = i + 1; + if(*str == '.') q = i; + str++; i++; + } + + if(p < q) + { + int len = q - p; + dest = (char*)rt_malloc(len + 1); + rt_strncpy(dest, &string[p], len); + dest[len] = '\0'; + } + + return dest; +} /** * @ingroup SystemInit @@ -75,13 +102,16 @@ void rt_system_module_init(void) #elif defined (__CC_ARM) extern int RTMSymTab$$Base; extern int RTMSymTab$$Limit; - + _rt_module_symtab_begin = (struct rt_module_symtab *)&RTMSymTab$$Base; _rt_module_symtab_end = (struct rt_module_symtab *)&RTMSymTab$$Limit; #endif rt_list_init(&rt_module_symbol_list); + /* initialize heap semaphore */ + rt_sem_init(&mod_sem, "module", 1, RT_IPC_FLAG_FIFO); + /* init current module */ rt_current_module = RT_NULL; } @@ -248,6 +278,40 @@ static void rt_module_init_object_container(struct rt_module* module) module->module_object[RT_Object_Class_Timer].type = RT_Object_Class_Timer; } +#ifdef RT_USING_HOOK +static void (*rt_module_load_hook)(rt_module_t module); +static void (*rt_module_unload_hook)(rt_module_t module); + +/** + * @addtogroup Hook + */ +/*@{*/ + +/** + * This function will set a hook function, which will be invoked when module + * be loaded to system. + * + * @param hook the hook function + */ +void rt_module_load_sethook(void (*hook)(rt_module_t module)) +{ + rt_module_load_hook = hook; +} + +/** + * This function will set a hook function, which will be invoked when module + * be unloaded from system. + * + * @param hook the hook function + */ +void rt_module_unload_sethook(void (*hook)(rt_module_t module)) +{ + rt_module_unload_hook = hook; +} + +/*@}*/ +#endif + /** * This function will load a module from memory and create a thread for it * @@ -274,7 +338,7 @@ rt_module_t rt_module_load(const char* name, void* module_ptr) /* rtmlinke finished */ linked = RT_TRUE; } - else if (rt_memcmp(elf_module->e_ident, ELFMAG, SELFMAG) != 0) + else if (rt_memcmp(elf_module->e_ident, ELFMAG, SELFMAG) != 0) { rt_kprintf(" module magic error\n"); return RT_NULL; @@ -301,7 +365,7 @@ rt_module_t rt_module_load(const char* name, void* module_ptr) } /* allocate module */ - module = (struct rt_module *)rt_object_allocate(RT_Object_Class_Module, (const char*)name); + module = (struct rt_module *)rt_object_allocate(RT_Object_Class_Module, name); if (!module) return RT_NULL; /* allocate module space */ @@ -436,25 +500,24 @@ rt_module_t rt_module_load(const char* name, void* module_ptr) if(elf_module->e_entry != 0) { - /* init module page list */ - rt_list_init(&module->page_list); - /* init module memory allocator */ module->mem_list = RT_NULL; - - /* create mpool for page node */ - module->mpool = rt_mp_create(name, 256, sizeof(struct rt_module_page)); + + /* create page array */ + module->page_array = (void *)rt_malloc(PAGE_COUNT_MAX * sizeof(struct rt_page_info)); + module->page_cnt = 0; /* create module thread */ module->stack_size = 2048; - module->thread_priority = 90; + module->thread_priority = 25; module->module_thread = rt_thread_create(name, module->module_entry, RT_NULL, module->stack_size, module->thread_priority, 10); module->module_thread->module_id = (void*)module; - + module->parent.flag = RT_MODULE_FLAG_WITHENTRY; + /* startup module thread */ rt_thread_startup(module->module_thread); } @@ -464,6 +527,13 @@ rt_module_t rt_module_load(const char* name, void* module_ptr) module->parent.flag |= RT_MODULE_FLAG_WITHOUTENTRY; } +#ifdef RT_USING_HOOK + if(rt_module_load_hook != RT_NULL) + { + rt_module_load_hook(module); + } +#endif + return module; } @@ -477,19 +547,19 @@ rt_module_t rt_module_load(const char* name, void* module_ptr) * @return the module object * */ -rt_module_t rt_module_open(const char* filename) +rt_module_t rt_module_open(const char* path) { int fd, length; struct rt_module* module; struct stat s; - char *buffer, *offset_ptr;; + char *buffer, *offset_ptr, *name; RT_DEBUG_NOT_IN_INTERRUPT; /* check parameters */ - RT_ASSERT(filename != RT_NULL); + RT_ASSERT(path != RT_NULL); - if (stat(filename, &s) !=0) + if (stat(path, &s) !=0) { rt_kprintf("access file failed\n"); return RT_NULL; @@ -502,7 +572,7 @@ rt_module_t rt_module_open(const char* filename) } offset_ptr = buffer; - fd = open(filename, O_RDONLY, 0); + fd = open(path, O_RDONLY, 0); if (fd < 0) { rt_kprintf("open file failed\n"); @@ -528,9 +598,11 @@ rt_module_t rt_module_open(const char* filename) rt_free(buffer); return RT_NULL; } - - module = rt_module_load(filename, (void *)buffer); + + name = _strip_name(path); + module = rt_module_load(name, (void *)buffer); rt_free(buffer); + rt_free(name); return module; } @@ -557,13 +629,13 @@ rt_err_t rt_module_unload(rt_module_t module) RT_DEBUG_NOT_IN_INTERRUPT; - rt_kprintf("rt_module_unload: %s\n", module->parent.name); - /* check parameter */ RT_ASSERT(module != RT_NULL); + rt_kprintf("rt_module_unload: %s\n", module->parent.name); + /* module has entry point */ - if(!(module->parent.flag & RT_MODULE_FLAG_WITHOUTENTRY)) + if((module->parent.flag & RT_MODULE_FLAG_WITHOUTENTRY) != RT_MODULE_FLAG_WITHOUTENTRY) { /* suspend module main thread */ if(module->module_thread != RT_NULL) @@ -728,22 +800,22 @@ rt_err_t rt_module_unload(rt_module_t module) /* delete dynamic object */ rt_timer_delete((rt_timer_t)object); } - } + } + } - /* free module pages */ - list = &module->page_list; - while(list->next != list) + if(module->page_cnt > 0) + { + int i; + struct rt_page_info* page = (struct rt_page_info*)module->page_array; + + rt_kprintf("warning: some module memory still hasn't be freed\n"); + + //list_memlist("tetris"); + + for(i=0; ipage_cnt; i++) { - struct rt_module_page* page; - - /* free page */ - page = rt_list_entry(list->next, struct rt_module_page, list); - rt_free_page(page->ptr, page->npage); - rt_list_remove(list->next); - } - - /* delete mpool */ - if(module->mpool) rt_mp_delete(module->mpool); + rt_module_free_page(page[i].page_ptr, page[i].npage); + } } /* release module space memory */ @@ -753,6 +825,15 @@ rt_err_t rt_module_unload(rt_module_t module) for(i=0; insym; i++) rt_free((void *)module->symtab[i].name); if(module->symtab != RT_NULL) rt_free(module->symtab); +#ifdef RT_USING_HOOK + if(rt_module_unload_hook != RT_NULL) + { + rt_module_unload_hook(module); + } +#endif + + rt_free(module->page_array); + /* delete module object */ rt_object_delete((rt_object_t)module); @@ -800,35 +881,79 @@ rt_module_t rt_module_find(const char* name) return RT_NULL; } -static struct rt_mem_head *morepage(rt_size_t nu) +#ifdef RT_USING_SLAB +/* + * This function will allocate the numbers page with specified size + * in page memory. + * + * @param size the size of memory to be allocated. + * @note this function is used for RT-Thread Application Module + */ +static void *rt_module_malloc_page(rt_size_t npages) { - rt_uint8_t *cp; - rt_uint32_t npage; - struct rt_mem_head *up; - struct rt_module_page *node; + void* chunk; + struct rt_page_info *page; - RT_DEBUG_NOT_IN_INTERRUPT; + chunk = rt_page_alloc(npages); + if (chunk == RT_NULL) return RT_NULL; - RT_ASSERT (nu != 0); + page = (struct rt_page_info*)rt_current_module->page_array; + page[rt_current_module->page_cnt].page_ptr = chunk; + page[rt_current_module->page_cnt].npage = npages; + rt_current_module->page_cnt++; - /* allocate pages from system heap */ - npage = (nu * sizeof(struct rt_mem_head) + RT_MM_PAGE_SIZE - 1)/RT_MM_PAGE_SIZE; - cp = rt_malloc_page(npage); - if(!cp) return RT_NULL; + RT_ASSERT(rt_current_module->page_cnt <= PAGE_COUNT_MAX); - /* allocate page list node from mpool */ - node = rt_mp_alloc(rt_current_module->mpool, RT_WAITING_FOREVER); - node->ptr = cp; - node->npage = npage; + return chunk; +} - /* insert page list node to moudle's page list */ - rt_list_insert_after (&rt_current_module->page_list, &node->list); +/* + * This function will release the previously allocated memory page + * by rt_malloc_page. + * + * @param page_ptr the page address to be released. + * @param npages the number of page shall be released. + * + * @note this function is used for RT-Thread Application Module + */ +static void rt_module_free_page(void *page_ptr, rt_size_t npages) +{ + int i, index; + struct rt_page_info *page; - up = (struct rt_mem_head *) cp; - up->size = npage * RT_MM_PAGE_SIZE / sizeof(struct rt_mem_head); - rt_module_free(rt_current_module, (void *)(up+1)); - - return up; + //rt_kprintf("rt_module_free_page 0x%x %d\n", page_ptr, npages); + rt_page_free(page_ptr, npages); + + page = (struct rt_page_info*)rt_current_module->page_array; + + for(i=0; ipage_cnt; i++) + { + if(page[i].page_ptr == page_ptr) + { + if(page[i].npage == npages + 1) + { + page[i].page_ptr += npages * RT_MM_PAGE_SIZE / sizeof(rt_uint32_t); + } + else if(page[i].npage == npages) + { + for(index=i; indexpage_cnt-1; index++) + { + page[index].page_ptr = page[index + 1].page_ptr; + page[index].npage = page[index + 1].npage; + } + page[rt_current_module->page_cnt - 1].page_ptr = RT_NULL; + page[rt_current_module->page_cnt - 1].npage = 0; + } + else RT_ASSERT(RT_FALSE); + + rt_current_module->page_cnt--; + + return; + } + } + + /* should not be get here */ + RT_ASSERT(RT_FALSE); } /* @@ -836,8 +961,9 @@ static struct rt_mem_head *morepage(rt_size_t nu) */ void *rt_module_malloc(rt_size_t size) { - struct rt_mem_head *b, *n; + struct rt_mem_head *b, *n, *up; struct rt_mem_head **prev; + rt_uint32_t npage; rt_size_t nunits; RT_DEBUG_NOT_IN_INTERRUPT; @@ -847,37 +973,10 @@ void *rt_module_malloc(rt_size_t size) RT_ASSERT(size != 0); RT_ASSERT(nunits != 0); - prev = (struct rt_mem_head **)&rt_current_module->mem_list; + rt_sem_take(&mod_sem, RT_WAITING_FOREVER); - /* if size can be divided by page, allocate page directly */ - if(size % RT_MM_PAGE_SIZE == 0) + for (prev = &rt_current_module->mem_list; (b = *prev) != RT_NULL; prev = &(b->next)) { - rt_uint8_t *cp; - struct rt_module_page *node; - rt_uint32_t npage = size / RT_MM_PAGE_SIZE; - - /* allocate pages from system heap */ - cp = rt_malloc_page(npage); - if(!cp) return RT_NULL; - - /* allocate page list node from mpool */ - node = rt_mp_alloc(rt_current_module->mpool, RT_WAITING_FOREVER); - node->ptr = cp; - node->npage = npage; - - /* insert page list node to moudle's page list */ - rt_list_insert_after (&rt_current_module->page_list, &node->list); - } - - while(RT_TRUE) - { - b = *prev; - if(!b) - { - if ((b = morepage(nunits)) == RT_NULL) return RT_NULL; - else return rt_module_malloc(size); /* To be improved */ - } - if (b->size > nunits) { /* split memory */ @@ -886,28 +985,50 @@ void *rt_module_malloc(rt_size_t size) n->size = b->size - nunits; b->size = nunits; *prev = n; - break; + + //rt_kprintf("rt_module_malloc 0x%x, %d\n",b + 1, size); + rt_sem_release(&mod_sem); + //list_memlist("tetris"); + return (void *)(b + 1); } if (b->size == nunits) { /* this node fit, remove this node */ *prev = b->next; - break; - } - prev = &(b->next); + rt_kprintf("rt_module_malloc 0x%x, %d\n",b + 1, size); + //list_memlist("tetris"); + rt_sem_release(&mod_sem); + return (void *)(b + 1); + } } - return (void *)(b + 1); + /* allocate pages from system heap */ + npage = (size + sizeof(struct rt_mem_head) + RT_MM_PAGE_SIZE - 1)/RT_MM_PAGE_SIZE; + if((up = (struct rt_mem_head*)rt_module_malloc_page(npage)) == RT_NULL) return RT_NULL; + + up->size = npage * RT_MM_PAGE_SIZE / sizeof(struct rt_mem_head); + + for (prev = &rt_current_module->mem_list; (b = *prev) != RT_NULL; prev = &(b->next)) + { + if (b > up + up->size) break; + } + + up->next = b; + *prev = up; + + rt_sem_release(&mod_sem); + + return rt_module_malloc(size); } /* - rt_module_free - insert memory block in free list + rt_module_free - free memory block in free list */ void rt_module_free(rt_module_t module, void *addr) { - struct rt_mem_head *b, *n; + struct rt_mem_head *b, *n, *r; struct rt_mem_head **prev; RT_DEBUG_NOT_IN_INTERRUPT; @@ -915,6 +1036,10 @@ void rt_module_free(rt_module_t module, void *addr) RT_ASSERT(addr); RT_ASSERT((((rt_uint32_t)addr) & (sizeof(struct rt_mem_head) -1)) == 0); + //rt_kprintf("rt_module_free 0x%x\n", addr); + + rt_sem_take(&mod_sem, RT_WAITING_FOREVER); + n = (struct rt_mem_head *)addr - 1; prev = (struct rt_mem_head **)&module->mem_list; @@ -923,14 +1048,42 @@ void rt_module_free(rt_module_t module, void *addr) RT_ASSERT(b->size > 0); RT_ASSERT(b > n || b + b->size <= n); - if (b + b->size == n) + if (b + b->size == n && ((rt_uint32_t)n % RT_MM_PAGE_SIZE != 0)) { - if (b + (b->size += n->size) == b->next) + if (b + (b->size + n->size) == b->next) { - b->size += b->next->size; - b->next = b->next->next; + b->size += b->next->size + n->size; + b->next = b->next->next; } + else b->size += n->size; + if((rt_uint32_t)b % RT_MM_PAGE_SIZE == 0) + { + int npage = b->size * sizeof(struct rt_page_info) / RT_MM_PAGE_SIZE; + if(npage > 0) + { + if((b->size * sizeof(struct rt_page_info) % RT_MM_PAGE_SIZE) != 0) + { + rt_size_t nunits = npage * RT_MM_PAGE_SIZE / sizeof(struct rt_mem_head); + /* split memory */ + r = b + nunits; + r->next = b->next; + r->size = b->size - nunits; + *prev = r; + } + else + { + *prev = b->next; + } + + rt_module_free_page(b, npage); + } + } + + /* unlock */ + rt_sem_release(&mod_sem); + ////list_memlist("tetris"); + return; } @@ -938,7 +1091,34 @@ void rt_module_free(rt_module_t module, void *addr) { n->size = b->size + n->size; n->next = b->next; - *prev = n; + + if((rt_uint32_t)n % RT_MM_PAGE_SIZE == 0) + { + int npage = n->size * sizeof(struct rt_page_info) / RT_MM_PAGE_SIZE; + if(npage > 0) + { + if((n->size * sizeof(struct rt_page_info) % RT_MM_PAGE_SIZE) != 0) + { + rt_size_t nunits = npage * RT_MM_PAGE_SIZE / sizeof(struct rt_mem_head); + /* split memory */ + r = n + nunits; + r->next = n->next; + r->size = n->size - nunits; + *prev = r; + } + else *prev = n->next; + + rt_module_free_page(n, npage); + } + } + else + { + *prev = n; + } + + /* unlock */ + rt_sem_release(&mod_sem); + //list_memlist("tetris"); return; } @@ -947,10 +1127,36 @@ void rt_module_free(rt_module_t module, void *addr) prev = &(b->next); } - n->next = b; - *prev = n; + if((rt_uint32_t)n % RT_MM_PAGE_SIZE == 0) + { + int npage = n->size * sizeof(struct rt_page_info) / RT_MM_PAGE_SIZE; + if(npage > 0) + { + rt_module_free_page(n, npage); + if(n->size % RT_MM_PAGE_SIZE != 0) + { + rt_size_t nunits = npage * RT_MM_PAGE_SIZE / sizeof(struct rt_mem_head); + /* split memory */ + r = n + nunits; + r->next = b; + r->size = n->size - nunits; + *prev = r; + } + else + { + *prev = b; + } + } + } + else + { + n->next = b; + *prev = n; + } - /* free page, TODO */ + /* unlock */ + rt_sem_release(&mod_sem); + //list_memlist("tetris"); } /* @@ -1027,5 +1233,43 @@ void *rt_module_realloc(void *ptr, rt_size_t size) } } } +#endif + +#ifdef RT_USING_FINSH +#include +void list_memlist(const char* name) +{ + rt_module_t module; + struct rt_mem_head **prev; + struct rt_mem_head *b; + + module = rt_module_find(name); + if(module == RT_NULL) return RT_NULL; + + for (prev = (struct rt_mem_head **)&module->mem_list; (b = *prev) != RT_NULL; prev = &(b->next)) + { + rt_kprintf("0x%x--%d\n", b, b->size * sizeof(struct rt_mem_head)); + } +} +FINSH_FUNCTION_EXPORT(list_memlist, list module free memory information) + +void list_mempage(const char* name) +{ + rt_module_t module; + struct rt_page_info *page; + int i; + + module = rt_module_find(name); + if(module == RT_NULL) return RT_NULL; + + page = (struct rt_page_info*)module->page_array; + + for(i=0; ipage_cnt; i++) + { + rt_kprintf("0x%x--%d\n", page[i].page_ptr, page[i].npage); + } +} +FINSH_FUNCTION_EXPORT(list_mempage, list module using memory page information) +#endif #endif diff --git a/src/object.c b/src/object.c index 5667fdd30f..8ebfe2add8 100644 --- a/src/object.c +++ b/src/object.c @@ -340,7 +340,7 @@ void rt_object_delete(rt_object_t object) /* unlock interrupt */ rt_hw_interrupt_enable(temp); -#ifdef RT_USING_MODULE +#if defined(RT_USING_MODULE) && defined(RT_USING_SLAB) if(object->flag & RT_OBJECT_FLAG_MODULE) rt_module_free((rt_module_t)object->module_id, object); else diff --git a/src/rtm.c b/src/rtm.c index a734b678ea..25b4793d2d 100644 --- a/src/rtm.c +++ b/src/rtm.c @@ -1,259 +1,268 @@ -/* - * File : rtm.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2010-04-12 yi.qiu first version - */ - -#include -#include -#include -#include -#include - -/* some buildin kernel symbol */ - -#ifdef RT_USING_MODULE -#include - -/* - * thread interface symbol - */ - -RTM_EXPORT(rt_thread_init); -RTM_EXPORT(rt_thread_detach); -RTM_EXPORT(rt_thread_create); -RTM_EXPORT(rt_thread_self); -RTM_EXPORT(rt_thread_find); -RTM_EXPORT(rt_thread_startup); -RTM_EXPORT(rt_thread_delete); -RTM_EXPORT(rt_thread_yield); -RTM_EXPORT(rt_thread_delay); -RTM_EXPORT(rt_thread_control); -RTM_EXPORT(rt_thread_suspend); -RTM_EXPORT(rt_thread_resume); -RTM_EXPORT(rt_thread_timeout); - -#ifdef RT_USING_SEMAPHORE -/* - * semaphore interface symbol - */ -RTM_EXPORT(rt_sem_init); -RTM_EXPORT(rt_sem_detach); -RTM_EXPORT(rt_sem_create); -RTM_EXPORT(rt_sem_delete); -RTM_EXPORT(rt_sem_take); -RTM_EXPORT(rt_sem_trytake); -RTM_EXPORT(rt_sem_release); -RTM_EXPORT(rt_sem_control); -#endif - -#ifdef RT_USING_MUTEX -/* - * mutex interface symbol - */ -RTM_EXPORT(rt_mutex_init); -RTM_EXPORT(rt_mutex_detach); -RTM_EXPORT(rt_mutex_create); -RTM_EXPORT(rt_mutex_delete); -RTM_EXPORT(rt_mutex_take); -RTM_EXPORT(rt_mutex_release); -RTM_EXPORT(rt_mutex_control); -#endif - -#ifdef RT_USING_EVENT -/* - * event interface symbol - */ -RTM_EXPORT(rt_event_init); -RTM_EXPORT(rt_event_detach); -RTM_EXPORT(rt_event_create); -RTM_EXPORT(rt_event_delete); -RTM_EXPORT(rt_event_send); -RTM_EXPORT(rt_event_recv); -RTM_EXPORT(rt_event_control); -#endif - -#ifdef RT_USING_MAILBOX -/* - * mailbox interface symbol - */ -RTM_EXPORT(rt_mb_init); -RTM_EXPORT(rt_mb_detach); -RTM_EXPORT(rt_mb_create); -RTM_EXPORT(rt_mb_delete); -RTM_EXPORT(rt_mb_send); -RTM_EXPORT(rt_mb_recv); -RTM_EXPORT(rt_mb_control); -#endif - -#ifdef RT_USING_MESSAGEQUEUE -/* - * message queue interface symbol - */ -RTM_EXPORT(rt_mq_init); -RTM_EXPORT(rt_mq_detach); -RTM_EXPORT(rt_mq_create); -RTM_EXPORT(rt_mq_delete); -RTM_EXPORT(rt_mq_send); -RTM_EXPORT(rt_mq_urgent); -RTM_EXPORT(rt_mq_recv); -RTM_EXPORT(rt_mq_control); -#endif - -#ifdef RT_USING_MEMPOOL -/* - * memory pool interface symbol - */ -RTM_EXPORT(rt_mp_init); -RTM_EXPORT(rt_mp_detach); -RTM_EXPORT(rt_mp_create); -RTM_EXPORT(rt_mp_delete); -RTM_EXPORT(rt_mp_alloc); -RTM_EXPORT(rt_mp_free); -#endif - -#ifdef RT_USING_HEAP -/* - * heap memory interface symbol - */ -RTM_EXPORT(rt_malloc); -RTM_EXPORT(rt_free); -RTM_EXPORT(rt_realloc); -RTM_EXPORT(rt_calloc); -#endif -/* - * clock & timer interface symbol - */ -RTM_EXPORT(rt_tick_get); -RTM_EXPORT(rt_tick_from_millisecond); -RTM_EXPORT(rt_system_timer_init); -RTM_EXPORT(rt_system_timer_thread_init); -RTM_EXPORT(rt_timer_init); -RTM_EXPORT(rt_timer_detach); -RTM_EXPORT(rt_timer_create); -RTM_EXPORT(rt_timer_delete); -RTM_EXPORT(rt_timer_start); -RTM_EXPORT(rt_timer_stop); -RTM_EXPORT(rt_timer_control); - -/* - * kservice interface symbol - */ -RTM_EXPORT(rt_memcpy) -RTM_EXPORT(rt_memcmp) -RTM_EXPORT(rt_memset) -RTM_EXPORT(rt_kprintf) -RTM_EXPORT(rt_sprintf) -RTM_EXPORT(rt_strstr) -RTM_EXPORT(rt_snprintf) - -/* - * misc interface symbol - */ -extern int __aeabi_idiv; -extern int __aeabi_ddiv; -extern int __aeabi_dmul; -extern int __aeabi_i2d; -extern int __aeabi_uidiv; -extern int __aeabi_uidivmod; -extern int __aeabi_idivmod; -extern int __aeabi_d2iz; - -RTM_EXPORT(__aeabi_ddiv) -RTM_EXPORT(__aeabi_dmul) -RTM_EXPORT(__aeabi_i2d) -RTM_EXPORT(__aeabi_uidiv) -RTM_EXPORT(__aeabi_idiv) -RTM_EXPORT(__aeabi_idivmod) -RTM_EXPORT(__aeabi_uidivmod) -RTM_EXPORT(__aeabi_d2iz) -RTM_EXPORT(strcmp) -RTM_EXPORT(strcpy) -RTM_EXPORT(strlen) -RTM_EXPORT(rand) -RTM_EXPORT(memset) -RTM_EXPORT(memcpy) - -#ifdef RT_USING_NEWLIB - -#include - -RTM_EXPORT(snprintf) -RTM_EXPORT(access) -RTM_EXPORT(__assert_func) - -#include -RTM_EXPORT(localtime) -RTM_EXPORT(time) - -#endif - -#ifdef RT_USING_DFS -#include - -RTM_EXPORT(open) -RTM_EXPORT(close) -RTM_EXPORT(read) -RTM_EXPORT(write) -RTM_EXPORT(stat) -#endif - -#ifdef RT_USING_RTGUI -/* FIX ME , should be removed from here */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -RTM_EXPORT(rtgui_view_show) -RTM_EXPORT(rtgui_view_create) -RTM_EXPORT(rtgui_view_destroy) -RTM_EXPORT(rtgui_view_event_handler) -RTM_EXPORT(rtgui_dc_draw_text) -RTM_EXPORT(rtgui_dc_begin_drawing) -RTM_EXPORT(rtgui_dc_end_drawing) -RTM_EXPORT(rtgui_workbench_event_loop) -RTM_EXPORT(rtgui_workbench_event_handler) -RTM_EXPORT(rtgui_workbench_add_view) -RTM_EXPORT(rtgui_workbench_create) -RTM_EXPORT(rtgui_workbench_destroy) -RTM_EXPORT(rtgui_workbench_close) -RTM_EXPORT(rtgui_timer_start) -RTM_EXPORT(rtgui_timer_create) -RTM_EXPORT(rtgui_timer_destory) -RTM_EXPORT(rtgui_timer_stop) -RTM_EXPORT(rtgui_thread_register) -RTM_EXPORT(rtgui_thread_deregister) -RTM_EXPORT(rtgui_widget_focus) -RTM_EXPORT(rtgui_widget_set_event_handler) -RTM_EXPORT(rtgui_widget_rect_to_device) -RTM_EXPORT(rtgui_widget_update) -RTM_EXPORT(rtgui_widget_get_rect) -RTM_EXPORT(rtgui_widget_set_rect) -RTM_EXPORT(rtgui_widget_get_toplevel) -RTM_EXPORT(rtgui_panel_register) -RTM_EXPORT(rtgui_panel_set_default_focused) -RTM_EXPORT(rtgui_button_create) -RTM_EXPORT(rtgui_button_destroy) -RTM_EXPORT(rtgui_button_set_onbutton) -RTM_EXPORT(rtgui_container_add_child) -RTM_EXPORT(rtgui_filelist_view_create) -RTM_EXPORT(rtgui_filelist_view_get_fullpath) -RTM_EXPORT(rtgui_list_view_create) -RTM_EXPORT(rtgui_list_view_destroy) -#endif -#endif - +/* + * File : rtm.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-04-12 yi.qiu first version + */ + +#include +#include +#include +#include +#include + +/* some buildin kernel symbol */ + +#ifdef RT_USING_MODULE +#include + +RTM_EXPORT(rt_object_get_information); + +/* + * thread interface symbol + */ + +RTM_EXPORT(rt_thread_init); +RTM_EXPORT(rt_thread_detach); +RTM_EXPORT(rt_thread_create); +RTM_EXPORT(rt_thread_self); +RTM_EXPORT(rt_thread_find); +RTM_EXPORT(rt_thread_startup); +RTM_EXPORT(rt_thread_delete); +RTM_EXPORT(rt_thread_yield); +RTM_EXPORT(rt_thread_delay); +RTM_EXPORT(rt_thread_control); +RTM_EXPORT(rt_thread_suspend); +RTM_EXPORT(rt_thread_resume); +RTM_EXPORT(rt_thread_timeout); + +#ifdef RT_USING_SEMAPHORE +/* + * semaphore interface symbol + */ +RTM_EXPORT(rt_sem_init); +RTM_EXPORT(rt_sem_detach); +RTM_EXPORT(rt_sem_create); +RTM_EXPORT(rt_sem_delete); +RTM_EXPORT(rt_sem_take); +RTM_EXPORT(rt_sem_trytake); +RTM_EXPORT(rt_sem_release); +RTM_EXPORT(rt_sem_control); +#endif + +#ifdef RT_USING_MUTEX +/* + * mutex interface symbol + */ +RTM_EXPORT(rt_mutex_init); +RTM_EXPORT(rt_mutex_detach); +RTM_EXPORT(rt_mutex_create); +RTM_EXPORT(rt_mutex_delete); +RTM_EXPORT(rt_mutex_take); +RTM_EXPORT(rt_mutex_release); +RTM_EXPORT(rt_mutex_control); +#endif + +#ifdef RT_USING_EVENT +/* + * event interface symbol + */ +RTM_EXPORT(rt_event_init); +RTM_EXPORT(rt_event_detach); +RTM_EXPORT(rt_event_create); +RTM_EXPORT(rt_event_delete); +RTM_EXPORT(rt_event_send); +RTM_EXPORT(rt_event_recv); +RTM_EXPORT(rt_event_control); +#endif + +#ifdef RT_USING_MAILBOX +/* + * mailbox interface symbol + */ +RTM_EXPORT(rt_mb_init); +RTM_EXPORT(rt_mb_detach); +RTM_EXPORT(rt_mb_create); +RTM_EXPORT(rt_mb_delete); +RTM_EXPORT(rt_mb_send); +RTM_EXPORT(rt_mb_recv); +RTM_EXPORT(rt_mb_control); +#endif + +#ifdef RT_USING_MESSAGEQUEUE +/* + * message queue interface symbol + */ +RTM_EXPORT(rt_mq_init); +RTM_EXPORT(rt_mq_detach); +RTM_EXPORT(rt_mq_create); +RTM_EXPORT(rt_mq_delete); +RTM_EXPORT(rt_mq_send); +RTM_EXPORT(rt_mq_urgent); +RTM_EXPORT(rt_mq_recv); +RTM_EXPORT(rt_mq_control); +#endif + +#ifdef RT_USING_MEMPOOL +/* + * memory pool interface symbol + */ +RTM_EXPORT(rt_mp_init); +RTM_EXPORT(rt_mp_detach); +RTM_EXPORT(rt_mp_create); +RTM_EXPORT(rt_mp_delete); +RTM_EXPORT(rt_mp_alloc); +RTM_EXPORT(rt_mp_free); +#endif + +#ifdef RT_USING_HEAP +/* + * heap memory interface symbol + */ +RTM_EXPORT(rt_malloc); +RTM_EXPORT(rt_free); +RTM_EXPORT(rt_realloc); +RTM_EXPORT(rt_calloc); +#endif +/* + * clock & timer interface symbol + */ +RTM_EXPORT(rt_tick_get); +RTM_EXPORT(rt_tick_from_millisecond); +RTM_EXPORT(rt_system_timer_init); +RTM_EXPORT(rt_system_timer_thread_init); +RTM_EXPORT(rt_timer_init); +RTM_EXPORT(rt_timer_detach); +RTM_EXPORT(rt_timer_create); +RTM_EXPORT(rt_timer_delete); +RTM_EXPORT(rt_timer_start); +RTM_EXPORT(rt_timer_stop); +RTM_EXPORT(rt_timer_control); + +/* + * kservice interface symbol + */ +RTM_EXPORT(rt_memcpy); +RTM_EXPORT(rt_memcmp); +RTM_EXPORT(rt_memset); +RTM_EXPORT(rt_kprintf); +RTM_EXPORT(rt_sprintf); +RTM_EXPORT(rt_strstr); +RTM_EXPORT(rt_snprintf); + +/* + * misc interface symbol + */ +extern int __aeabi_idiv; +extern int __aeabi_ddiv; +extern int __aeabi_dmul; +extern int __aeabi_i2d; +extern int __aeabi_uidiv; +extern int __aeabi_uidivmod; +extern int __aeabi_idivmod; +extern int __aeabi_d2iz; + +RTM_EXPORT(__aeabi_ddiv); +RTM_EXPORT(__aeabi_dmul); +RTM_EXPORT(__aeabi_i2d); +RTM_EXPORT(__aeabi_uidiv); +RTM_EXPORT(__aeabi_idiv); +RTM_EXPORT(__aeabi_idivmod); +RTM_EXPORT(__aeabi_uidivmod); +RTM_EXPORT(__aeabi_d2iz); +RTM_EXPORT(strcmp); +RTM_EXPORT(strcpy); +RTM_EXPORT(strlen); +RTM_EXPORT(rand); +RTM_EXPORT(memset); +RTM_EXPORT(memcpy); + +#ifdef RT_USING_NEWLIB + +#include + +RTM_EXPORT(snprintf); +RTM_EXPORT(access); +RTM_EXPORT(__assert_func); + +#include +RTM_EXPORT(localtime); +RTM_EXPORT(time); + +#endif + +#ifdef RT_USING_DFS +#include + +RTM_EXPORT(open); +RTM_EXPORT(close); +RTM_EXPORT(read); +RTM_EXPORT(write); +RTM_EXPORT(stat); +#endif + +#ifdef RT_USING_RTGUI +/* FIX ME , should be removed from here */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +RTM_EXPORT(rtgui_label_create); +RTM_EXPORT(rtgui_view_show); +RTM_EXPORT(rtgui_view_create); +RTM_EXPORT(rtgui_view_destroy); +RTM_EXPORT(rtgui_view_event_handler); +RTM_EXPORT(rtgui_dc_draw_text); +RTM_EXPORT(rtgui_dc_begin_drawing); +RTM_EXPORT(rtgui_dc_end_drawing); +RTM_EXPORT(rtgui_workbench_event_loop); +RTM_EXPORT(rtgui_workbench_event_handler); +RTM_EXPORT(rtgui_workbench_add_view); +RTM_EXPORT(rtgui_workbench_create); +RTM_EXPORT(rtgui_workbench_destroy); +RTM_EXPORT(rtgui_workbench_close); +RTM_EXPORT(rtgui_timer_start); +RTM_EXPORT(rtgui_timer_create); +RTM_EXPORT(rtgui_timer_destory); +RTM_EXPORT(rtgui_timer_stop); +RTM_EXPORT(rtgui_thread_register); +RTM_EXPORT(rtgui_thread_deregister); +RTM_EXPORT(rtgui_widget_focus); +RTM_EXPORT(rtgui_widget_set_event_handler); +RTM_EXPORT(rtgui_widget_rect_to_device); +RTM_EXPORT(rtgui_widget_update); +RTM_EXPORT(rtgui_widget_get_rect); +RTM_EXPORT(rtgui_widget_set_rect); +RTM_EXPORT(rtgui_widget_get_toplevel); +RTM_EXPORT(rtgui_panel_register); +RTM_EXPORT(rtgui_panel_set_default_focused); +RTM_EXPORT(rtgui_button_create); +RTM_EXPORT(rtgui_button_destroy); +RTM_EXPORT(rtgui_button_set_onbutton); +RTM_EXPORT(rtgui_container_add_child); +RTM_EXPORT(rtgui_filelist_view_create); +RTM_EXPORT(rtgui_filelist_view_get_fullpath); +RTM_EXPORT(rtgui_list_view_create); +RTM_EXPORT(rtgui_list_view_destroy); +RTM_EXPORT(rtgui_listctrl_set_onitem); +RTM_EXPORT(rtgui_image_create_from_mem); +RTM_EXPORT(rtgui_listctrl_create); + +#endif +#endif + diff --git a/src/slab.c b/src/slab.c index af044662af..378faea1d8 100644 --- a/src/slab.c +++ b/src/slab.c @@ -256,6 +256,12 @@ void *rt_page_alloc(rt_size_t npages) break; } } + +#ifdef RT_MEM_STATS + used_mem += npages * RT_MM_PAGE_SIZE; + if (used_mem > max_mem) max_mem = used_mem; +#endif + /* unlock heap */ rt_sem_release(&heap_sem); @@ -275,6 +281,13 @@ void rt_page_free(void *addr, rt_size_t npages) /* lock heap */ rt_sem_take(&heap_sem, RT_WAITING_FOREVER); + + /* update memory usage */ +#ifdef RT_MEM_STATS + if(rt_page_list != RT_NULL) + used_mem -= npages * RT_MM_PAGE_SIZE; +#endif + for (prev = &rt_page_list; (b = *prev) != RT_NULL; prev = &(b->next)) { RT_ASSERT(b->page > 0); @@ -443,52 +456,6 @@ rt_inline int zoneindex(rt_uint32_t *bytes) /*@{*/ -/* - * This function will allocate the numbers page with specified size - * in page memory. - * - * @param size the size of memory to be allocated. - * @note this function is used for RT-Thread Application Module - */ -void *rt_malloc_page(rt_size_t npages) -{ - void* chunk; - - chunk = rt_page_alloc(npages); - if (chunk == RT_NULL) return RT_NULL; - - /* update memory usage */ -#ifdef RT_MEM_STATS - rt_sem_take(&heap_sem, RT_WAITING_FOREVER); - used_mem += npages * RT_MM_PAGE_SIZE; - if (used_mem > max_mem) max_mem = used_mem; - rt_sem_release(&heap_sem); -#endif - - return chunk; -} - -/* - * This function will release the previously allocated memory page - * by rt_malloc_page. - * - * @param page_ptr the page address to be released. - * @param npages the number of page shall be released. - * - * @note this function is used for RT-Thread Application Module - */ -void rt_free_page(void *page_ptr, rt_size_t npages) -{ - rt_page_free(page_ptr, npages); - - /* update memory usage */ -#ifdef RT_MEM_STATS - rt_sem_take(&heap_sem, RT_WAITING_FOREVER); - used_mem -= npages * RT_MM_PAGE_SIZE; - rt_sem_release(&heap_sem); -#endif -} - /** * This function will allocate a block from system heap memory. * - If the nbytes is less than zero,