From 1c425607c3940e77e4d4893348bbc8d375004d37 Mon Sep 17 00:00:00 2001 From: "bernard.xiong@gmail.com" Date: Mon, 22 Oct 2012 03:12:21 +0000 Subject: [PATCH] fixed mutex issue in memheap; fixed compiling issue in kservice.c when COMPILER is not defined; add finsh for win32 porting. git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2365 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- components/finsh/cmd.c | 20 +++++++++- components/finsh/finsh.h | 50 +++++++++++++++++++++++- components/finsh/finsh_vm.c | 17 +++++++- components/finsh/shell.c | 40 +++++++++++++++++++ src/kservice.c | 7 ++-- src/memheap.c | 77 +++++++++++++++++++++++++++---------- 6 files changed, 182 insertions(+), 29 deletions(-) diff --git a/components/finsh/cmd.c b/components/finsh/cmd.c index d33cdebda..8cd82c2d5 100644 --- a/components/finsh/cmd.c +++ b/components/finsh/cmd.c @@ -27,10 +27,26 @@ * 2010-04-21 yi.qiu add list_module * 2012-04-29 goprife improve the command line auto-complete feature. * 2012-06-02 lgnq add list_memheap + * 2012-10-22 Bernard add MS VC++ patch. */ #include #include "finsh.h" +#if defined(_MSC_VER) +static struct finsh_syscall* _next_syscall(struct finsh_syscall* call) +{ + unsigned int *ptr; + ptr = (unsigned int*) (call + 1); + while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _syscall_table_end)) + ptr ++; + + return (struct finsh_syscall*)ptr; +} +#define _NEXT_SYSCALl(index) index=_next_syscall(index) +#else +#define _NEXT_SYSCALl(index) index++ +#endif + rt_inline unsigned int rt_list_len(const rt_list_t *l) { @@ -548,7 +564,7 @@ long list(void) rt_kprintf("--Function List:\n"); { struct finsh_syscall *index; - for (index = _syscall_table_begin; index < _syscall_table_end; index ++) + for (index = _syscall_table_begin; index < _syscall_table_end; _NEXT_SYSCALl(index)) { #ifdef FINSH_USING_DESCRIPTION rt_kprintf("%-16s -- %s\n", index->name, index->desc); @@ -632,7 +648,7 @@ void list_prefix(char *prefix) /* checks in system function call */ { struct finsh_syscall* index; - for (index = _syscall_table_begin; index < _syscall_table_end; index ++) + for (index = _syscall_table_begin; index < _syscall_table_end; _NEXT_SYSCALl(index)) { if (str_is_prefix(prefix, index->name) == 0) { diff --git a/components/finsh/finsh.h b/components/finsh/finsh.h index 03a2e4778..10ef09da0 100644 --- a/components/finsh/finsh.h +++ b/components/finsh/finsh.h @@ -16,6 +16,11 @@ #include +#if defined(_MSC_VER) +#pragma section("FSymTab$f",read) +#pragma section("VSymTab",read) +#endif + /* -- the beginning of option -- */ #define FINSH_NAME_MAX 16 /* max length of identifier */ #define FINSH_NODE_MAX 16 /* max number of node */ @@ -119,6 +124,9 @@ struct finsh_syscall #endif syscall_func func; /* the function address of system call */ }; +#if defined(_MSC_VER) +#pragma pack(pop) +#endif /* system call item */ struct finsh_syscall_item { @@ -132,6 +140,7 @@ extern struct finsh_syscall_item *global_syscall_list; struct finsh_syscall* finsh_syscall_lookup(const char* name); /* system variable table */ + struct finsh_sysvar { const char* name; /* the name of variable */ @@ -141,6 +150,7 @@ struct finsh_sysvar u_char type; /* the type of variable */ void* var ; /* the address of variable */ }; + /* system variable item */ struct finsh_sysvar_item { @@ -163,6 +173,18 @@ struct finsh_sysvar* finsh_sysvar_lookup(const char* name); * @param name the name of function. * @param desc the description of function, which will show in help. */ +#ifdef _MSC_VER + #define FINSH_FUNCTION_EXPORT(name, desc) \ + const char __fsym_##name##_name[] = #name; \ + const char __fsym_##name##_desc[] = #desc; \ + __declspec(allocate("FSymTab$f")) const struct finsh_syscall __fsym_##name = \ + { \ + __fsym_##name##_name, \ + __fsym_##name##_desc, \ + (syscall_func)&name \ + }; + #pragma comment(linker, "/merge:FSymTab=mytext") +#else #define FINSH_FUNCTION_EXPORT(name, desc) \ const char __fsym_##name##_name[] = #name; \ const char __fsym_##name##_desc[] = #desc; \ @@ -172,6 +194,7 @@ struct finsh_sysvar* finsh_sysvar_lookup(const char* name); __fsym_##name##_desc, \ (syscall_func)&name \ }; +#endif /** * @ingroup finsh @@ -182,6 +205,17 @@ struct finsh_sysvar* finsh_sysvar_lookup(const char* name); * @param alias the alias name of function. * @param desc the description of function, which will show in help. */ +#ifdef _MSC_VER + #define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc) \ + const char __fsym_##name##_name[] = #alias; \ + const char __fsym_##name##_desc[] = #desc; \ + __declspec(allocate("FSymTab$f")) const struct finsh_syscall __fsym_##name = \ + { \ + __fsym_##name##_name, \ + __fsym_##name##_desc, \ + (syscall_func)&name \ + }; +#else #define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc) \ const char __fsym_##name##_name[] = #alias; \ const char __fsym_##name##_desc[] = #desc; \ @@ -191,7 +225,7 @@ struct finsh_sysvar* finsh_sysvar_lookup(const char* name); __fsym_##name##_desc, \ (syscall_func)&name \ }; - +#endif /** * @ingroup finsh * @@ -201,6 +235,18 @@ struct finsh_sysvar* finsh_sysvar_lookup(const char* name); * @param type the type of variable. * @param desc the description of function, which will show in help. */ +#ifdef _MSC_VER + #define FINSH_VAR_EXPORT(name, type, desc) \ + const char __vsym_##name##_name[] = #name; \ + const char __vsym_##name##_desc[] = #desc; \ + __declspec(allocate("VSymTab")) const struct finsh_sysvar __vsym_##name = \ + { \ + __vsym_##name##_name, \ + __vsym_##name##_desc, \ + type, \ + (void*)&name \ + }; +#else #define FINSH_VAR_EXPORT(name, type, desc) \ const char __vsym_##name##_name[] = #name; \ const char __vsym_##name##_desc[] = #desc; \ @@ -211,6 +257,7 @@ struct finsh_sysvar* finsh_sysvar_lookup(const char* name); type, \ (void*)&name \ }; +#endif #else #define FINSH_FUNCTION_EXPORT(name, desc) \ const char __fsym_##name##_name[] = #name; \ @@ -369,5 +416,4 @@ void finsh_syscall_append(const char* name, syscall_func func); */ void finsh_sysvar_append(const char* name, u_char type, void* addr); #endif - #endif diff --git a/components/finsh/finsh_vm.c b/components/finsh/finsh_vm.c index 3214bed15..c5b6dcf63 100644 --- a/components/finsh/finsh_vm.c +++ b/components/finsh/finsh_vm.c @@ -83,12 +83,27 @@ void finsh_syscall_append(const char* name, syscall_func func) } #endif +#if defined(_MSC_VER) +static struct finsh_syscall* _next_syscall(struct finsh_syscall* call) +{ + unsigned int *ptr; + ptr = (unsigned int*) (call + 1); + while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _syscall_table_end)) + ptr ++; + + return (struct finsh_syscall*)ptr; +} +#define _NEXT_SYSCALL(index) index=_next_syscall(index) +#else +#define _NEXT_SYSCALL(index) index++ +#endif + struct finsh_syscall* finsh_syscall_lookup(const char* name) { struct finsh_syscall* index; struct finsh_syscall_item* item; - for (index = _syscall_table_begin; index < _syscall_table_end; index ++) + for (index = _syscall_table_begin; index < _syscall_table_end; _NEXT_SYSCALL(index)) { if (strcmp(index->name, name) == 0) return index; diff --git a/components/finsh/shell.c b/components/finsh/shell.c index 601bf647f..c10c193c9 100644 --- a/components/finsh/shell.c +++ b/components/finsh/shell.c @@ -304,7 +304,17 @@ rt_bool_t finsh_handle_history(struct finsh_shell* shell, char ch) if (shell->use_history) { +#if defined(_WIN32) + int i; + rt_kprintf("\r"); + + for(i=0; i<= 60; i++) + putchar(' '); + rt_kprintf("\r"); + +#else rt_kprintf("\033[2K\r"); +#endif rt_kprintf("%s%s", FINSH_PROMPT, shell->line); return RT_TRUE;; } @@ -459,6 +469,26 @@ void finsh_system_var_init(const void* begin, const void* end) extern "asm" int __vsymtab_start; extern "asm" int __vsymtab_end; #endif +#elif defined(_MSC_VER) +#pragma section("FSymTab$a", read) +const char __fsym_begin_name[] = "__start"; +const char __fsym_begin_desc[] = "begin of finsh"; +__declspec(allocate("FSymTab$a")) const struct finsh_syscall __fsym_begin = +{ + __fsym_begin_name, + __fsym_begin_desc, + NULL +}; + +#pragma section("FSymTab$z", read) +const char __fsym_end_name[] = "__end"; +const char __fsym_end_desc[] = "end of finsh"; +__declspec(allocate("FSymTab$z")) const struct finsh_syscall __fsym_end = +{ + __fsym_end_name, + __fsym_end_desc, + NULL +}; #endif /* @@ -493,6 +523,16 @@ void finsh_system_init(void) #elif defined(__ADSPBLACKFIN__) /* for VisualDSP++ Compiler */ finsh_system_function_init(&__fsymtab_start, &__fsymtab_end); finsh_system_var_init(&__vsymtab_start, &__vsymtab_end); +#elif defined(_MSC_VER) + unsigned int *ptr_begin, *ptr_end; + + ptr_begin = (unsigned int*)&__fsym_begin; ptr_begin += (sizeof(struct finsh_syscall)/sizeof(unsigned int)); + while (*ptr_begin == 0) ptr_begin ++; + + ptr_end = (unsigned int*) &__fsym_end; ptr_end --; + while (*ptr_end == 0) ptr_end --; + + finsh_system_function_init(ptr_begin, ptr_end); #endif #endif diff --git a/src/kservice.c b/src/kservice.c index 49b787aaf..991cf5016 100644 --- a/src/kservice.c +++ b/src/kservice.c @@ -1052,9 +1052,10 @@ void rt_hw_console_output(const char *str) #elif defined(__CC_ARM) __weak void rt_hw_console_output(const char *str) #elif defined(__IAR_SYSTEMS_ICC__) -#if __VER__ > 540 -__weak -#endif + #if __VER__ > 540 + __weak + #endif +#else void rt_hw_console_output(const char *str) #endif { diff --git a/src/memheap.c b/src/memheap.c index 3992ae440..458b8593e 100644 --- a/src/memheap.c +++ b/src/memheap.c @@ -10,6 +10,7 @@ * Change Logs: * Date Author Notes * 2012-04-10 Bernard first implementation + * 2012-10-16 Bernard add the mutex lock for heap object. */ #include @@ -96,6 +97,9 @@ rt_err_t rt_memheap_init(struct rt_memheap *memheap, const char *name, /* not in free list */ item->next_free = item->prev_free = RT_NULL; + /* initialize mutex lock */ + rt_mutex_init(&(memheap->lock), name, RT_IPC_FLAG_FIFO); + RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("memory heap: start addr 0x%08x, size %d, free list header 0x%08x", start_addr, size, &(memheap->free_header))); @@ -105,6 +109,9 @@ RTM_EXPORT(rt_memheap_init); rt_err_t rt_memheap_detach(struct rt_memheap *heap) { + RT_ASSERT(heap); + + rt_object_detach(&(heap->lock.parent.parent)); rt_object_detach(&(heap->parent)); /* Return a successful completion. */ @@ -112,12 +119,13 @@ rt_err_t rt_memheap_detach(struct rt_memheap *heap) } RTM_EXPORT(rt_memheap_detach); -void *rt_memheap_alloc(struct rt_memheap *pool_ptr, rt_uint32_t size) +void *rt_memheap_alloc(struct rt_memheap *heap, rt_uint32_t size) { + rt_err_t result; rt_uint32_t free_size; struct rt_memheap_item *header_ptr; - RT_ASSERT(pool_ptr != RT_NULL); + RT_ASSERT(heap != RT_NULL); /* align allocated size */ size = RT_ALIGN(size, RT_ALIGN_SIZE); @@ -126,13 +134,22 @@ void *rt_memheap_alloc(struct rt_memheap *pool_ptr, rt_uint32_t size) RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("allocate %d", size)); - if (size < pool_ptr->available_size) + if (size < heap->available_size) { /* search on free list */ free_size = 0; + + /* lock memheap */ + result = rt_mutex_take(&(heap->lock), RT_WAITING_FOREVER); + if (result != RT_EOK) + { + rt_set_errno(result); + return RT_NULL; + } + /* get the first free memory block */ - header_ptr = pool_ptr->free_list->next_free; - while (header_ptr != pool_ptr->free_list && free_size < size) + header_ptr = heap->free_list->next_free; + while (header_ptr != heap->free_list && free_size < size) { /* get current freed memory block size */ free_size = (rt_uint32_t)(header_ptr->next) - (rt_uint32_t)header_ptr - RT_MEMHEAP_SIZE; @@ -165,7 +182,7 @@ void *rt_memheap_alloc(struct rt_memheap *pool_ptr, rt_uint32_t size) new_ptr->magic = RT_MEMHEAP_MAGIC; /* put the pool pointer into the new block. */ - new_ptr->pool_ptr = pool_ptr; + new_ptr->pool_ptr = heap; /* break down the block list */ new_ptr->prev = header_ptr; @@ -180,20 +197,20 @@ void *rt_memheap_alloc(struct rt_memheap *pool_ptr, rt_uint32_t size) header_ptr->prev_free = RT_NULL; /* insert new_ptr to free list */ - new_ptr->next_free = pool_ptr->free_list->next_free; - new_ptr->prev_free = pool_ptr->free_list; - pool_ptr->free_list->next_free->prev_free = new_ptr; - pool_ptr->free_list->next_free = new_ptr; + new_ptr->next_free = heap->free_list->next_free; + new_ptr->prev_free = heap->free_list; + heap->free_list->next_free->prev_free = new_ptr; + heap->free_list->next_free = new_ptr; RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new ptr: nf 0x%08x, pf 0x%08x", new_ptr->next_free, new_ptr->prev_free)); /* decrement the available byte count. */ - pool_ptr->available_size = pool_ptr->available_size - size - RT_MEMHEAP_SIZE; + heap->available_size = heap->available_size - size - RT_MEMHEAP_SIZE; } else { /* decrement the entire free size from the available bytes count. */ - pool_ptr->available_size = pool_ptr->available_size - free_size; + heap->available_size = heap->available_size - free_size; /* remove header_ptr from free list */ RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("one block: h[0x%08x], nf 0x%08x, pf 0x%08x", header_ptr, @@ -205,6 +222,9 @@ void *rt_memheap_alloc(struct rt_memheap *pool_ptr, rt_uint32_t size) header_ptr->prev_free = RT_NULL; } + /* release lock */ + rt_mutex_release(&(heap->lock)); + /* Mark the allocated block as not available. */ header_ptr->magic |= RT_MEMHEAP_USED; @@ -214,6 +234,9 @@ void *rt_memheap_alloc(struct rt_memheap *pool_ptr, rt_uint32_t size) return (void *)((rt_uint8_t *)header_ptr + RT_MEMHEAP_SIZE)); } + + /* release lock */ + rt_mutex_release(&(heap->lock)); } RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("allocate memory: failed\n")); @@ -225,7 +248,8 @@ RTM_EXPORT(rt_memheap_alloc); void rt_memheap_free(void *ptr) { - struct rt_memheap *pool_ptr; + rt_err_t result; + struct rt_memheap *heap; struct rt_memheap_item *header_ptr, *new_ptr; rt_uint32_t insert_header; @@ -240,13 +264,21 @@ void rt_memheap_free(void *ptr) RT_ASSERT((header_ptr->magic & RT_MEMHEAP_MASK) == RT_MEMHEAP_MAGIC); /* get pool ptr */ - pool_ptr = header_ptr->pool_ptr; + heap = header_ptr->pool_ptr; + + /* lock memheap */ + result = rt_mutex_take(&(heap->lock), RT_WAITING_FOREVER); + if (result != RT_EOK) + { + rt_set_errno(result); + return ; + } /* Mark the memory as available. */ header_ptr->magic &= ~RT_MEMHEAP_USED; /* Adjust the available number of bytes. */ - pool_ptr->available_size = pool_ptr->available_size + + heap->available_size = heap->available_size + ((rt_uint32_t)(header_ptr->next) - (rt_uint32_t)header_ptr) - RT_MEMHEAP_SIZE; @@ -256,7 +288,7 @@ void rt_memheap_free(void *ptr) RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("merge: left node 0x%08x", header_ptr->prev)); /* adjust the available number of bytes. */ - pool_ptr->available_size = pool_ptr->available_size + RT_MEMHEAP_SIZE; + heap->available_size = heap->available_size + RT_MEMHEAP_SIZE; /* yes, merge block with previous neighbor. */ (header_ptr->prev)->next = header_ptr->next; @@ -272,7 +304,7 @@ void rt_memheap_free(void *ptr) if (!RT_MEMHEAP_IS_USED(header_ptr->next)) { /* adjust the available number of bytes. */ - pool_ptr->available_size = pool_ptr->available_size + RT_MEMHEAP_SIZE; + heap->available_size = heap->available_size + RT_MEMHEAP_SIZE; /* merge block with next neighbor. */ new_ptr = header_ptr->next; @@ -291,14 +323,17 @@ void rt_memheap_free(void *ptr) if (insert_header) { /* no left merge, insert to free list */ - header_ptr->next_free = pool_ptr->free_list->next_free; - header_ptr->prev_free = pool_ptr->free_list; - pool_ptr->free_list->next_free->prev_free = header_ptr; - pool_ptr->free_list->next_free = header_ptr; + header_ptr->next_free = heap->free_list->next_free; + header_ptr->prev_free = heap->free_list; + heap->free_list->next_free->prev_free = header_ptr; + heap->free_list->next_free = header_ptr; RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("insert to free list: nf 0x%08x, pf 0x%08x", header_ptr->next_free, header_ptr->prev_free)); } + + /* release lock */ + rt_mutex_release(&(heap->lock)); } RTM_EXPORT(rt_memheap_free);