summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorqiuyiuestc <[email protected]>2010-10-28 01:21:47 +0000
committerqiuyiuestc <[email protected]>2010-10-28 01:21:47 +0000
commitfb7d4122fc97be364cf2ce76380b0e5465aba7eb (patch)
tree5149aa8116873baaeb7b8e9cb7160a5011aa10bd /src
parenta6f06d24cfec32dddee27a1ce61920fc4007d68a (diff)
implement module memory allocator
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1030 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'src')
-rw-r--r--src/idle.c29
-rw-r--r--src/ipc.c19
-rw-r--r--src/kservice.c2
-rw-r--r--src/mempool.c8
-rw-r--r--src/module.c150
-rw-r--r--src/object.c20
-rw-r--r--src/scheduler.c4
-rw-r--r--src/slab.c24
-rw-r--r--src/thread.c8
9 files changed, 231 insertions, 33 deletions
diff --git a/src/idle.c b/src/idle.c
index 6d5ce9fca0..a0a87677e2 100644
--- a/src/idle.c
+++ b/src/idle.c
@@ -64,9 +64,8 @@ void rt_thread_idle_excute(void)
rt_base_t lock;
rt_thread_t thread;
#ifdef RT_USING_MODULE
- rt_module_t module;
+ rt_module_t module = RT_NULL;
#endif
-
/* disable interrupt */
lock = rt_hw_interrupt_disable();
@@ -76,9 +75,16 @@ void rt_thread_idle_excute(void)
/* get defunct thread */
thread = rt_list_entry(rt_thread_defunct.next, struct rt_thread, tlist);
- /* get thread's parent module */
#ifdef RT_USING_MODULE
- module = thread->module_parent;
+ /* get thread's parent module */
+ module = (rt_module_t)thread->module_id;
+
+ /* if the thread is module's main thread */
+ if(module->module_thread == thread)
+ {
+ /* detach module's main thread */
+ module->module_thread = RT_NULL;
+ }
#endif
/* remove defunct thread */
rt_list_remove(&(thread->tlist));
@@ -96,15 +102,10 @@ void rt_thread_idle_excute(void)
rt_hw_interrupt_enable(lock);
#ifdef RT_USING_MODULE
- if(module != RT_NULL)
- {
- /* if the thread is module's main thread */
- if(module->module_thread == thread)
- {
- /* detach module's main thread */
- module->module_thread = RT_NULL;
- }
- }
+ /* 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);
+ else
#endif
/* release thread's stack */
rt_free(thread->stack_addr);
@@ -122,7 +123,7 @@ void rt_thread_idle_excute(void)
/* unload module */
rt_module_unload(module);
}
- }
+ }
#endif //RT_USING_MODULE
}
diff --git a/src/ipc.c b/src/ipc.c
index 986a39f6a0..96b11410c1 100644
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -32,6 +32,7 @@
* is RT_IPC_FLAG_PRIO
* 2010-01-20 mbbill remove rt_ipc_object_decrease function.
* 2010-04-20 Bernard move memcpy outside interrupt disable in mq
+ * 2010-10-26 yi.qiu add module support in rt_mp_delete and rt_mq_delete
*/
#include <rtthread.h>
@@ -1228,6 +1229,13 @@ rt_err_t rt_mb_delete (rt_mailbox_t mb)
/* resume all suspended thread */
rt_ipc_object_resume_all(&(mb->parent));
+#ifdef RT_USING_MODULE
+ /* 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);
+ else
+#endif
+
/* free mailbox pool */
rt_free(mb->msg_pool);
@@ -1580,10 +1588,17 @@ rt_err_t rt_mq_delete (rt_mq_t mq)
/* resume all suspended thread */
rt_ipc_object_resume_all(&(mq->parent));
- /* free mailbox pool */
+#ifdef RT_USING_MODULE
+ /* 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);
+ else
+#endif
+
+ /* free message queue pool */
rt_free(mq->msg_pool);
- /* delete mailbox object */
+ /* delete message queue object */
rt_object_delete(&(mq->parent.parent));
return RT_EOK;
diff --git a/src/kservice.c b/src/kservice.c
index e5c93f105d..18ccb67525 100644
--- a/src/kservice.c
+++ b/src/kservice.c
@@ -370,7 +370,7 @@ rt_ubase_t rt_strncmp(const char * cs, const char * ct, rt_ubase_t count)
*
* @return the result
*/
-rt_uint32_t rt_strcmp (const char *cs, const char *ct)
+rt_ubase_t rt_strcmp (const char *cs, const char *ct)
{
while (*cs && *cs == *ct)
cs++, ct++;
diff --git a/src/mempool.c b/src/mempool.c
index 53f1162802..5d91118604 100644
--- a/src/mempool.c
+++ b/src/mempool.c
@@ -15,6 +15,7 @@
* 2006-08-04 Bernard add hook support
* 2006-08-10 Bernard fix interrupt bug in rt_mp_alloc
* 2010-07-13 Bernard fix RT_ALIGN issue found by kuronca
+ * 2010-10-26 yi.qiu add module support in rt_mp_delete
*/
#include <rthw.h>
@@ -252,6 +253,13 @@ rt_err_t rt_mp_delete(rt_mp_t mp)
rt_hw_interrupt_enable(temp);
}
+#ifdef RT_USING_MODULE
+ /* 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);
+ else
+#endif
+
/* release allocated room */
rt_free(mp->start_address);
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>
diff --git a/src/object.c b/src/object.c
index 2b8ccb62d3..c992f0fe04 100644
--- a/src/object.c
+++ b/src/object.c
@@ -14,6 +14,7 @@
* 2006-05-18 Bernard fix the object init bug
* 2006-08-03 Bernard add hook support
* 2007-01-28 Bernard rename RT_OBJECT_Class_Static to RT_Object_Class_Static
+ * 2010-10-26 yi.qiu add module support in rt_object_allocate and rt_object_free
*/
#include <rtthread.h>
@@ -270,12 +271,23 @@ rt_object_t rt_object_allocate(enum rt_object_class_type type, const char* name)
/* no memory can be allocated */
return RT_NULL;
}
-
+
/* init object's parameters */
/* set object type */
object->type = type;
+ /* set object flag */
+ object->flag = 0;
+
+#ifdef RT_USING_MODULE
+ if(rt_module_self() != RT_NULL)
+ {
+ object->module_id = (void*)rt_module_self();
+ object->flag |= RT_OBJECT_FLAG_MODULE;
+ }
+#endif
+
/* copy name */
for (temp = 0; temp < RT_NAME_MAX; temp ++)
{
@@ -325,6 +337,12 @@ void rt_object_delete(rt_object_t object)
/* unlock interrupt */
rt_hw_interrupt_enable(temp);
+#ifdef RT_USING_MODULE
+ if(object->flag & RT_OBJECT_FLAG_MODULE)
+ rt_module_free((rt_module_t)object->module_id, object);
+ else
+#endif
+
/* free the memory of object */
rt_free(object);
}
diff --git a/src/scheduler.c b/src/scheduler.c
index d14328feba..340c01bb27 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -264,8 +264,8 @@ void rt_schedule()
rt_current_thread = to_thread;
#ifdef RT_USING_MODULE
- rt_module_set ((rt_current_thread->module_parent != RT_NULL) ?
- rt_current_thread->module_parent : RT_NULL);
+ rt_module_set ((rt_current_thread->module_id != RT_NULL) ?
+ (rt_module_t)rt_current_thread->module_id : RT_NULL);
#endif
#ifdef RT_USING_HOOK
diff --git a/src/slab.c b/src/slab.c
index dc904230f2..2624df1832 100644
--- a/src/slab.c
+++ b/src/slab.c
@@ -11,6 +11,7 @@
* Date Author Notes
* 2008-07-12 Bernard the first version
* 2010-07-13 Bernard fix RT_ALIGN issue found by kuronca
+ * 2010-10-23 yi.qiu add module memory allocator
*/
/*
@@ -52,6 +53,7 @@
#include <rthw.h>
#include <rtthread.h>
+#include "kservice.h"
/* #define RT_SLAB_DEBUG */
@@ -222,11 +224,11 @@ struct rt_page_head
rt_size_t page; /* number of page */
/* dummy */
- char dummy[RT_MM_PAGE_SIZE - (sizeof(struct rt_page_head*) + sizeof (rt_size_t))];
+ char dummy[RT_MM_PAGE_SIZE - (sizeof(struct rt_page_head*) + sizeof (rt_size_t) + sizeof(rt_list_t))];
};
static struct rt_page_head *rt_page_list;
-static void *rt_page_alloc(rt_size_t npages)
+void *rt_page_alloc(rt_size_t npages)
{
struct rt_page_head *b, *n;
struct rt_page_head **prev;
@@ -256,7 +258,7 @@ static void *rt_page_alloc(rt_size_t npages)
return b;
}
-static void rt_page_free(void *addr, rt_size_t npages)
+void rt_page_free(void *addr, rt_size_t npages)
{
struct rt_page_head *b, *n;
struct rt_page_head **prev;
@@ -450,6 +452,10 @@ void *rt_malloc(rt_size_t size)
/* zero size, return RT_NULL */
if (size == 0) return RT_NULL;
+#ifdef RT_USING_MODULE
+ if(rt_module_self() != RT_NULL) return rt_module_malloc(size);
+#endif
+
/*
* Handle large allocations directly. There should not be very many of
* these so performance is not a big issue.
@@ -630,6 +636,10 @@ void *rt_realloc(void *ptr, rt_size_t size)
return RT_NULL;
}
+#ifdef RT_USING_MODULE
+ if(rt_module_self() != RT_NULL) return rt_module_realloc(ptr, size);
+#endif
+
/*
* Get the original allocation's zone. If the new request winds up
* using the same chunk size we do not have to do anything.
@@ -715,6 +725,14 @@ void rt_free(void *ptr)
if (rt_free_hook != RT_NULL) rt_free_hook(ptr);
#endif
+#ifdef RT_USING_MODULE
+ if(rt_module_self() != RT_NULL)
+ {
+ rt_module_free(rt_module_self(), ptr);
+ return;
+ }
+#endif
+
/* get memory usage */
#ifdef RT_SLAB_DEBUG
rt_uint32 addr = ((rt_uint32_t)ptr & ~RT_MM_PAGE_MASK);
diff --git a/src/thread.c b/src/thread.c
index 536189070e..05eb403b56 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -19,7 +19,6 @@
* 2006-09-03 Bernard implement rt_thread_detach
* 2008-02-16 Bernard fix the rt_thread_timeout bug
* 2010-03-21 Bernard change the errno of rt_thread_delay/sleep to RT_EOK.
- * 2010-04-11 Yi.Qiu add module feature
*/
#include <rtthread.h>
@@ -73,13 +72,6 @@ static rt_err_t _rt_thread_init(struct rt_thread* thread,
/* error and flags */
thread->error = RT_EOK;
thread->stat = RT_THREAD_INIT;
- thread->flags = 0;
-
-#ifdef RT_USING_MODULE
- /* init module parent */
- thread->module_parent =
- (rt_module_self() != RT_NULL) ? rt_module_self() : RT_NULL;
-#endif
/* init user data */
thread->user_data = 0;