diff options
Diffstat (limited to 'src/module.c')
| -rw-r--r-- | src/module.c | 150 |
1 files changed, 148 insertions, 2 deletions
diff --git a/src/module.c b/src/module.c index d101c5b3b0..54e6378fd4 100644 --- a/src/module.c +++ b/src/module.c @@ -11,6 +11,7 @@ * 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 */ #include <rtthread.h> @@ -35,7 +36,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)) -static struct rt_module* rt_current_module = RT_NULL; +static rt_module_t rt_current_module = 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; @@ -50,8 +51,10 @@ void rt_system_module_init(void) extern int __rtmsymtab_start; extern int __rtmsymtab_end; +#ifdef __GNUC__ _rt_module_symtab_begin = (struct rt_module_symtab *)&__rtmsymtab_start; _rt_module_symtab_end = (struct rt_module_symtab *)&__rtmsymtab_end; +#endif rt_list_init(&rt_module_symbol_list); } @@ -348,7 +351,9 @@ rt_module_t rt_module_load(const rt_uint8_t* name, void* module_ptr) module->module_entry, RT_NULL, module->stack_size, module->thread_priority, 10); - module->module_thread->module_parent = module; + module->module_thread->module_id = (void*)module; + module->module_mem_list = RT_NULL; + rt_list_init(&module->module_page); rt_thread_startup(module->module_thread); return module; @@ -620,6 +625,147 @@ rt_module_t rt_module_find(char* name) return RT_NULL; } +/* module memory allocator */ +struct rt_mem_head +{ + rt_size_t size; /* size of memory block */ + struct rt_mem_head *next; /* next valid memory block */ +}; +static struct rt_mem_head *morepage(rt_size_t nu); + +/* + rt_module_free - alloc memory block in free list +*/ +void *rt_module_malloc(rt_size_t size) +{ + struct rt_mem_head *b, *n; + struct rt_mem_head **prev; + rt_size_t nunits; + + nunits = (size + sizeof(struct rt_mem_head) -1)/sizeof(struct rt_mem_head) + 1; + + RT_ASSERT(size != 0); + RT_ASSERT(nunits != 0); + + prev = (struct rt_mem_head **)&rt_current_module->module_mem_list; + + while(RT_TRUE) + { + b = *prev; + if(b == RT_NULL) + { + if ((b = morepage(nunits)) == RT_NULL) + return RT_NULL; + } + + if (b->size > nunits) + { + /* splite memory */ + n = b + nunits; + n->next = b->next; + n->size = b->size - nunits; + b->size = nunits; + *prev = n; + break; + } + + if (b->size == nunits) + { + /* this node fit, remove this node */ + *prev = b->next; + break; + } + + prev = &(b->next); + } + + return (void *)(b + 1); +} + +/* + rt_module_free - insert 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 **prev; + + RT_ASSERT(addr != RT_NULL); + RT_ASSERT((((rt_uint32_t)addr) & (sizeof(struct rt_mem_head) -1)) == 0); + + n = (struct rt_mem_head *)addr - 1; + prev = (struct rt_mem_head **)&module->module_mem_list; + + while ((b = *prev) != RT_NULL) + { + RT_ASSERT(b->size > 0); + RT_ASSERT(b > n || b + b->size <= n); + + if (b + b->size == n) + { + if (b + (b->size += n->size) == b->next) + { + b->size += b->next->size; + b->next = b->next->next; + } + + return; + } + + if (b == n + n->size) + { + n->size = b->size + n->size; + n->next = b->next; + *prev = n; + + return; + } + if (b > n + n->size) break; + + prev = &(b->next); + } + + n->next = b; + *prev = n; +} + +/* + rt_module_realloc - realloc memory block in free list +*/ +void *rt_module_realloc(void *ptr, rt_size_t size) +{ + RT_ASSERT(RT_NULL); + + /* TO DO */ +} + +/* 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; +}; +static struct rt_module_page *rt_module_page_list; + +static struct rt_mem_head *morepage(rt_size_t nu) +{ + rt_uint8_t *cp; + rt_uint32_t npage; + struct rt_mem_head *up; + + RT_ASSERT (nu != 0); + + npage = (nu * sizeof(struct rt_mem_head) + RT_MM_PAGE_SIZE - 1)/RT_MM_PAGE_SIZE; + cp = rt_page_alloc(npage); + if(cp == RT_NULL) return RT_NULL; + + 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; +} + #if defined(RT_USING_FINSH) #include <finsh.h> |
