[Kernel] Remove object container in module feature.

This commit is contained in:
Bernard Xiong 2018-06-10 17:56:02 +08:00
parent c83c8d8462
commit 682da9b249
6 changed files with 9 additions and 978 deletions

View File

@ -614,113 +614,6 @@ int list_module(void)
} }
FINSH_FUNCTION_EXPORT(list_module, list module in system); FINSH_FUNCTION_EXPORT(list_module, list module in system);
MSH_CMD_EXPORT(list_module, list module in system); MSH_CMD_EXPORT(list_module, list module in system);
int list_mod_detail(const char *name)
{
int i;
struct rt_module *module;
/* find module */
if ((module = rt_module_find(name)) != RT_NULL)
{
/* module has entry point */
if (!(module->parent.flag & RT_MODULE_FLAG_WITHOUTENTRY))
{
struct rt_thread *thread;
struct rt_list_node *tlist;
rt_uint8_t *ptr;
/* list main thread in module */
if (module->module_thread != RT_NULL)
{
rt_uint8_t stat;
rt_kprintf("main thread pri status sp stack size max used left tick error\n");
rt_kprintf("------------- ---- ------- ---------- ---------- ---------- ---------- ---\n");
thread = module->module_thread;
rt_kprintf("%-8.*s 0x%02x", RT_NAME_MAX, thread->name, thread->current_priority);
stat = (thread->stat & RT_THREAD_STAT_MASK);
if (stat == RT_THREAD_READY) rt_kprintf(" ready ");
else if (stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend");
else if (stat == RT_THREAD_INIT) rt_kprintf(" init ");
ptr = (rt_uint8_t *)thread->stack_addr;
while (*ptr == '#')ptr ++;
rt_kprintf(" 0x%08x 0x%08x 0x%08x 0x%08x %03d\n",
thread->stack_size + ((rt_uint32_t)thread->stack_addr - (rt_uint32_t)thread->sp),
thread->stack_size,
thread->stack_size - ((rt_uint32_t) ptr - (rt_uint32_t)thread->stack_addr),
thread->remaining_tick,
thread->error);
}
/* list sub thread in module */
tlist = &module->module_object[RT_Object_Class_Thread].object_list;
if (!rt_list_isempty(tlist)) _list_thread(tlist);
#ifdef RT_USING_SEMAPHORE
/* list semaphored in module */
tlist = &module->module_object[RT_Object_Class_Semaphore].object_list;
if (!rt_list_isempty(tlist)) _list_sem(tlist);
#endif
#ifdef RT_USING_MUTEX
/* list mutex in module */
tlist = &module->module_object[RT_Object_Class_Mutex].object_list;
if (!rt_list_isempty(tlist)) _list_mutex(tlist);
#endif
#ifdef RT_USING_EVENT
/* list event in module */
tlist = &module->module_object[RT_Object_Class_Event].object_list;
if (!rt_list_isempty(tlist)) _list_event(tlist);
#endif
#ifdef RT_USING_MAILBOX
/* list mailbox in module */
tlist = &module->module_object[RT_Object_Class_MailBox].object_list;
if (!rt_list_isempty(tlist)) _list_mailbox(tlist);
#endif
#ifdef RT_USING_MESSAGEQUEUE
/* list message queue in module */
tlist = &module->module_object[RT_Object_Class_MessageQueue].object_list;
if (!rt_list_isempty(tlist)) _list_msgqueue(tlist);
#endif
#ifdef RT_USING_MEMHEAP
/* list memory heap in module */
tlist = &module->module_object[RT_Object_Class_MemHeap].object_list;
if (!rt_list_isempty(tlist)) _list_memheap(tlist);
#endif
#ifdef RT_USING_MEMPOOL
/* list memory pool in module */
tlist = &module->module_object[RT_Object_Class_MemPool].object_list;
if (!rt_list_isempty(tlist)) _list_mempool(tlist);
#endif
#ifdef RT_USING_DEVICE
/* list device in module */
tlist = &module->module_object[RT_Object_Class_Device].object_list;
if (!rt_list_isempty(tlist)) _list_device(tlist);
#endif
/* list timer in module */
tlist = &module->module_object[RT_Object_Class_Timer].object_list;
if (!rt_list_isempty(tlist)) _list_timer(tlist);
}
if (module->nsym > 0)
{
rt_kprintf("symbol address \n");
rt_kprintf("-------- ----------\n");
/* list module export symbols */
for (i = 0; i < module->nsym; i++)
{
rt_kprintf("%s 0x%x\n",
module->symtab[i].name, module->symtab[i].addr);
}
}
}
return 0;
}
FINSH_FUNCTION_EXPORT(list_mod_detail, list module objects in system)
#endif #endif
long list(void) long list(void)

View File

@ -333,7 +333,7 @@ int msh_exec(char *cmd, rt_size_t length)
{ {
return cmd_ret; return cmd_ret;
} }
#ifdef RT_USING_MODULE #if defined(RT_USING_MODULE) && defined(RT_USING_DFS)
if (msh_exec_module(cmd, length) == 0) if (msh_exec_module(cmd, length) == 0)
{ {
return 0; return 0;

View File

@ -7,7 +7,7 @@
#include <dfs_posix.h> #include <dfs_posix.h>
#endif #endif
#ifdef RT_USING_PTHREADS #ifdef RT_USING_PTHREADS
#include <pthread.h> #include <pthread.h>
#endif #endif
@ -126,7 +126,7 @@ _open_r(struct _reent *ptr, const char *file, int flags, int mode)
#endif #endif
} }
_ssize_t _ssize_t
_read_r(struct _reent *ptr, int fd, void *buf, size_t nbytes) _read_r(struct _reent *ptr, int fd, void *buf, size_t nbytes)
{ {
#ifndef RT_USING_DFS #ifndef RT_USING_DFS
@ -372,7 +372,7 @@ void *_calloc_r (struct _reent *ptr, size_t size, size_t len)
return result; return result;
} }
void void
_free_r (struct _reent *ptr, void *addr) _free_r (struct _reent *ptr, void *addr)
{ {
rt_free (addr); rt_free (addr);
@ -387,43 +387,20 @@ _exit (int status)
module = rt_module_self(); module = rt_module_self();
if (module != RT_NULL) if (module != RT_NULL)
{ {
struct rt_list_node *list; rt_thread_suspend(rt_thread_self());
struct rt_object *object;
rt_enter_critical();
/* delete all threads in the module */
list = &module->module_object[RT_Object_Class_Thread].object_list;
while (list->next != list)
{
object = rt_list_entry(list->next, struct rt_object, list);
if (rt_object_is_systemobject(object) == RT_TRUE)
{
/* detach static object */
rt_thread_detach((rt_thread_t)object);
}
else
{
/* delete dynamic object */
rt_thread_delete((rt_thread_t)object);
}
}
/* delete main thread */
rt_thread_delete(module->module_thread);
rt_exit_critical();
/* re-schedule */ /* re-schedule */
rt_schedule(); rt_schedule();
} }
#endif #endif
rt_kprintf("thread:%s exit with %d\n", rt_thread_self()->name, status); rt_kprintf("thread:%s exit with %d\n", rt_thread_self()->name, status);
RT_ASSERT(0); RT_ASSERT(0);
while (1); while (1);
} }
void void
_system(const char *s) _system(const char *s)
{ {
/* not support this call */ /* not support this call */

View File

@ -175,24 +175,6 @@ void rt_thread_idle_excute(void)
/* delete thread object */ /* delete thread object */
rt_object_delete((rt_object_t)thread); rt_object_delete((rt_object_t)thread);
#endif #endif
#ifdef RT_USING_MODULE
if (module != RT_NULL)
{
extern rt_err_t rt_module_destroy(rt_module_t module);
/* if sub thread list and main thread are all empty */
if ((module->module_thread == RT_NULL) &&
rt_list_isempty(&module->module_object[RT_Object_Class_Thread].object_list))
{
module->nref --;
}
/* destroy module */
if (module->nref == 0)
rt_module_destroy(module);
}
#endif
} }
} }

View File

@ -120,10 +120,6 @@ int rt_system_module_init(void)
_rt_module_symtab_end = __section_end("RTMSymTab"); _rt_module_symtab_end = __section_end("RTMSymTab");
#endif #endif
#ifdef RT_USING_SLAB
/* initialize heap semaphore */
rt_sem_init(&mod_sem, "module", 1, RT_IPC_FLAG_FIFO);
#endif
return 0; return 0;
} }
INIT_COMPONENT_EXPORT(rt_system_module_init); INIT_COMPONENT_EXPORT(rt_system_module_init);
@ -138,7 +134,7 @@ void list_symbol(void)
index != _rt_module_symtab_end; index != _rt_module_symtab_end;
index ++) index ++)
{ {
rt_kprintf("%s\n", index->name); rt_kprintf("%s => 0x%08x\n", index->name, index->addr);
} }
return ; return ;
@ -295,80 +291,6 @@ static int rt_module_arm_relocate(struct rt_module *module,
return 0; return 0;
} }
void rt_module_init_object_container(struct rt_module *module)
{
RT_ASSERT(module != RT_NULL);
/* clear all of object information */
rt_memset(&module->module_object[0], 0x0, sizeof(module->module_object));
/* initialize object container - thread */
rt_list_init(&(module->module_object[RT_Object_Class_Thread].object_list));
module->module_object[RT_Object_Class_Thread].object_size = sizeof(struct rt_thread);
module->module_object[RT_Object_Class_Thread].type = RT_Object_Class_Thread;
#ifdef RT_USING_SEMAPHORE
/* initialize object container - semaphore */
rt_list_init(&(module->module_object[RT_Object_Class_Semaphore].object_list));
module->module_object[RT_Object_Class_Semaphore].object_size = sizeof(struct rt_semaphore);
module->module_object[RT_Object_Class_Semaphore].type = RT_Object_Class_Semaphore;
#endif
#ifdef RT_USING_MUTEX
/* initialize object container - mutex */
rt_list_init(&(module->module_object[RT_Object_Class_Mutex].object_list));
module->module_object[RT_Object_Class_Mutex].object_size = sizeof(struct rt_mutex);
module->module_object[RT_Object_Class_Mutex].type = RT_Object_Class_Mutex;
#endif
#ifdef RT_USING_EVENT
/* initialize object container - event */
rt_list_init(&(module->module_object[RT_Object_Class_Event].object_list));
module->module_object[RT_Object_Class_Event].object_size = sizeof(struct rt_event);
module->module_object[RT_Object_Class_Event].type = RT_Object_Class_Event;
#endif
#ifdef RT_USING_MAILBOX
/* initialize object container - mailbox */
rt_list_init(&(module->module_object[RT_Object_Class_MailBox].object_list));
module->module_object[RT_Object_Class_MailBox].object_size = sizeof(struct rt_mailbox);
module->module_object[RT_Object_Class_MailBox].type = RT_Object_Class_MailBox;
#endif
#ifdef RT_USING_MESSAGEQUEUE
/* initialize object container - message queue */
rt_list_init(&(module->module_object[RT_Object_Class_MessageQueue].object_list));
module->module_object[RT_Object_Class_MessageQueue].object_size = sizeof(struct rt_messagequeue);
module->module_object[RT_Object_Class_MessageQueue].type = RT_Object_Class_MessageQueue;
#endif
#ifdef RT_USING_MEMHEAP
/* initialize object container - memory heap */
rt_list_init(&(module->module_object[RT_Object_Class_MemHeap].object_list));
module->module_object[RT_Object_Class_MemHeap].object_size = sizeof(struct rt_memheap);
module->module_object[RT_Object_Class_MemHeap].type = RT_Object_Class_MemHeap;
#endif
#ifdef RT_USING_MEMPOOL
/* initialize object container - memory pool */
rt_list_init(&(module->module_object[RT_Object_Class_MemPool].object_list));
module->module_object[RT_Object_Class_MemPool].object_size = sizeof(struct rt_mempool);
module->module_object[RT_Object_Class_MemPool].type = RT_Object_Class_MemPool;
#endif
#ifdef RT_USING_DEVICE
/* initialize object container - device */
rt_list_init(&(module->module_object[RT_Object_Class_Device].object_list));
module->module_object[RT_Object_Class_Device].object_size = sizeof(struct rt_device);
module->module_object[RT_Object_Class_Device].type = RT_Object_Class_Device;
#endif
/* initialize object container - timer */
rt_list_init(&(module->module_object[RT_Object_Class_Timer].object_list));
module->module_object[RT_Object_Class_Timer].object_size = sizeof(struct rt_timer);
module->module_object[RT_Object_Class_Timer].type = RT_Object_Class_Timer;
}
#ifdef RT_USING_HOOK #ifdef RT_USING_HOOK
static void (*rt_module_load_hook)(rt_module_t module); static void (*rt_module_load_hook)(rt_module_t module);
static void (*rt_module_unload_hook)(rt_module_t module); static void (*rt_module_unload_hook)(rt_module_t module);
@ -1016,9 +938,6 @@ rt_module_t rt_module_do_main(const char *name,
if (module == RT_NULL) if (module == RT_NULL)
return RT_NULL; return RT_NULL;
/* init module object container */
rt_module_init_object_container(module);
if (line_size && cmd_line) if (line_size && cmd_line)
{ {
/* set module argument */ /* set module argument */
@ -1042,16 +961,6 @@ rt_module_t rt_module_do_main(const char *name,
if (elf_module->e_entry != 0) if (elf_module->e_entry != 0)
{ {
#ifdef RT_USING_SLAB
/* init module memory allocator */
module->mem_list = RT_NULL;
/* create page array */
module->page_array =
(void *)rt_malloc(PAGE_COUNT_MAX * sizeof(struct rt_page_info));
module->page_cnt = 0;
#endif
/* create module thread */ /* create module thread */
module->module_thread = rt_thread_create(name, module->module_thread = rt_thread_create(name,
module_main_entry, module, module_main_entry, module,
@ -1291,8 +1200,6 @@ FINSH_FUNCTION_EXPORT_ALIAS(rt_module_open, exec, exec module from a file);
rt_err_t rt_module_destroy(rt_module_t module) rt_err_t rt_module_destroy(rt_module_t module)
{ {
int i; int i;
struct rt_object *object;
struct rt_list_node *list;
RT_DEBUG_NOT_IN_INTERRUPT; RT_DEBUG_NOT_IN_INTERRUPT;
@ -1306,147 +1213,6 @@ rt_err_t rt_module_destroy(rt_module_t module)
/* module has entry point */ /* module has entry point */
if (!(module->parent.flag & RT_MODULE_FLAG_WITHOUTENTRY)) if (!(module->parent.flag & RT_MODULE_FLAG_WITHOUTENTRY))
{ {
#ifdef RT_USING_SEMAPHORE
/* delete semaphores */
list = &module->module_object[RT_Object_Class_Semaphore].object_list;
while (list->next != list)
{
object = rt_list_entry(list->next, struct rt_object, list);
if (rt_object_is_systemobject(object) == RT_TRUE)
{
/* detach static object */
rt_sem_detach((rt_sem_t)object);
}
else
{
/* delete dynamic object */
rt_sem_delete((rt_sem_t)object);
}
}
#endif
#ifdef RT_USING_MUTEX
/* delete mutexs*/
list = &module->module_object[RT_Object_Class_Mutex].object_list;
while (list->next != list)
{
object = rt_list_entry(list->next, struct rt_object, list);
if (rt_object_is_systemobject(object) == RT_TRUE)
{
/* detach static object */
rt_mutex_detach((rt_mutex_t)object);
}
else
{
/* delete dynamic object */
rt_mutex_delete((rt_mutex_t)object);
}
}
#endif
#ifdef RT_USING_EVENT
/* delete mailboxs */
list = &module->module_object[RT_Object_Class_Event].object_list;
while (list->next != list)
{
object = rt_list_entry(list->next, struct rt_object, list);
if (rt_object_is_systemobject(object) == RT_TRUE)
{
/* detach static object */
rt_event_detach((rt_event_t)object);
}
else
{
/* delete dynamic object */
rt_event_delete((rt_event_t)object);
}
}
#endif
#ifdef RT_USING_MAILBOX
/* delete mailboxs */
list = &module->module_object[RT_Object_Class_MailBox].object_list;
while (list->next != list)
{
object = rt_list_entry(list->next, struct rt_object, list);
if (rt_object_is_systemobject(object) == RT_TRUE)
{
/* detach static object */
rt_mb_detach((rt_mailbox_t)object);
}
else
{
/* delete dynamic object */
rt_mb_delete((rt_mailbox_t)object);
}
}
#endif
#ifdef RT_USING_MESSAGEQUEUE
/* delete msgqueues */
list = &module->module_object[RT_Object_Class_MessageQueue].object_list;
while (list->next != list)
{
object = rt_list_entry(list->next, struct rt_object, list);
if (rt_object_is_systemobject(object) == RT_TRUE)
{
/* detach static object */
rt_mq_detach((rt_mq_t)object);
}
else
{
/* delete dynamic object */
rt_mq_delete((rt_mq_t)object);
}
}
#endif
#ifdef RT_USING_MEMPOOL
/* delete mempools */
list = &module->module_object[RT_Object_Class_MemPool].object_list;
while (list->next != list)
{
object = rt_list_entry(list->next, struct rt_object, list);
if (rt_object_is_systemobject(object) == RT_TRUE)
{
/* detach static object */
rt_mp_detach((rt_mp_t)object);
}
else
{
/* delete dynamic object */
rt_mp_delete((rt_mp_t)object);
}
}
#endif
#ifdef RT_USING_DEVICE
/* delete devices */
list = &module->module_object[RT_Object_Class_Device].object_list;
while (list->next != list)
{
object = rt_list_entry(list->next, struct rt_object, list);
rt_device_unregister((rt_device_t)object);
}
#endif
/* delete timers */
list = &module->module_object[RT_Object_Class_Timer].object_list;
while (list->next != list)
{
object = rt_list_entry(list->next, struct rt_object, list);
if (rt_object_is_systemobject(object) == RT_TRUE)
{
/* detach static object */
rt_timer_detach((rt_timer_t)object);
}
else
{
/* delete dynamic object */
rt_timer_delete((rt_timer_t)object);
}
}
/* delete command line */ /* delete command line */
if (module->module_cmd_line != RT_NULL) if (module->module_cmd_line != RT_NULL)
{ {
@ -1454,20 +1220,6 @@ rt_err_t rt_module_destroy(rt_module_t module)
} }
} }
#ifdef RT_USING_SLAB
if (module->page_cnt > 0)
{
struct rt_page_info *page = (struct rt_page_info *)module->page_array;
rt_kprintf("Module: warning - memory still hasn't been free finished\n");
while (module->page_cnt != 0)
{
rt_module_free_page(module, page[0].page_ptr, page[0].npage);
}
}
#endif
/* release module space memory */ /* release module space memory */
rt_free(module->module_space); rt_free(module->module_space);
@ -1479,11 +1231,6 @@ rt_err_t rt_module_destroy(rt_module_t module)
if (module->symtab != RT_NULL) if (module->symtab != RT_NULL)
rt_free(module->symtab); rt_free(module->symtab);
#ifdef RT_USING_SLAB
if (module->page_array != RT_NULL)
rt_free(module->page_array);
#endif
/* delete module object */ /* delete module object */
rt_object_delete((rt_object_t)module); rt_object_delete((rt_object_t)module);
@ -1499,10 +1246,6 @@ rt_err_t rt_module_destroy(rt_module_t module)
*/ */
rt_err_t rt_module_unload(rt_module_t module) rt_err_t rt_module_unload(rt_module_t module)
{ {
struct rt_object *object;
struct rt_list_node *list;
rt_bool_t mdelete = RT_TRUE;
RT_DEBUG_NOT_IN_INTERRUPT; RT_DEBUG_NOT_IN_INTERRUPT;
/* check parameter */ /* check parameter */
@ -1510,34 +1253,7 @@ rt_err_t rt_module_unload(rt_module_t module)
return -RT_ERROR; return -RT_ERROR;
rt_enter_critical(); rt_enter_critical();
if (!(module->parent.flag & RT_MODULE_FLAG_WITHOUTENTRY)) /* invoke module cleanup */
{
/* delete module in main thread destroy */
mdelete = RT_FALSE;
/* delete all sub-threads */
list = &module->module_object[RT_Object_Class_Thread].object_list;
while (list->next != list)
{
object = rt_list_entry(list->next, struct rt_object, list);
if (rt_object_is_systemobject(object) == RT_TRUE)
{
/* detach static object */
rt_thread_detach((rt_thread_t)object);
}
else
{
/* delete dynamic object */
rt_thread_delete((rt_thread_t)object);
}
}
/* delete the main thread of module */
if (module->module_thread != RT_NULL)
{
rt_thread_delete(module->module_thread);
}
}
rt_exit_critical(); rt_exit_critical();
#ifdef RT_USING_HOOK #ifdef RT_USING_HOOK
@ -1547,11 +1263,6 @@ rt_err_t rt_module_unload(rt_module_t module)
} }
#endif #endif
if (mdelete == RT_TRUE)
{
rt_module_destroy(module);
}
return RT_EOK; return RT_EOK;
} }
@ -1598,462 +1309,4 @@ rt_module_t rt_module_find(const char *name)
} }
RTM_EXPORT(rt_module_find); RTM_EXPORT(rt_module_find);
#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)
{
void *chunk;
struct rt_page_info *page;
rt_module_t self_module;
self_module = rt_module_self();
RT_ASSERT(self_module != RT_NULL);
chunk = rt_page_alloc(npages);
if (chunk == RT_NULL)
return RT_NULL;
page = (struct rt_page_info *)self_module->page_array;
page[self_module->page_cnt].page_ptr = chunk;
page[self_module->page_cnt].npage = npages;
self_module->page_cnt ++;
RT_ASSERT(self_module->page_cnt <= PAGE_COUNT_MAX);
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_malloc_page 0x%x %d\n",
chunk, npages));
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
*/
static void rt_module_free_page(rt_module_t module,
void *page_ptr,
rt_size_t npages)
{
int i, index;
struct rt_page_info *page;
rt_module_t self_module;
self_module = rt_module_self();
RT_ASSERT(self_module != RT_NULL);
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_free_page 0x%x %d\n",
page_ptr, npages));
rt_page_free(page_ptr, npages);
page = (struct rt_page_info *)module->page_array;
for (i = 0; i < module->page_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);
page[i].npage -= npages;
}
else if (page[i].npage == npages)
{
for (index = i; index < module->page_cnt - 1; index ++)
{
page[index].page_ptr = page[index + 1].page_ptr;
page[index].npage = page[index + 1].npage;
}
page[module->page_cnt - 1].page_ptr = RT_NULL;
page[module->page_cnt - 1].npage = 0;
module->page_cnt --;
}
else
RT_ASSERT(RT_FALSE);
self_module->page_cnt --;
return;
}
}
/* should not get here */
RT_ASSERT(RT_FALSE);
}
/**
* rt_module_malloc - allocate memory block in free list
*/
void *rt_module_malloc(rt_size_t size)
{
struct rt_mem_head *b, *n, *up;
struct rt_mem_head **prev;
rt_uint32_t npage;
rt_size_t nunits;
rt_module_t self_module;
self_module = rt_module_self();
RT_ASSERT(self_module != RT_NULL);
RT_DEBUG_NOT_IN_INTERRUPT;
nunits = (size + sizeof(struct rt_mem_head) - 1) /
sizeof(struct rt_mem_head)
+ 1;
RT_ASSERT(size != 0);
RT_ASSERT(nunits != 0);
rt_sem_take(&mod_sem, RT_WAITING_FOREVER);
for (prev = (struct rt_mem_head **)&self_module->mem_list;
(b = *prev) != RT_NULL;
prev = &(b->next))
{
if (b->size > nunits)
{
/* split memory */
n = b + nunits;
n->next = b->next;
n->size = b->size - nunits;
b->size = nunits;
*prev = n;
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_malloc 0x%x, %d\n",
b + 1, size));
rt_sem_release(&mod_sem);
return (void *)(b + 1);
}
if (b->size == nunits)
{
/* this node fit, remove this node */
*prev = b->next;
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_malloc 0x%x, %d\n",
b + 1, size));
rt_sem_release(&mod_sem);
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 = (struct rt_mem_head **)&self_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 - free memory block in free list
*/
void rt_module_free(rt_module_t module, void *addr)
{
struct rt_mem_head *b, *n, *r;
struct rt_mem_head **prev;
RT_DEBUG_NOT_IN_INTERRUPT;
RT_ASSERT(addr);
RT_ASSERT((((rt_uint32_t)addr) & (sizeof(struct rt_mem_head) - 1)) == 0);
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("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;
while ((b = *prev) != RT_NULL)
{
RT_ASSERT(b->size > 0);
RT_ASSERT(b > n || 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)
{
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(module, b, npage);
}
}
/* unlock */
rt_sem_release(&mod_sem);
return;
}
if (b == n + n->size)
{
n->size = b->size + n->size;
n->next = b->next;
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(module, n, npage);
}
}
else
{
*prev = n;
}
/* unlock */
rt_sem_release(&mod_sem);
return;
}
if (b > n + n->size)
break;
prev = &(b->next);
}
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(module, 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;
}
/* unlock */
rt_sem_release(&mod_sem);
}
/**
* rt_module_realloc - realloc memory block in free list
*/
void *rt_module_realloc(void *ptr, rt_size_t size)
{
struct rt_mem_head *b, *p, *prev, *tmpp;
rt_size_t nunits;
rt_module_t self_module;
self_module = rt_module_self();
RT_ASSERT(self_module != RT_NULL);
RT_DEBUG_NOT_IN_INTERRUPT;
if (!ptr)
return rt_module_malloc(size);
if (size == 0)
{
rt_module_free(self_module, ptr);
return RT_NULL;
}
nunits = (size + sizeof(struct rt_mem_head) - 1) /
sizeof(struct rt_mem_head)
+ 1;
b = (struct rt_mem_head *)ptr - 1;
if (nunits <= b->size)
{
/* new size is smaller or equal then before */
if (nunits == b->size)
return ptr;
else
{
p = b + nunits;
p->size = b->size - nunits;
b->size = nunits;
rt_module_free(self_module, (void *)(p + 1));
return (void *)(b + 1);
}
}
else
{
/* more space then required */
prev = (struct rt_mem_head *)self_module->mem_list;
for (p = prev->next;
p != (b->size + b) && p != RT_NULL;
prev = p, p = p->next)
{
break;
}
/* available block after ap in freelist */
if (p != RT_NULL &&
(p->size >= (nunits - (b->size))) &&
p == (b + b->size))
{
/* perfect match */
if (p->size == (nunits - (b->size)))
{
b->size = nunits;
prev->next = p->next;
}
else /* more space then required, split block */
{
/* pointer to old header */
tmpp = p;
p = b + nunits;
/* restoring old pointer */
p->next = tmpp->next;
/* new size for p */
p->size = tmpp->size + b->size - nunits;
b->size = nunits;
prev->next = p;
}
self_module->mem_list = (void *)prev;
return (void *)(b + 1);
}
else /* allocate new memory and copy old data */
{
if ((p = rt_module_malloc(size)) == RT_NULL)
return RT_NULL;
rt_memmove(p, (b + 1), ((b->size) * sizeof(struct rt_mem_head)));
rt_module_free(self_module, (void *)(b + 1));
return (void *)(p);
}
}
}
#ifdef RT_USING_FINSH
#include <finsh.h>
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;
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;
page = (struct rt_page_info *)module->page_array;
for (i = 0; i < module->page_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 /* RT_USING_FINSH */
#endif /* RT_USING_SLAB */
#endif #endif

View File

@ -252,15 +252,9 @@ void rt_object_init(struct rt_object *object,
register rt_base_t temp; register rt_base_t temp;
struct rt_object_information *information; struct rt_object_information *information;
#ifdef RT_USING_MODULE
/* get module object information */
information = (rt_module_self() != RT_NULL) ?
&rt_module_self()->module_object[type] : rt_object_get_information(type);
#else
/* get object information */ /* get object information */
information = rt_object_get_information(type); information = rt_object_get_information(type);
RT_ASSERT(information != RT_NULL); RT_ASSERT(information != RT_NULL);
#endif
/* initialize object's parameters */ /* initialize object's parameters */
@ -324,18 +318,9 @@ rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
RT_DEBUG_NOT_IN_INTERRUPT; RT_DEBUG_NOT_IN_INTERRUPT;
#ifdef RT_USING_MODULE
/*
* get module object information,
* module object should be managed by kernel object container
*/
information = (rt_module_self() != RT_NULL && (type != RT_Object_Class_Module)) ?
&rt_module_self()->module_object[type] : rt_object_get_information(type);
#else
/* get object information */ /* get object information */
information = rt_object_get_information(type); information = rt_object_get_information(type);
RT_ASSERT(information != RT_NULL); RT_ASSERT(information != RT_NULL);
#endif
object = (struct rt_object *)RT_KERNEL_MALLOC(information->object_size); object = (struct rt_object *)RT_KERNEL_MALLOC(information->object_size);
if (object == RT_NULL) if (object == RT_NULL)
@ -458,65 +443,6 @@ rt_object_t rt_object_find(const char *name, rt_uint8_t type)
/* which is invoke in interrupt status */ /* which is invoke in interrupt status */
RT_DEBUG_NOT_IN_INTERRUPT; RT_DEBUG_NOT_IN_INTERRUPT;
#ifdef RT_USING_MODULE
/* check whether to find a object inside a module. */
{
const char *name_ptr;
int module_name_length;
name_ptr = name;
while ((*name_ptr != '\0') && (*name_ptr != '/'))
name_ptr ++;
if (*name_ptr == '/')
{
struct rt_module *module = RT_NULL;
/* get the name length of module */
module_name_length = name_ptr - name;
/* enter critical */
rt_enter_critical();
/* find module */
information = rt_object_get_information(RT_Object_Class_Module);
RT_ASSERT(information != RT_NULL);
for (node = information->object_list.next;
node != &(information->object_list);
node = node->next)
{
object = rt_list_entry(node, struct rt_object, list);
if ((rt_strncmp(object->name, name, module_name_length) == 0) &&
(module_name_length == RT_NAME_MAX || object->name[module_name_length] == '\0'))
{
/* get module */
module = (struct rt_module *)object;
break;
}
}
rt_exit_critical();
/* there is no this module inside the system */
if (module == RT_NULL) return RT_NULL;
/* get the object pool of module */
information = &(module->module_object[type]);
/* get object name */
while ((*name_ptr == '/') && (*name_ptr != '\0')) name_ptr ++;
if (*name_ptr == '\0')
{
if (type == RT_Object_Class_Module) return object;
return RT_NULL;
}
/* point to the object name */
name = name_ptr;
}
}
#endif
/* enter critical */ /* enter critical */
rt_enter_critical(); rt_enter_critical();