Kaynağa Gözat

implement module memory allocator

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1030 bbd45198-f89e-11dd-88c7-29a3b14d5316
qiuyiuestc 14 yıl önce
ebeveyn
işleme
fb7d4122fc
11 değiştirilmiş dosya ile 269 ekleme ve 57 silme
  1. 27 22
      include/rtdef.h
  2. 11 2
      include/rtthread.h
  3. 15 14
      src/idle.c
  4. 17 2
      src/ipc.c
  5. 1 1
      src/kservice.c
  6. 8 0
      src/mempool.c
  7. 148 2
      src/module.c
  8. 19 1
      src/object.c
  9. 2 2
      src/scheduler.c
  10. 21 3
      src/slab.c
  11. 0 8
      src/thread.c

+ 27 - 22
include/rtdef.h

@@ -10,7 +10,8 @@
  * Change Logs:
  * Date           Author       Notes
  * 2007-01-10     Bernard      the first version
- * 2008-07-12	  Bernard	   remove all rt_int8, rt_uint32_t etc typedef
+ * 2008-07-12     Bernard	  remove all rt_int8, rt_uint32_t etc typedef
+ * 2010-10-26     yi.qiu       add module support
  */
 #ifndef __RT_DEF_H__
 #define __RT_DEF_H__
@@ -163,6 +164,12 @@ typedef struct rt_list_node rt_list_t;					/* Type for lists. 							*/
  * @addtogroup KernelObject
  */
 /*@{*/
+
+/*
+ * kernel object macros
+ */
+#define RT_OBJECT_FLAG_MODULE		0x80			/* is module object. 						*/
+
 /*
  * Base structure of Kernel object
  */
@@ -174,6 +181,12 @@ struct rt_object
 	rt_uint8_t  type;
 	/* flag of kernel object			*/
 	rt_uint8_t  flag;
+	
+#ifdef RT_USING_MODULE
+	/* id of application module			*/
+	void* module_id;
+#endif	
+
 	/* list pointer of kernel object 	*/
 	rt_list_t	list;
 };
@@ -303,7 +316,6 @@ typedef struct rt_timer* rt_timer_t;
 #define RT_THREAD_CTRL_INFO				0x03			/* Get thread information. 					*/
 
 typedef struct rt_thread* rt_thread_t;
-typedef struct rt_module* rt_module_t;
 
 /*
  * Thread related structure
@@ -314,6 +326,10 @@ struct rt_thread
 	char        name[RT_NAME_MAX];						/* the name of thread 						*/
 	rt_uint8_t	type;									/* type of object 							*/
 	rt_uint8_t  flags;									/* thread's flags 							*/
+	
+#ifdef RT_USING_MODULE
+	void* module_id;								/* id of application module					*/
+#endif
 
 	rt_list_t	list;									/* the object list 							*/
 	rt_list_t	tlist;									/* the thread list 							*/
@@ -350,10 +366,6 @@ struct rt_thread
 
 	struct rt_timer thread_timer;						/* thread timer 							*/
 
-#ifdef RT_USING_MODULE
-	rt_module_t module_parent;							/* module parent 							*/
-#endif
-
 	rt_uint32_t user_data;								/* user data 								*/
 };
 /*@}*/
@@ -362,33 +374,26 @@ struct rt_thread
 /*
  * module system
  */
-enum rt_module_class_type
-{
-	RT_Module_Class_APP = 0,						/* application module								*/
-	RT_Module_Class_EXTENSION,		
-	RT_Module_Class_SERVICE,							/* service module 								*/
-	RT_Module_Class_Unknown							/* unknown module 								*/
-};
-
 struct rt_module
 {
 	/* inherit from object */
-	struct rt_object parent;
+	struct	rt_object parent;
 
-	rt_uint8_t* module_space;
+	rt_uint8_t* module_space;							/* module memory space						*/
 
-	void* module_entry;
-	rt_uint32_t stack_size;
+	void*		module_entry;							/* entry address of module's thread			*/
+	rt_thread_t module_thread;							/* stack size of module's thread			*/
+	rt_uint32_t stack_size;								/* priority of module's thread				*/
 	rt_uint32_t thread_priority;
-	rt_thread_t module_thread;
 
-	/* module memory pool */
-	rt_uint32_t mempool_size;
-	void* module_mempool;
+	/* module memory allocator */
+	void*		module_mem_list;
+	rt_list_t	module_page;
 
 	/* object in this module, module object is the last basic object type */
 	struct rt_object_information module_object[RT_Object_Class_Module];
 };
+typedef struct rt_module* rt_module_t;
 #endif
 
 /**

+ 11 - 2
include/rtthread.h

@@ -14,7 +14,7 @@
  * 2006-08-10     Bernard      add version information
  * 2007-01-28     Bernard      rename RT_OBJECT_Class_Static to RT_Object_Class_Static
  * 2007-03-03     Bernard      clean up the definitions to rtdef.h
- * 2010-04-11     yi.qiu          add module feature
+ * 2010-04-11     yi.qiu      add module feature
  */
 
 #ifndef __RT_THREAD_H__
@@ -184,6 +184,11 @@ void rt_memory_info(rt_uint32_t *total,
 void rt_malloc_sethook(void (*hook)(void *ptr, rt_uint32_t size));
 void rt_free_sethook(void (*hook)(void *ptr));
 #endif
+
+#ifdef RT_USING_SLAB
+void *rt_page_alloc(rt_size_t npages);
+void rt_page_free(void *addr, rt_size_t npages);
+#endif
 #endif
 /*@}*/
 
@@ -305,8 +310,11 @@ rt_err_t  rt_device_control(rt_device_t dev, rt_uint8_t cmd, void* arg);
 rt_module_t rt_module_load(const rt_uint8_t* name, void* module_ptr);
 rt_module_t rt_module_load_from_file(const rt_uint8_t* name, const char* filename);
 rt_err_t rt_module_unload(rt_module_t module);
-rt_err_t rt_module_self_set (rt_module_t module);
+void *rt_module_malloc(rt_size_t size);
+void *rt_module_realloc(void *ptr, rt_size_t size);
+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(char* name);
 #endif
  
@@ -343,6 +351,7 @@ void* rt_memset(void *src, int c, rt_ubase_t n);
 void* rt_memcpy(void *dest, const void *src, rt_ubase_t n);
 
 rt_ubase_t rt_strncmp(const char * cs, const char * ct, rt_ubase_t count);
+rt_ubase_t rt_strcmp (const char *cs, const char *ct);
 rt_ubase_t rt_strlen (const char *src);
 char *rt_strdup(const char *s);
 

+ 15 - 14
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
 	}
 	

+ 17 - 2
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;

+ 1 - 1
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++;

+ 8 - 0
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);
 

+ 148 - 2
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>
 

+ 19 - 1
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);
 }

+ 2 - 2
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

+ 21 - 3
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);

+ 0 - 8
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;