Browse Source

add sys_fork support

shaojinchun 4 years ago
parent
commit
2c52093bba

+ 3 - 0
components/dfs/include/dfs.h

@@ -100,6 +100,9 @@ void dfs_unlock(void);
 void dfs_fd_lock(void);
 void dfs_fd_lock(void);
 void dfs_fd_unlock(void);
 void dfs_fd_unlock(void);
 
 
+void dfs_fm_lock(void);
+void dfs_fm_unlock(void);
+
 /* FD APIs */
 /* FD APIs */
 int fdt_fd_new(struct dfs_fdtable *fdt);
 int fdt_fd_new(struct dfs_fdtable *fdt);
 struct dfs_fd *fdt_fd_get(struct dfs_fdtable* fdt, int fd);
 struct dfs_fd *fdt_fd_get(struct dfs_fdtable* fdt, int fd);

+ 23 - 13
components/dfs/src/dfs_file.c

@@ -25,6 +25,16 @@ struct dfs_fnode_mgr
 
 
 static struct dfs_fnode_mgr dfs_fm;
 static struct dfs_fnode_mgr dfs_fm;
 
 
+void dfs_fm_lock(void)
+{
+    rt_mutex_take(&dfs_fm.lock, RT_WAITING_FOREVER);
+}
+
+void dfs_fm_unlock(void)
+{
+    rt_mutex_release(&dfs_fm.lock);
+}
+
 void dfs_fnode_mgr_init(void)
 void dfs_fnode_mgr_init(void)
 {
 {
     int i = 0;
     int i = 0;
@@ -97,13 +107,13 @@ int dfs_file_is_open(const char *pathname)
 
 
     fullpath = dfs_normalize_path(NULL, pathname);
     fullpath = dfs_normalize_path(NULL, pathname);
 
 
-    rt_mutex_take(&dfs_fm.lock, RT_WAITING_FOREVER);
+    dfs_fm_lock();
     fnode = dfs_fnode_find(fullpath, NULL);
     fnode = dfs_fnode_find(fullpath, NULL);
     if (fnode)
     if (fnode)
     {
     {
         ret = 1;
         ret = 1;
     }
     }
-    rt_mutex_release(&dfs_fm.lock);
+    dfs_fm_unlock();
 
 
     rt_free(fullpath);
     rt_free(fullpath);
     return ret;
     return ret;
@@ -140,7 +150,7 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags)
 
 
     LOG_D("open file:%s", fullpath);
     LOG_D("open file:%s", fullpath);
 
 
-    rt_mutex_take(&dfs_fm.lock, RT_WAITING_FOREVER);
+    dfs_fm_lock();
     /* fnode find */
     /* fnode find */
     fnode = dfs_fnode_find(fullpath, &hash_head);
     fnode = dfs_fnode_find(fullpath, &hash_head);
     if (fnode)
     if (fnode)
@@ -148,7 +158,7 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags)
         fnode->ref_count++;
         fnode->ref_count++;
         fd->pos   = 0;
         fd->pos   = 0;
         fd->fnode = fnode;
         fd->fnode = fnode;
-        rt_mutex_release(&dfs_fm.lock);
+        dfs_fm_unlock();
     }
     }
     else
     else
     {
     {
@@ -156,7 +166,7 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags)
         fs = dfs_filesystem_lookup(fullpath);
         fs = dfs_filesystem_lookup(fullpath);
         if (fs == NULL)
         if (fs == NULL)
         {
         {
-            rt_mutex_release(&dfs_fm.lock);
+            dfs_fm_unlock();
             rt_free(fullpath); /* release path */
             rt_free(fullpath); /* release path */
             return -ENOENT;
             return -ENOENT;
         }
         }
@@ -164,7 +174,7 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags)
         fnode = rt_calloc(1, sizeof(struct dfs_fnode));
         fnode = rt_calloc(1, sizeof(struct dfs_fnode));
         if (!fnode)
         if (!fnode)
         {
         {
-            rt_mutex_release(&dfs_fm.lock);
+            dfs_fm_unlock();
             rt_free(fullpath); /* release path */
             rt_free(fullpath); /* release path */
             return -ENOMEM;
             return -ENOMEM;
         }
         }
@@ -195,7 +205,7 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags)
         /* specific file system open routine */
         /* specific file system open routine */
         if (fnode->fops->open == NULL)
         if (fnode->fops->open == NULL)
         {
         {
-            rt_mutex_release(&dfs_fm.lock);
+            dfs_fm_unlock();
             /* clear fd */
             /* clear fd */
             if (fnode->path != fnode->fullpath)
             if (fnode->path != fnode->fullpath)
             {
             {
@@ -229,9 +239,9 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags)
             rt_free(fnode->path);
             rt_free(fnode->path);
             fd->fnode = NULL;
             fd->fnode = NULL;
             rt_free(fnode);
             rt_free(fnode);
-            rt_mutex_release(&dfs_fm.lock);
         }
         }
 
 
+        dfs_fm_unlock();
         LOG_D("%s open failed", fullpath);
         LOG_D("%s open failed", fullpath);
 
 
         return result;
         return result;
@@ -243,7 +253,7 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags)
         fnode->type = FT_DIRECTORY;
         fnode->type = FT_DIRECTORY;
         fnode->flags |= DFS_F_DIRECTORY;
         fnode->flags |= DFS_F_DIRECTORY;
     }
     }
-    rt_mutex_release(&dfs_fm.lock);
+    dfs_fm_unlock();
 
 
     LOG_D("open successful");
     LOG_D("open successful");
     return 0;
     return 0;
@@ -268,12 +278,12 @@ int dfs_file_close(struct dfs_fd *fd)
 
 
     if (fd->ref_count == 1)
     if (fd->ref_count == 1)
     {
     {
-        rt_mutex_take(&dfs_fm.lock, RT_WAITING_FOREVER);
+        dfs_fm_lock();
         fnode = fd->fnode;
         fnode = fd->fnode;
 
 
         if (fnode->ref_count <= 0)
         if (fnode->ref_count <= 0)
         {
         {
-            rt_mutex_release(&dfs_fm.lock);
+            dfs_fm_unlock();
             return -ENXIO;
             return -ENXIO;
         }
         }
 
 
@@ -285,7 +295,7 @@ int dfs_file_close(struct dfs_fd *fd)
         /* close fd error, return */
         /* close fd error, return */
         if (result < 0)
         if (result < 0)
         {
         {
-            rt_mutex_release(&dfs_fm.lock);
+            dfs_fm_unlock();
             return result;
             return result;
         }
         }
 
 
@@ -301,8 +311,8 @@ int dfs_file_close(struct dfs_fd *fd)
             }
             }
             rt_free(fnode->path);
             rt_free(fnode->path);
             rt_free(fnode);
             rt_free(fnode);
-            rt_mutex_release(&dfs_fm.lock);
         }
         }
+        dfs_fm_unlock();
     }
     }
 
 
     return result;
     return result;

+ 7 - 0
components/lwp/arch/arm/cortex-a/lwp_gcc.S

@@ -91,6 +91,13 @@ lwp_set_thread_context:
     ldr r0, [sp]
     ldr r0, [sp]
     mov pc, lr
     mov pc, lr
 
 
+.global lwp_get_user_sp
+lwp_get_user_sp:
+    cps #Mode_SYS
+    mov r0, sp
+    cps #Mode_SVC
+    mov pc, lr
+
 /*
 /*
  * void SVC_Handler(void);
  * void SVC_Handler(void);
  */
  */

+ 24 - 17
components/lwp/lwp.c

@@ -139,7 +139,7 @@ static struct process_aux *lwp_argscopy(struct rt_lwp *lwp, int argc, char **arg
     if (size > ARCH_PAGE_SIZE)
     if (size > ARCH_PAGE_SIZE)
         return RT_NULL;
         return RT_NULL;
 
 
-    /* args = (int*)lwp_map_user(lwp, 0, size); */
+    /* args = (int *)lwp_map_user(lwp, 0, size); */
     args = (int *)lwp_map_user(lwp, (void *)(KERNEL_VADDR_START - ARCH_PAGE_SIZE), size, 0);
     args = (int *)lwp_map_user(lwp, (void *)(KERNEL_VADDR_START - ARCH_PAGE_SIZE), size, 0);
     if (args == RT_NULL)
     if (args == RT_NULL)
         return RT_NULL;
         return RT_NULL;
@@ -404,17 +404,23 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
         off = eheader.e_phoff;
         off = eheader.e_phoff;
         process_header_size = eheader.e_phnum * sizeof pheader;
         process_header_size = eheader.e_phnum * sizeof pheader;
         if (process_header_size > ARCH_PAGE_SIZE)
         if (process_header_size > ARCH_PAGE_SIZE)
+        {
             return -RT_ERROR;
             return -RT_ERROR;
+        }
 #ifdef RT_USING_USERSPACE
 #ifdef RT_USING_USERSPACE
         va = (uint8_t *)lwp_map_user(lwp, (void *)(KERNEL_VADDR_START - ARCH_PAGE_SIZE * 2), process_header_size, 0);
         va = (uint8_t *)lwp_map_user(lwp, (void *)(KERNEL_VADDR_START - ARCH_PAGE_SIZE * 2), process_header_size, 0);
         if (!va)
         if (!va)
+        {
             return -RT_ERROR;
             return -RT_ERROR;
+        }
         pa = rt_hw_mmu_v2p(m_info, va);
         pa = rt_hw_mmu_v2p(m_info, va);
-        process_header = (uint8_t*)pa - PV_OFFSET;
+        process_header = (uint8_t *)pa - PV_OFFSET;
 #else
 #else
         process_header = (uint8_t *)rt_malloc(process_header_size);
         process_header = (uint8_t *)rt_malloc(process_header_size);
         if (!process_header)
         if (!process_header)
+        {
             return -RT_ERROR;
             return -RT_ERROR;
+        }
 #endif
 #endif
         check_off(off, len);
         check_off(off, len);
         lseek(fd, off, SEEK_SET);
         lseek(fd, off, SEEK_SET);
@@ -523,14 +529,14 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
                     while (size)
                     while (size)
                     {
                     {
                         pa = rt_hw_mmu_v2p(m_info, va);
                         pa = rt_hw_mmu_v2p(m_info, va);
-                        va_self = (void*)((char*)pa - PV_OFFSET);
+                        va_self = (void *)((char *)pa - PV_OFFSET);
                         LOG_D("va_self = %p pa = %p", va_self, pa);
                         LOG_D("va_self = %p pa = %p", va_self, pa);
                         tmp_len = (size < ARCH_PAGE_SIZE) ? size : ARCH_PAGE_SIZE;
                         tmp_len = (size < ARCH_PAGE_SIZE) ? size : ARCH_PAGE_SIZE;
                         tmp_len = load_fread(va_self, 1, tmp_len, fd);
                         tmp_len = load_fread(va_self, 1, tmp_len, fd);
                         rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, va_self, tmp_len);
                         rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, va_self, tmp_len);
                         read_len += tmp_len;
                         read_len += tmp_len;
                         size -= tmp_len;
                         size -= tmp_len;
-                        va = (void*)((char*)va + ARCH_PAGE_SIZE);
+                        va = (void *)((char *)va + ARCH_PAGE_SIZE);
                     }
                     }
                 }
                 }
 #else
 #else
@@ -541,7 +547,7 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
             if (pheader.p_filesz < pheader.p_memsz)
             if (pheader.p_filesz < pheader.p_memsz)
             {
             {
 #ifdef RT_USING_USERSPACE
 #ifdef RT_USING_USERSPACE
-                void *va = (void*)((char*)lwp->text_entry + pheader.p_filesz);
+                void *va = (void *)((char *)lwp->text_entry + pheader.p_filesz);
                 void *va_self;
                 void *va_self;
                 void *pa;
                 void *pa;
                 uint32_t size = pheader.p_memsz - pheader.p_filesz;
                 uint32_t size = pheader.p_memsz - pheader.p_filesz;
@@ -554,12 +560,12 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
                 {
                 {
                     size_s = (size < ARCH_PAGE_SIZE - off) ? size : ARCH_PAGE_SIZE - off;
                     size_s = (size < ARCH_PAGE_SIZE - off) ? size : ARCH_PAGE_SIZE - off;
                     pa = rt_hw_mmu_v2p(m_info, va);
                     pa = rt_hw_mmu_v2p(m_info, va);
-                    va_self = (void*)((char*)pa - PV_OFFSET);
-                    memset((void*)((char*)va_self + off), 0, size_s);
-                    rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void*)((char*)va_self + off), size_s);
+                    va_self = (void *)((char *)pa - PV_OFFSET);
+                    memset((void *)((char *)va_self + off), 0, size_s);
+                    rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)((char *)va_self + off), size_s);
                     off = 0;
                     off = 0;
                     size -= size_s;
                     size -= size_s;
-                    va = (void*)((char*)va + ARCH_PAGE_SIZE);
+                    va = (void *)((char *)va + ARCH_PAGE_SIZE);
                 }
                 }
 #else
 #else
                 memset((uint8_t *)lwp->text_entry + pheader.p_filesz, 0, (size_t)(pheader.p_memsz - pheader.p_filesz));
                 memset((uint8_t *)lwp->text_entry + pheader.p_filesz, 0, (size_t)(pheader.p_memsz - pheader.p_filesz));
@@ -874,19 +880,20 @@ pid_t lwp_execve(char *filename, int argc, char **argv, char **envp)
                                1024 * 4, 25, 200);
                                1024 * 4, 25, 200);
         if (thread != RT_NULL)
         if (thread != RT_NULL)
         {
         {
-            struct rt_lwp *lwp_self;
+            struct rt_lwp *self_lwp;
 
 
             thread->tid = tid;
             thread->tid = tid;
             lwp_tid_set_thread(tid, thread);
             lwp_tid_set_thread(tid, thread);
-            LOG_D("lwp kernel => (0x%08x, 0x%08x)\n", (rt_uint32_t)thread->stack_addr, (rt_uint32_t)thread->stack_addr + thread->stack_size);
+            LOG_D("lwp kernel => (0x%08x, 0x%08x)\n", (rt_uint32_t)thread->stack_addr,
+                    (rt_uint32_t)thread->stack_addr + thread->stack_size);
             level = rt_hw_interrupt_disable();
             level = rt_hw_interrupt_disable();
-            lwp_self = (struct rt_lwp *)rt_thread_self()->lwp;
-            if (lwp_self)
+            self_lwp = lwp_self();
+            if (self_lwp)
             {
             {
                 /* lwp add to children link */
                 /* lwp add to children link */
-                lwp->sibling = lwp_self->first_child;
-                lwp_self->first_child = lwp;
-                lwp->parent = lwp_self;
+                lwp->sibling = self_lwp->first_child;
+                self_lwp->first_child = lwp;
+                lwp->parent = self_lwp;
             }
             }
             thread->lwp = lwp;
             thread->lwp = lwp;
             rt_list_insert_after(&lwp->t_grp, &thread->sibling);
             rt_list_insert_after(&lwp->t_grp, &thread->sibling);
@@ -898,7 +905,7 @@ pid_t lwp_execve(char *filename, int argc, char **argv, char **envp)
             }
             }
 #endif
 #endif
 
 
-            if ((rt_console_get_foreground() == lwp_self) && !bg)
+            if ((rt_console_get_foreground() == self_lwp) && !bg)
             {
             {
                 rt_console_set_foreground(lwp);
                 rt_console_set_foreground(lwp);
             }
             }

+ 1 - 2
components/lwp/lwp.h

@@ -58,8 +58,7 @@ struct rt_lwp
 #endif
 #endif
 
 
     uint8_t lwp_type;
     uint8_t lwp_type;
-    uint8_t heap_cnt;
-    uint8_t reserv[2];
+    uint8_t reserv[3];
 
 
     struct rt_lwp *parent;
     struct rt_lwp *parent;
     struct rt_lwp *first_child;
     struct rt_lwp *first_child;

+ 20 - 5
components/lwp/lwp_avl.c

@@ -176,19 +176,34 @@ struct lwp_avl_struct *lwp_avl_find(avl_key_t key, struct lwp_avl_struct *ptree)
     return ptree;
     return ptree;
 }
 }
 
 
-void lwp_avl_traversal(struct lwp_avl_struct *ptree, void (*fun)(struct lwp_avl_struct *, void *), void *arg)
+int lwp_avl_traversal(struct lwp_avl_struct *ptree, int (*fun)(struct lwp_avl_struct *, void *), void *arg)
 {
 {
+    int ret;
+
     if (!ptree)
     if (!ptree)
     {
     {
-        return;
+        return 0;
     }
     }
     if (ptree->avl_left)
     if (ptree->avl_left)
     {
     {
-        lwp_avl_traversal(ptree->avl_left, fun, arg);
+        ret = lwp_avl_traversal(ptree->avl_left, fun, arg);
+        if (ret != 0)
+        {
+            return ret;
+        }
+    }
+    ret = (*fun)(ptree, arg);
+    if (ret != 0)
+    {
+        return ret;
     }
     }
-    (*fun)(ptree, arg);
     if (ptree->avl_right)
     if (ptree->avl_right)
     {
     {
-        lwp_avl_traversal(ptree->avl_right, fun, arg);
+        ret = lwp_avl_traversal(ptree->avl_right, fun, arg);
+        if (ret != 0)
+        {
+            return ret;
+        }
     }
     }
+    return ret;
 }
 }

+ 1 - 1
components/lwp/lwp_avl.h

@@ -36,7 +36,7 @@ struct lwp_avl_struct
 void lwp_avl_remove(struct lwp_avl_struct * node_to_delete, struct lwp_avl_struct ** ptree);
 void lwp_avl_remove(struct lwp_avl_struct * node_to_delete, struct lwp_avl_struct ** ptree);
 void lwp_avl_insert (struct lwp_avl_struct * new_node, struct lwp_avl_struct ** ptree);
 void lwp_avl_insert (struct lwp_avl_struct * new_node, struct lwp_avl_struct ** ptree);
 struct lwp_avl_struct* lwp_avl_find(avl_key_t key, struct lwp_avl_struct* ptree);
 struct lwp_avl_struct* lwp_avl_find(avl_key_t key, struct lwp_avl_struct* ptree);
-void lwp_avl_traversal(struct lwp_avl_struct* ptree, void (*fun)(struct lwp_avl_struct*, void *), void *arg);
+int lwp_avl_traversal(struct lwp_avl_struct* ptree, int (*fun)(struct lwp_avl_struct*, void *), void *arg);
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }

+ 6 - 5
components/lwp/lwp_mm_area.c

@@ -39,7 +39,7 @@ int lwp_map_area_insert(struct lwp_avl_struct **avl_tree, size_t addr, size_t si
     memset(node, 0, sizeof(struct lwp_avl_struct));
     memset(node, 0, sizeof(struct lwp_avl_struct));
 
 
     node->avl_key = ma->addr;
     node->avl_key = ma->addr;
-    node->data = (void*)ma;
+    node->data = (void *)ma;
     lwp_avl_insert(node, avl_tree);
     lwp_avl_insert(node, avl_tree);
     return 0;
     return 0;
 }
 }
@@ -70,7 +70,7 @@ struct lwp_avl_struct* lwp_map_find(struct lwp_avl_struct* ptree, size_t addr)
         }
         }
         if ((size_t)node->avl_key <= addr)
         if ((size_t)node->avl_key <= addr)
         {
         {
-            struct rt_mm_area_struct *ma = (struct rt_mm_area_struct*)node->data;
+            struct rt_mm_area_struct *ma = (struct rt_mm_area_struct *)node->data;
             if ((ma->addr <= addr) && (addr < ma->addr + ma->size))
             if ((ma->addr <= addr) && (addr < ma->addr + ma->size))
             {
             {
                 /* find area */
                 /* find area */
@@ -103,13 +103,14 @@ struct lwp_avl_struct* lwp_map_find_first(struct lwp_avl_struct* ptree)
     return ptree;
     return ptree;
 }
 }
 
 
-static void top_mem_fun(struct lwp_avl_struct* ptree, void *arg)
+int top_mem_fun(struct lwp_avl_struct* ptree, void *arg)
 {
 {
-    size_t *vs = (size_t*)arg;
+    size_t *vs = (size_t *)arg;
     struct rt_mm_area_struct *ma;
     struct rt_mm_area_struct *ma;
 
 
-    ma = (struct rt_mm_area_struct*)ptree->data;
+    ma = (struct rt_mm_area_struct *)ptree->data;
     *vs += ma->size;
     *vs += ma->size;
+    return 0;
 }
 }
 
 
 size_t lwp_vmem_count(struct lwp_avl_struct *ptree)
 size_t lwp_vmem_count(struct lwp_avl_struct *ptree)

+ 2 - 1
components/lwp/lwp_mm_area.h

@@ -23,7 +23,8 @@ extern "C" {
 
 
 enum
 enum
 {
 {
-    MM_AREA_TYPE_PHY = 0,  /* mm_area physical address is IO register or reserved memory */
+    MM_AREA_TYPE_PHY = 0,  /* mm_area physical address is IO register or reserved memory no cached*/
+    MM_AREA_TYPE_PHY_CACHED,  /* mm_area physical address is IO register or reserved memory with cached */
     MM_AREA_TYPE_SHM,      /* mm_area physical address is shared memory */
     MM_AREA_TYPE_SHM,      /* mm_area physical address is shared memory */
     MM_AREA_TYPE_DATA,     /* mm_area physical address is alloced from page manager for data */
     MM_AREA_TYPE_DATA,     /* mm_area physical address is alloced from page manager for data */
     MM_AREA_TYPE_TEXT,     /* mm_area physical address is alloced from page manager for text */
     MM_AREA_TYPE_TEXT,     /* mm_area physical address is alloced from page manager for text */

+ 33 - 16
components/lwp/lwp_pid.c

@@ -30,12 +30,17 @@
 #define DBG_LVL    DBG_INFO
 #define DBG_LVL    DBG_INFO
 #include <rtdbg.h>
 #include <rtdbg.h>
 
 
+#define PID_CT_ASSERT(name, x) \
+    struct assert_##name {char ary[2 * (x) - 1];}
+
+PID_CT_ASSERT(pid_max_nr, RT_LWP_MAX_NR > 1);
+
 struct rt_pid_struct
 struct rt_pid_struct
 {
 {
     struct rt_lwp* pidmap[RT_LWP_MAX_NR];
     struct rt_lwp* pidmap[RT_LWP_MAX_NR];
     pid_t last_pid;
     pid_t last_pid;
 };
 };
-static struct rt_pid_struct pid_struct = {0};
+static struct rt_pid_struct pid_struct = {{0}, 1};
 
 
 int libc_stdio_get_console(void);
 int libc_stdio_get_console(void);
 
 
@@ -64,8 +69,9 @@ struct rt_lwp* lwp_new(void)
     struct rt_lwp* lwp = RT_NULL;
     struct rt_lwp* lwp = RT_NULL;
 
 
     level = rt_hw_interrupt_disable();
     level = rt_hw_interrupt_disable();
+
     /* first scan */
     /* first scan */
-    for (i=pid_struct.last_pid; i<RT_LWP_MAX_NR; i++)
+    for (i = pid_struct.last_pid; i < RT_LWP_MAX_NR; i++)
     {
     {
         if (!pid_struct.pidmap[i])
         if (!pid_struct.pidmap[i])
         {
         {
@@ -76,7 +82,8 @@ struct rt_lwp* lwp_new(void)
     /* if first scan failed, scan the pidmap start with 0 */
     /* if first scan failed, scan the pidmap start with 0 */
     if (i >= RT_LWP_MAX_NR)
     if (i >= RT_LWP_MAX_NR)
     {
     {
-        for (i=0; i<pid_struct.last_pid; i++)
+        /* 0 is reserved */
+        for (i = 1; i < pid_struct.last_pid; i++)
         {
         {
             if (!pid_struct.pidmap[i])
             if (!pid_struct.pidmap[i])
             {
             {
@@ -92,7 +99,12 @@ struct rt_lwp* lwp_new(void)
         pid_struct.last_pid = 0;
         pid_struct.last_pid = 0;
         goto out;
         goto out;
     }
     }
-    pid_struct.last_pid = (i + 1)%RT_LWP_MAX_NR;
+    pid_struct.last_pid = (i + 1) % RT_LWP_MAX_NR;
+    if (pid_struct.last_pid == 0)
+    {
+        /* 0 is reserved */
+        pid_struct.last_pid++;
+    }
     lwp = (struct rt_lwp *)rt_malloc(sizeof(struct rt_lwp));
     lwp = (struct rt_lwp *)rt_malloc(sizeof(struct rt_lwp));
     if (lwp == RT_NULL)
     if (lwp == RT_NULL)
     {
     {
@@ -131,11 +143,7 @@ static void lwp_user_obj_free(struct rt_lwp *lwp)
         {
         {
         case RT_Object_Class_Thread:
         case RT_Object_Class_Thread:
         {
         {
-            rt_thread_t tid = (rt_thread_t)object;
-            if (tid->stat != RT_THREAD_CLOSE)
-            {
-                rt_thread_delete(tid);
-            }
+            RT_ASSERT(0);
             break;
             break;
         }
         }
         case RT_Object_Class_Semaphore:
         case RT_Object_Class_Semaphore:
@@ -268,7 +276,7 @@ void lwp_free(struct rt_lwp* lwp)
             {
             {
                 thread = rt_list_entry(lwp->wait_list.next, struct rt_thread, tlist);
                 thread = rt_list_entry(lwp->wait_list.next, struct rt_thread, tlist);
                 thread->error = RT_EOK;
                 thread->error = RT_EOK;
-                thread->msg_ret = (void*)lwp->lwp_ret;
+                thread->msg_ret = (void *)lwp->lwp_ret;
                 rt_thread_resume(thread);
                 rt_thread_resume(thread);
             }
             }
         }
         }
@@ -320,11 +328,19 @@ void lwp_ref_dec(struct rt_lwp *lwp)
 
 
 struct rt_lwp* lwp_from_pid(pid_t pid)
 struct rt_lwp* lwp_from_pid(pid_t pid)
 {
 {
+    if ((pid <= 0) || (pid >= RT_LWP_MAX_NR))
+    {
+        return NULL;
+    }
     return pid_struct.pidmap[pid];
     return pid_struct.pidmap[pid];
 }
 }
 
 
 pid_t lwp_to_pid(struct rt_lwp* lwp)
 pid_t lwp_to_pid(struct rt_lwp* lwp)
 {
 {
+    if (!lwp)
+    {
+        return -1;
+    }
     return lwp->pid;
     return lwp->pid;
 }
 }
 
 
@@ -333,7 +349,7 @@ char* lwp_pid2name(int32_t pid)
     struct rt_lwp* lwp;
     struct rt_lwp* lwp;
     char* process_name = RT_NULL;
     char* process_name = RT_NULL;
 
 
-    lwp = pid_struct.pidmap[pid];
+    lwp = lwp_from_pid(pid);
     if (lwp)
     if (lwp)
     {
     {
         process_name = strrchr(lwp->cmd, '/');
         process_name = strrchr(lwp->cmd, '/');
@@ -349,8 +365,9 @@ int32_t lwp_name2pid(const char* name)
     char* process_name = RT_NULL;
     char* process_name = RT_NULL;
     struct rt_lwp* lwp = RT_NULL;
     struct rt_lwp* lwp = RT_NULL;
 
 
-    for (pid=0; pid<RT_LWP_MAX_NR; pid++)
+    for (pid = 1; pid < RT_LWP_MAX_NR; pid++)
     {
     {
+        /* 0 is reserved */
         if (pid_struct.pidmap[pid])
         if (pid_struct.pidmap[pid])
         {
         {
             lwp = pid_struct.pidmap[pid];
             lwp = pid_struct.pidmap[pid];
@@ -389,7 +406,7 @@ pid_t waitpid(pid_t pid, int *status, int options)
         goto quit;
         goto quit;
     }
     }
 
 
-    lwp_self = (struct rt_lwp*)rt_thread_self()->lwp;
+    lwp_self = (struct rt_lwp *)rt_thread_self()->lwp;
     if (!lwp_self)
     if (!lwp_self)
     {
     {
         goto quit;
         goto quit;
@@ -521,7 +538,7 @@ long list_process(void)
     if (count > 0)
     if (count > 0)
     {
     {
         /* get thread pointers */
         /* get thread pointers */
-        threads = (struct rt_thread **)rt_calloc(count, sizeof(struct rt_thread*));
+        threads = (struct rt_thread **)rt_calloc(count, sizeof(struct rt_thread *));
         if (threads)
         if (threads)
         {
         {
             index = rt_object_get_pointers(RT_Object_Class_Thread, (rt_object_t *)threads, count);
             index = rt_object_get_pointers(RT_Object_Class_Thread, (rt_object_t *)threads, count);
@@ -555,7 +572,7 @@ long list_process(void)
         }
         }
     }
     }
 
 
-    for (index=0; index<RT_LWP_MAX_NR; index++)
+    for (index = 0; index < RT_LWP_MAX_NR; index++)
     {
     {
         if (pid_struct.pidmap[index])
         if (pid_struct.pidmap[index])
         {
         {
@@ -676,7 +693,7 @@ void lwp_request_thread_exit(rt_thread_t thread_to_exit)
     {
     {
         goto finish;
         goto finish;
     }
     }
-    if ((struct rt_lwp*)thread_to_exit->lwp != lwp)
+    if ((struct rt_lwp *)thread_to_exit->lwp != lwp)
     {
     {
         goto finish;
         goto finish;
     }
     }

+ 83 - 27
components/lwp/lwp_shm.c

@@ -75,7 +75,7 @@ static int _lwp_shmget(size_t key, size_t size, int create)
     node_key = lwp_avl_find(key, shm_tree_key);
     node_key = lwp_avl_find(key, shm_tree_key);
     if (node_key)
     if (node_key)
     {
     {
-        return (struct lwp_shm_struct*)node_key->data - _shm_ary;   /* the index */
+        return (struct lwp_shm_struct *)node_key->data - _shm_ary;   /* the index */
     }
     }
 
 
     /* If there doesn't exist such an item and we're allowed to create one ... */
     /* If there doesn't exist such an item and we're allowed to create one ... */
@@ -101,7 +101,7 @@ static int _lwp_shmget(size_t key, size_t size, int create)
         {
         {
             goto err;
             goto err;
         }
         }
-        page_addr_p = (void*)((char*)page_addr + PV_OFFSET);    /* physical address */
+        page_addr_p = (void *)((char *)page_addr + PV_OFFSET);    /* physical address */
 
 
         /* initialize the shared memory structure */
         /* initialize the shared memory structure */
         p = _shm_ary + id;
         p = _shm_ary + id;
@@ -117,11 +117,11 @@ static int _lwp_shmget(size_t key, size_t size, int create)
             goto err;
             goto err;
         }
         }
         node_key->avl_key = p->key;
         node_key->avl_key = p->key;
-        node_key->data = (void*)p;
+        node_key->data = (void *)p;
         lwp_avl_insert(node_key, &shm_tree_key);
         lwp_avl_insert(node_key, &shm_tree_key);
         node_pa = node_key + 1;
         node_pa = node_key + 1;
         node_pa->avl_key = p->addr;
         node_pa->avl_key = p->addr;
-        node_pa->data = (void*)p;
+        node_pa->data = (void *)p;
         lwp_avl_insert(node_pa, &shm_tree_pa);
         lwp_avl_insert(node_pa, &shm_tree_pa);
     }
     }
     return id;
     return id;
@@ -172,7 +172,7 @@ static struct lwp_avl_struct *shm_id_to_node(int id)
     {
     {
         return RT_NULL;
         return RT_NULL;
     }
     }
-    if (node_key->data != (void*)p)
+    if (node_key->data != (void *)p)
     {
     {
         return RT_NULL;
         return RT_NULL;
     }
     }
@@ -192,13 +192,13 @@ static int _lwp_shmrm(int id)
     {
     {
         return -1;
         return -1;
     }
     }
-    p = (struct lwp_shm_struct*)node_key->data;
+    p = (struct lwp_shm_struct *)node_key->data;
     if (p->ref)
     if (p->ref)
     {
     {
         return 0;
         return 0;
     }
     }
     bit = rt_page_bits(p->size);
     bit = rt_page_bits(p->size);
-    rt_pages_free((void*)((char*)p->addr - PV_OFFSET), bit);
+    rt_pages_free((void *)((char *)p->addr - PV_OFFSET), bit);
     lwp_avl_remove(node_key, &shm_tree_key);
     lwp_avl_remove(node_key, &shm_tree_key);
     node_pa = node_key + 1;
     node_pa = node_key + 1;
     lwp_avl_remove(node_pa, &shm_tree_pa);
     lwp_avl_remove(node_pa, &shm_tree_pa);
@@ -237,15 +237,15 @@ static void *_lwp_shmat(int id, void *shm_vaddr)
     {
     {
         return RT_NULL;
         return RT_NULL;
     }
     }
-    p = (struct lwp_shm_struct*)node_key->data; /* p = _shm_ary[id]; */
+    p = (struct lwp_shm_struct *)node_key->data; /* p = _shm_ary[id]; */
 
 
     /* map the shared memory into the address space of the current thread */
     /* map the shared memory into the address space of the current thread */
-    lwp = (struct rt_lwp *)rt_thread_self()->lwp;
+    lwp = lwp_self();
     if (!lwp)
     if (!lwp)
     {
     {
         return RT_NULL;
         return RT_NULL;
     }
     }
-    va = lwp_map_user_type(lwp, shm_vaddr, (void*)p->addr, p->size, 1, MM_AREA_TYPE_SHM);
+    va = lwp_map_user_type(lwp, shm_vaddr, (void *)p->addr, p->size, 1, MM_AREA_TYPE_SHM);
     if (va)
     if (va)
     {
     {
         p->ref++;
         p->ref++;
@@ -269,37 +269,92 @@ void *lwp_shmat(int id, void *shm_vaddr)
     return ret;
     return ret;
 }
 }
 
 
-/* Unmap the shared memory from the address space of the current thread. */
-int _lwp_shmdt(void *shm_vaddr)
+static struct lwp_shm_struct *_lwp_shm_struct_get(struct rt_lwp *lwp, void *shm_vaddr)
 {
 {
-    struct rt_lwp *lwp = RT_NULL;
     void *pa = RT_NULL;
     void *pa = RT_NULL;
     struct lwp_avl_struct *node_pa = RT_NULL;
     struct lwp_avl_struct *node_pa = RT_NULL;
-    struct lwp_shm_struct* p = RT_NULL;
 
 
-    lwp = (struct rt_lwp*)rt_thread_self()->lwp;
     if (!lwp)
     if (!lwp)
     {
     {
-        return -1;
+        return RT_NULL;
     }
     }
     pa = rt_hw_mmu_v2p(&lwp->mmu_info, shm_vaddr);  /* physical memory */
     pa = rt_hw_mmu_v2p(&lwp->mmu_info, shm_vaddr);  /* physical memory */
 
 
     node_pa = lwp_avl_find((size_t)pa, shm_tree_pa);
     node_pa = lwp_avl_find((size_t)pa, shm_tree_pa);
     if (!node_pa)
     if (!node_pa)
     {
     {
-        return -1;
+        return RT_NULL;
     }
     }
-    p = (struct lwp_shm_struct*)node_pa->data;
-    if (!p->ref)
+    return (struct lwp_shm_struct *)node_pa->data;
+}
+
+static int _lwp_shm_ref_inc(struct rt_lwp *lwp, void *shm_vaddr)
+{
+    struct lwp_shm_struct* p = _lwp_shm_struct_get(lwp, shm_vaddr);
+
+    if (p)
     {
     {
-        return -1;
+        p->ref++;
+        return p->ref;
     }
     }
-    p->ref--;
+    return -1;
+}
 
 
-    lwp_unmap_user_phy(lwp, shm_vaddr);
-    return 0;
+int lwp_shm_ref_inc(struct rt_lwp *lwp, void *shm_vaddr)
+{
+    int ret = 0;
+    rt_base_t level = 0;
+
+    level = rt_hw_interrupt_disable();
+    ret = _lwp_shm_ref_inc(lwp, shm_vaddr);
+    rt_hw_interrupt_enable(level);
+
+    return ret;
+}
+
+static int _lwp_shm_ref_dec(struct rt_lwp *lwp, void *shm_vaddr)
+{
+    struct lwp_shm_struct* p = _lwp_shm_struct_get(lwp, shm_vaddr);
+
+    if (p && (p->ref > 0))
+    {
+        p->ref--;
+        return p->ref;
+    }
+    return -1;
 }
 }
 
 
+int lwp_shm_ref_dec(struct rt_lwp *lwp, void *shm_vaddr)
+{
+    int ret = 0;
+    rt_base_t level = 0;
+
+    level = rt_hw_interrupt_disable();
+    ret = _lwp_shm_ref_dec(lwp, shm_vaddr);
+    rt_hw_interrupt_enable(level);
+
+    return ret;
+}
+
+/* Unmap the shared memory from the address space of the current thread. */
+int _lwp_shmdt(void *shm_vaddr)
+{
+    struct rt_lwp *lwp = RT_NULL;
+    int ret = 0;
+
+    lwp = lwp_self();
+    if (!lwp)
+    {
+        return -1;
+    }
+    ret = _lwp_shm_ref_dec(lwp, shm_vaddr);
+    if (ret >= 0)
+    {
+        lwp_unmap_user_phy(lwp, shm_vaddr);
+        return 0;
+    }
+    return -1;
+}
 /* A wrapping function: detach the mapped shared memory. */
 /* A wrapping function: detach the mapped shared memory. */
 int lwp_shmdt(void *shm_vaddr)
 int lwp_shmdt(void *shm_vaddr)
 {
 {
@@ -325,9 +380,9 @@ void *_lwp_shminfo(int id)
     {
     {
         return RT_NULL;
         return RT_NULL;
     }
     }
-    p = (struct lwp_shm_struct*)node_key->data; /* p = _shm_ary[id]; */
+    p = (struct lwp_shm_struct *)node_key->data; /* p = _shm_ary[id]; */
 
 
-    return (void*)((char*)p->addr - PV_OFFSET);     /* get the virtual address */
+    return (void *)((char *)p->addr - PV_OFFSET);     /* get the virtual address */
 }
 }
 
 
 /* A wrapping function: get the virtual address of a shared memory. */
 /* A wrapping function: get the virtual address of a shared memory. */
@@ -343,13 +398,14 @@ void *lwp_shminfo(int id)
 }
 }
 
 
 #ifdef RT_USING_FINSH
 #ifdef RT_USING_FINSH
-static void _shm_info(struct lwp_avl_struct* node_key, void *data)
+static int _shm_info(struct lwp_avl_struct* node_key, void *data)
 {
 {
     int id = 0;
     int id = 0;
-    struct lwp_shm_struct* p = (struct lwp_shm_struct*)node_key->data;
+    struct lwp_shm_struct* p = (struct lwp_shm_struct *)node_key->data;
 
 
     id = p - _shm_ary;
     id = p - _shm_ary;
     rt_kprintf("0x%08x 0x%08x 0x%08x %8d\n", p->key, p->addr, p->size, id);
     rt_kprintf("0x%08x 0x%08x 0x%08x %8d\n", p->key, p->addr, p->size, id);
+    return 0;
 }
 }
 
 
 void list_shm(void)
 void list_shm(void)

+ 2 - 0
components/lwp/lwp_shm.h

@@ -21,6 +21,8 @@ int lwp_shmrm(int id);
 void* lwp_shmat(int id, void* shm_vaddr);
 void* lwp_shmat(int id, void* shm_vaddr);
 int lwp_shmdt(void* shm_vaddr);
 int lwp_shmdt(void* shm_vaddr);
 void *lwp_shminfo(int id);
 void *lwp_shminfo(int id);
+int lwp_shm_ref_inc(struct rt_lwp *lwp, void *shm_vaddr);
+int lwp_shm_ref_dec(struct rt_lwp *lwp, void *shm_vaddr);
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }

+ 372 - 122
components/lwp/lwp_syscall.c

@@ -26,15 +26,15 @@
 #if (defined(RT_USING_SAL) && defined(SAL_USING_POSIX))
 #if (defined(RT_USING_SAL) && defined(SAL_USING_POSIX))
 #include <sys/socket.h>
 #include <sys/socket.h>
 
 
-#define SYSCALL_NET(f)      ((void*)(f))
+#define SYSCALL_NET(f)      ((void *)(f))
 #else
 #else
-#define SYSCALL_NET(f)      ((void*)sys_notimpl)
+#define SYSCALL_NET(f)      ((void *)sys_notimpl)
 #endif
 #endif
 
 
 #if defined(RT_USING_DFS) && defined(RT_USING_USERSPACE)
 #if defined(RT_USING_DFS) && defined(RT_USING_USERSPACE)
-#define SYSCALL_USPACE(f)   ((void*)(f))
+#define SYSCALL_USPACE(f)   ((void *)(f))
 #else
 #else
-#define SYSCALL_USPACE(f)   ((void*)sys_notimpl)
+#define SYSCALL_USPACE(f)   ((void *)sys_notimpl)
 #endif
 #endif
 
 
 #define DBG_TAG    "SYSCALL"
 #define DBG_TAG    "SYSCALL"
@@ -49,6 +49,7 @@
 #include <sal.h>
 #include <sal.h>
 #endif /* RT_USING_SAL */
 #endif /* RT_USING_SAL */
 
 
+#include <lwp_console.h>
 #include "lwp_ipc_internal.h"
 #include "lwp_ipc_internal.h"
 
 
 #define ALLOC_KERNEL_STACK_SIZE 5120
 #define ALLOC_KERNEL_STACK_SIZE 5120
@@ -343,7 +344,7 @@ static void lwp_user_thread(void *parameter)
 
 
     user_stack = (uint32_t)tid->user_stack + tid->user_stack_size;
     user_stack = (uint32_t)tid->user_stack + tid->user_stack_size;
     user_stack &= ~7; //align 8
     user_stack &= ~7; //align 8
-    set_user_context((void*)user_stack);
+    set_user_context((void *)user_stack);
 
 
     lwp_user_entry(parameter, tid->user_entry, lwp->data_entry, RT_NULL);
     lwp_user_entry(parameter, tid->user_entry, lwp->data_entry, RT_NULL);
 }
 }
@@ -358,7 +359,7 @@ void sys_exit(int value)
     LOG_D("thread/process exit.");
     LOG_D("thread/process exit.");
 
 
     tid = rt_thread_self();
     tid = rt_thread_self();
-    lwp = (struct rt_lwp*)tid->lwp;
+    lwp = (struct rt_lwp *)tid->lwp;
 
 
     level = rt_hw_interrupt_disable();
     level = rt_hw_interrupt_disable();
     if (tid->clear_child_tid)
     if (tid->clear_child_tid)
@@ -404,7 +405,7 @@ ssize_t sys_read(int fd, void *buf, size_t nbyte)
         return -1;
         return -1;
     }
     }
 
 
-    if (!lwp_user_accessable((void*)buf, nbyte))
+    if (!lwp_user_accessable((void *)buf, nbyte))
     {
     {
         rt_set_errno(EINVAL);
         rt_set_errno(EINVAL);
         return -1;
         return -1;
@@ -443,7 +444,7 @@ ssize_t sys_write(int fd, const void *buf, size_t nbyte)
         return -1;
         return -1;
     }
     }
 
 
-    if (!lwp_user_accessable((void*)buf, nbyte))
+    if (!lwp_user_accessable((void *)buf, nbyte))
     {
     {
         rt_set_errno(EINVAL);
         rt_set_errno(EINVAL);
         return -1;
         return -1;
@@ -480,7 +481,7 @@ int sys_open(const char *name, int flag, ...)
     rt_size_t len = 0;
     rt_size_t len = 0;
     char *kname = RT_NULL;
     char *kname = RT_NULL;
 
 
-    if (!lwp_user_accessable((void*)name, 1))
+    if (!lwp_user_accessable((void *)name, 1))
     {
     {
         rt_set_errno(EINVAL);
         rt_set_errno(EINVAL);
         return -1;
         return -1;
@@ -635,7 +636,7 @@ int sys_poll(struct pollfd *fds, nfds_t nfds, int timeout)
 #ifdef RT_USING_USERSPACE
 #ifdef RT_USING_USERSPACE
     struct pollfd *kfds = RT_NULL;
     struct pollfd *kfds = RT_NULL;
 
 
-    if (!lwp_user_accessable((void*)fds, nfds * sizeof *fds))
+    if (!lwp_user_accessable((void *)fds, nfds * sizeof *fds))
     {
     {
         rt_set_errno(EINVAL);
         rt_set_errno(EINVAL);
         return -1;
         return -1;
@@ -692,7 +693,7 @@ int sys_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, s
 
 
     if (readfds)
     if (readfds)
     {
     {
-        if (!lwp_user_accessable((void*)readfds, sizeof *readfds))
+        if (!lwp_user_accessable((void *)readfds, sizeof *readfds))
         {
         {
             rt_set_errno(EINVAL);
             rt_set_errno(EINVAL);
             goto quit;
             goto quit;
@@ -707,7 +708,7 @@ int sys_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, s
     }
     }
     if (writefds)
     if (writefds)
     {
     {
-        if (!lwp_user_accessable((void*)writefds, sizeof *writefds))
+        if (!lwp_user_accessable((void *)writefds, sizeof *writefds))
         {
         {
             rt_set_errno(EINVAL);
             rt_set_errno(EINVAL);
             goto quit;
             goto quit;
@@ -722,7 +723,7 @@ int sys_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, s
     }
     }
     if (exceptfds)
     if (exceptfds)
     {
     {
-        if (!lwp_user_accessable((void*)exceptfds, sizeof *exceptfds))
+        if (!lwp_user_accessable((void *)exceptfds, sizeof *exceptfds))
         {
         {
             rt_set_errno(EINVAL);
             rt_set_errno(EINVAL);
             goto quit;
             goto quit;
@@ -775,7 +776,7 @@ int sys_unlink(const char *pathname)
     rt_size_t len = 0;
     rt_size_t len = 0;
     char *kname = RT_NULL;
     char *kname = RT_NULL;
 
 
-    if (!lwp_user_accessable((void*)pathname, 1))
+    if (!lwp_user_accessable((void *)pathname, 1))
     {
     {
         rt_set_errno(EINVAL);
         rt_set_errno(EINVAL);
         return -1;
         return -1;
@@ -815,7 +816,7 @@ int sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
 
 
     dbg_log(DBG_LOG, "sys_nanosleep\n");
     dbg_log(DBG_LOG, "sys_nanosleep\n");
 
 
-    if (!lwp_user_accessable((void*)rqtp, sizeof *rqtp))
+    if (!lwp_user_accessable((void *)rqtp, sizeof *rqtp))
     {
     {
         rt_set_errno(EINVAL);
         rt_set_errno(EINVAL);
         return -1;
         return -1;
@@ -828,7 +829,7 @@ int sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
 
 
     if (rmtp)
     if (rmtp)
     {
     {
-        if (!lwp_user_accessable((void*)rmtp, sizeof *rmtp))
+        if (!lwp_user_accessable((void *)rmtp, sizeof *rmtp))
         {
         {
             rt_set_errno(EINVAL);
             rt_set_errno(EINVAL);
             return -1;
             return -1;
@@ -867,7 +868,7 @@ int sys_gettimeofday(struct timeval *tp, struct timezone *tzp)
 #ifdef RT_USING_USERSPACE
 #ifdef RT_USING_USERSPACE
     if (tp)
     if (tp)
     {
     {
-        if (!lwp_user_accessable((void*)tp, sizeof *tp))
+        if (!lwp_user_accessable((void *)tp, sizeof *tp))
         {
         {
             rt_set_errno(EINVAL);
             rt_set_errno(EINVAL);
             return -1;
             return -1;
@@ -1065,7 +1066,7 @@ rt_err_t sys_mb_send_wait(rt_mailbox_t mb,
 
 
 rt_err_t sys_mb_recv(rt_mailbox_t mb, rt_uint32_t *value, rt_int32_t timeout)
 rt_err_t sys_mb_recv(rt_mailbox_t mb, rt_uint32_t *value, rt_int32_t timeout)
 {
 {
-    return rt_mb_recv(mb, (rt_ubase_t*)value, timeout);
+    return rt_mb_recv(mb, (rt_ubase_t *)value, timeout);
 }
 }
 
 
 rt_mq_t sys_mq_create(const char *name,
 rt_mq_t sys_mq_create(const char *name,
@@ -1110,7 +1111,7 @@ rt_timer_t sys_timer_create(const char *name,
         rt_tick_t   time,
         rt_tick_t   time,
         rt_uint8_t  flag)
         rt_uint8_t  flag)
 {
 {
-    return rt_timer_create(name, timer_timeout_callback, (void*)data, time, flag);
+    return rt_timer_create(name, timer_timeout_callback, (void *)data, time, flag);
 }
 }
 
 
 rt_err_t sys_timer_delete(rt_timer_t timer)
 rt_err_t sys_timer_delete(rt_timer_t timer)
@@ -1158,9 +1159,9 @@ rt_thread_t sys_thread_create(void *arg[])
         rt_set_errno(ENOMEM);
         rt_set_errno(ENOMEM);
         goto fail;
         goto fail;
     }
     }
-    thread = rt_thread_create((const char*)arg[0],
+    thread = rt_thread_create((const char *)arg[0],
             lwp_user_thread,
             lwp_user_thread,
-            (void*)arg[2],
+            (void *)arg[2],
             ALLOC_KERNEL_STACK_SIZE,
             ALLOC_KERNEL_STACK_SIZE,
             (rt_uint8_t)(size_t)arg[4],
             (rt_uint8_t)(size_t)arg[4],
             (rt_uint32_t)arg[5]);
             (rt_uint32_t)arg[5]);
@@ -1173,7 +1174,7 @@ rt_thread_t sys_thread_create(void *arg[])
     thread->user_entry = (void (*)(void *))arg[1];
     thread->user_entry = (void (*)(void *))arg[1];
     thread->user_stack = (void *)user_stack;
     thread->user_stack = (void *)user_stack;
     thread->user_stack_size = (uint32_t)arg[3];
     thread->user_stack_size = (uint32_t)arg[3];
-    thread->lwp = (void*)lwp;
+    thread->lwp = (void *)lwp;
     thread->tid = tid;
     thread->tid = tid;
     lwp_tid_set_thread(tid, thread);
     lwp_tid_set_thread(tid, thread);
 
 
@@ -1231,7 +1232,8 @@ fail:
  *          start_args
  *          start_args
  *          */
  *          */
 #define SYS_CLONE_ARGS_NR 7
 #define SYS_CLONE_ARGS_NR 7
-int lwp_set_thread_context(void *new_thread_stack, void *origin_thread_stack, void *user_stack, void **thread_sp, int tid);
+int lwp_set_thread_context(void *new_thread_stack, void *origin_thread_stack,
+        void *user_stack, void **thread_sp, int tid);
 long sys_clone(void *arg[])
 long sys_clone(void *arg[])
 {
 {
     rt_base_t level = 0;
     rt_base_t level = 0;
@@ -1291,7 +1293,7 @@ long sys_clone(void *arg[])
         rt_set_errno(ENOMEM);
         rt_set_errno(ENOMEM);
         goto fail;
         goto fail;
     }
     }
-    thread = rt_thread_create((const char*)"pthread",
+    thread = rt_thread_create((const char *)"pthread",
             RT_NULL,
             RT_NULL,
             RT_NULL,
             RT_NULL,
             ALLOC_KERNEL_STACK_SIZE,
             ALLOC_KERNEL_STACK_SIZE,
@@ -1306,7 +1308,7 @@ long sys_clone(void *arg[])
     thread->user_entry = RT_NULL;
     thread->user_entry = RT_NULL;
     thread->user_stack = RT_NULL;
     thread->user_stack = RT_NULL;
     thread->user_stack_size = 0;
     thread->user_stack_size = 0;
-    thread->lwp = (void*)lwp;
+    thread->lwp = (void *)lwp;
     thread->tid = tid;
     thread->tid = tid;
 
 
     if ((flags & CLONE_SETTLS) == CLONE_SETTLS)
     if ((flags & CLONE_SETTLS) == CLONE_SETTLS)
@@ -1319,7 +1321,7 @@ long sys_clone(void *arg[])
     }
     }
     if ((flags & CLONE_CHILD_CLEARTID) == CLONE_CHILD_CLEARTID)
     if ((flags & CLONE_CHILD_CLEARTID) == CLONE_CHILD_CLEARTID)
     {
     {
-        thread->clear_child_tid = (int*)arg[4];
+        thread->clear_child_tid = (int *)arg[4];
     }
     }
 
 
     level = rt_hw_interrupt_disable();
     level = rt_hw_interrupt_disable();
@@ -1329,8 +1331,8 @@ long sys_clone(void *arg[])
     /* copy origin stack */
     /* copy origin stack */
     rt_memcpy(thread->stack_addr, self->stack_addr, ALLOC_KERNEL_STACK_SIZE);
     rt_memcpy(thread->stack_addr, self->stack_addr, ALLOC_KERNEL_STACK_SIZE);
     lwp_tid_set_thread(tid, thread);
     lwp_tid_set_thread(tid, thread);
-    tid = lwp_set_thread_context((void*)((char*)thread->stack_addr + ALLOC_KERNEL_STACK_SIZE),
-            (void*)((char*)self->stack_addr + ALLOC_KERNEL_STACK_SIZE), user_stack, &thread->sp, tid);
+    tid = lwp_set_thread_context((void *)((char *)thread->stack_addr + ALLOC_KERNEL_STACK_SIZE),
+            (void *)((char *)self->stack_addr + ALLOC_KERNEL_STACK_SIZE), user_stack, &thread->sp, tid);
     if (tid)
     if (tid)
     {
     {
         rt_thread_startup(thread);
         rt_thread_startup(thread);
@@ -1346,6 +1348,211 @@ fail:
     return -1;
     return -1;
 }
 }
 
 
+int lwp_dup_user(struct lwp_avl_struct* ptree, void *arg);
+void *lwp_get_user_sp(void);
+
+static int _copy_process(struct rt_lwp *dest_lwp, struct rt_lwp *src_lwp)
+{
+    return lwp_avl_traversal(src_lwp->map_area, lwp_dup_user, dest_lwp);
+}
+
+static void lwp_struct_copy(struct rt_lwp *dst, struct rt_lwp *src)
+{
+#ifdef RT_USING_USERSPACE
+    dst->end_heap = src->end_heap;
+#endif
+    dst->lwp_type = src->lwp_type;
+    dst->text_entry = src->text_entry;
+    dst->text_size = src->text_size;
+    dst->data_entry = src->data_entry;
+    dst->data_size = src->data_size;
+    dst->args = src->args;
+    rt_memcpy(dst->cmd, src->cmd, RT_NAME_MAX);
+
+    dst->signal_mask = src->signal_mask;
+    rt_memcpy(dst->signal_handler, src->signal_handler, sizeof dst->signal_handler);
+}
+
+static int lwp_copy_files(struct rt_lwp *dst, struct rt_lwp *src)
+{
+    struct dfs_fdtable *dst_fdt;
+    struct dfs_fdtable *src_fdt;
+
+    src_fdt = &src->fdt;
+    dst_fdt = &dst->fdt;
+    /* init fds */
+    dst_fdt->fds = rt_calloc(src_fdt->maxfd, sizeof(void *));
+    if (dst_fdt->fds)
+    {
+        struct dfs_fd *d_s;
+        struct dfs_fd *d_d;
+        int i;
+
+        dst_fdt->maxfd = src_fdt->maxfd;
+
+        dfs_fd_lock();
+        /* copy stdio */
+        for (i = 0; i < src_fdt->maxfd; i++)
+        {
+            d_s = fdt_fd_get(src_fdt, i);
+            if (d_s)
+            {
+                dfs_fm_lock();
+                if (!d_s->fnode)
+                {
+                    dfs_fm_unlock();
+                    continue;
+                }
+                d_s->fnode->ref_count++;
+                dfs_fm_unlock();
+
+                /* alloc dfs_fd struct */
+                d_d = (struct dfs_fd *)rt_calloc(1, sizeof(struct dfs_fd));
+                if (!d_d)
+                {
+                    dfs_fd_unlock();
+                    return -1;
+                }
+                dst_fdt->fds[i] = d_d;
+                d_d->magic = d_s->magic;
+                d_d->ref_count = 1;
+                d_d->pos = d_s->pos;
+                d_d->fnode = d_s->fnode;
+                d_d->data = d_s->data;
+            }
+        }
+        dfs_fd_unlock();
+        return 0;
+    }
+    return -1;
+}
+
+int sys_fork(void)
+{
+    rt_base_t level;
+    int tid = 0;
+    struct rt_lwp *lwp = RT_NULL;
+    struct rt_lwp *self_lwp = RT_NULL;
+    rt_thread_t thread = RT_NULL;
+    rt_thread_t self_thread = RT_NULL;
+    void *user_stack = RT_NULL;
+    char thread_name[RT_NAME_MAX + 1];
+
+    /* new lwp */
+    lwp = lwp_new();
+    if (!lwp)
+    {
+        rt_set_errno(ENOMEM);
+        goto fail;
+    }
+
+    /* new tid */
+    if ((tid = lwp_tid_get()) == 0)
+    {
+        rt_set_errno(ENOMEM);
+        goto fail;
+    }
+
+    /* user space init */
+    if (lwp_user_space_init(lwp) != 0)
+    {
+        rt_set_errno(ENOMEM);
+        goto fail;
+    }
+
+    self_lwp = lwp_self();
+
+    /* copy process */
+    if (_copy_process(lwp, self_lwp) != 0)
+    {
+        rt_set_errno(ENOMEM);
+        goto fail;
+    }
+
+    /* copy lwp struct data */
+    lwp_struct_copy(lwp, self_lwp);
+
+    /* copy files */
+    if (lwp_copy_files(lwp, self_lwp) != 0)
+    {
+        rt_set_errno(ENOMEM);
+        goto fail;
+    }
+
+    /* create thread */
+    self_thread = rt_thread_self();
+
+    rt_memcpy(thread_name, self_thread->name, RT_NAME_MAX);
+    thread_name[RT_NAME_MAX] = '\0';
+    thread = rt_thread_create((const char *)thread_name,
+            RT_NULL,
+            RT_NULL,
+            ALLOC_KERNEL_STACK_SIZE,
+            self_thread->init_priority,
+            self_thread->init_tick);
+    if (!thread)
+    {
+        goto fail;
+    }
+
+    thread->cleanup = self_thread->cleanup;
+    thread->user_entry = self_thread->user_entry;
+    thread->user_stack = self_thread->user_stack;
+    thread->user_stack_size = self_thread->user_stack_size;
+    thread->signal_mask = self_thread->signal_mask;
+    thread->thread_idr = self_thread->thread_idr;
+    thread->lwp = (void *)lwp;
+    thread->tid = tid;
+
+    level = rt_hw_interrupt_disable();
+
+    /* add thread to lwp process */
+    rt_list_insert_after(&lwp->t_grp, &thread->sibling);
+
+    /* lwp add to children link */
+    lwp->sibling = self_lwp->first_child;
+    self_lwp->first_child = lwp;
+    lwp->parent = self_lwp;
+
+    rt_hw_interrupt_enable(level);
+
+    /* copy origin stack */
+    rt_memcpy(thread->stack_addr, self_thread->stack_addr, ALLOC_KERNEL_STACK_SIZE);
+    lwp_tid_set_thread(tid, thread);
+
+    level = rt_hw_interrupt_disable();
+    user_stack = lwp_get_user_sp();
+    rt_hw_interrupt_enable(level);
+
+    tid = lwp_set_thread_context((void *)((char *)thread->stack_addr + ALLOC_KERNEL_STACK_SIZE),
+            (void *)((char *)self_thread->stack_addr + ALLOC_KERNEL_STACK_SIZE), user_stack, &thread->sp, tid);
+    if (tid)
+    {
+        level = rt_hw_interrupt_disable();
+        if (rt_console_get_foreground() == self_lwp)
+        {
+            rt_console_set_foreground(lwp);
+        }
+        rt_hw_interrupt_enable(level);
+        rt_thread_startup(thread);
+        return lwp_to_pid(lwp);
+    }
+    else
+    {
+        return 0;
+    }
+fail:
+    if (tid != 0)
+    {
+        lwp_tid_put(tid);
+    }
+    if (lwp)
+    {
+        lwp_ref_dec(lwp);
+    }
+    return -1;
+}
+
 rt_err_t sys_thread_delete(rt_thread_t thread)
 rt_err_t sys_thread_delete(rt_thread_t thread)
 {
 {
     return rt_thread_delete(thread);
     return rt_thread_delete(thread);
@@ -1406,12 +1613,12 @@ INIT_DEVICE_EXPORT(critical_init);
 
 
 void sys_enter_critical(void)
 void sys_enter_critical(void)
 {
 {
-   rt_sem_take(&critical_lock, RT_WAITING_FOREVER);
+    rt_sem_take(&critical_lock, RT_WAITING_FOREVER);
 }
 }
 
 
 void sys_exit_critical(void)
 void sys_exit_critical(void)
 {
 {
-   rt_sem_release(&critical_lock);
+    rt_sem_release(&critical_lock);
 }
 }
 
 
 /* syscall: "sys_log" ret: "int" args: "const char*" "size" */
 /* syscall: "sys_log" ret: "int" args: "const char*" "size" */
@@ -1436,7 +1643,10 @@ int sys_log(const char* log, int size)
 {
 {
     rt_device_t console = rt_console_get_device();
     rt_device_t console = rt_console_get_device();
 
 
-    if (console && __sys_log_enable) rt_device_write(console, -1, log, size);
+    if (console && __sys_log_enable)
+    {
+        rt_device_write(console, -1, log, size);
+    }
 
 
     return 0;
     return 0;
 }
 }
@@ -1578,12 +1788,12 @@ int sys_bind(int socket, const struct musl_sockaddr *name, socklen_t namelen)
     struct sockaddr sa;
     struct sockaddr sa;
     struct musl_sockaddr kname;
     struct musl_sockaddr kname;
 
 
-    if (!lwp_user_accessable((void*)name, namelen))
+    if (!lwp_user_accessable((void *)name, namelen))
     {
     {
         rt_set_errno(EINVAL);
         rt_set_errno(EINVAL);
         return -1;
         return -1;
     }
     }
-    lwp_get_from_user(&kname, (void*)name, namelen);
+    lwp_get_from_user(&kname, (void *)name, namelen);
 
 
     sockaddr_tolwip(&kname, &sa);
     sockaddr_tolwip(&kname, &sa);
 
 
@@ -1622,7 +1832,7 @@ int sys_getpeername (int socket, struct musl_sockaddr *name, socklen_t *namelen)
     }
     }
 
 
     knamelen = sizeof(struct sockaddr);
     knamelen = sizeof(struct sockaddr);
-    ret = getpeername (socket, &sa, &knamelen);
+    ret = getpeername(socket, &sa, &knamelen);
 
 
     if (ret == 0)
     if (ret == 0)
     {
     {
@@ -1665,7 +1875,7 @@ int sys_getsockname (int socket, struct musl_sockaddr *name, socklen_t *namelen)
     }
     }
 
 
     knamelen = sizeof(struct sockaddr);
     knamelen = sizeof(struct sockaddr);
-    ret = getsockname (socket, &sa, &knamelen);
+    ret = getsockname(socket, &sa, &knamelen);
     if (ret == 0)
     if (ret == 0)
     {
     {
         sockaddr_tomusl(&sa, &kname);
         sockaddr_tomusl(&sa, &kname);
@@ -1674,21 +1884,21 @@ int sys_getsockname (int socket, struct musl_sockaddr *name, socklen_t *namelen)
             unamelen = sizeof(struct musl_sockaddr);
             unamelen = sizeof(struct musl_sockaddr);
         }
         }
         lwp_put_to_user(name, &kname, unamelen);
         lwp_put_to_user(name, &kname, unamelen);
-        lwp_put_to_user(namelen, &unamelen, sizeof (socklen_t *));
+        lwp_put_to_user(namelen, &unamelen, sizeof(socklen_t *));
     }
     }
     return ret;
     return ret;
 }
 }
 
 
-int sys_getsockopt (int socket, int level, int optname, void *optval, socklen_t *optlen)
+int sys_getsockopt(int socket, int level, int optname, void *optval, socklen_t *optlen)
 {
 {
     convert_sockopt(&level, &optname);
     convert_sockopt(&level, &optname);
-    return getsockopt (socket, level, optname, optval, optlen);
+    return getsockopt(socket, level, optname, optval, optlen);
 }
 }
 
 
-int sys_setsockopt (int socket, int level, int optname, const void *optval, socklen_t optlen)
+int sys_setsockopt(int socket, int level, int optname, const void *optval, socklen_t optlen)
 {
 {
     convert_sockopt(&level, &optname);
     convert_sockopt(&level, &optname);
-    return setsockopt (socket, level, optname, optval, optlen);
+    return setsockopt(socket, level, optname, optval, optlen);
 }
 }
 
 
 int sys_connect(int socket, const struct musl_sockaddr *name, socklen_t namelen)
 int sys_connect(int socket, const struct musl_sockaddr *name, socklen_t namelen)
@@ -1696,12 +1906,12 @@ int sys_connect(int socket, const struct musl_sockaddr *name, socklen_t namelen)
     struct sockaddr sa;
     struct sockaddr sa;
     struct musl_sockaddr kname;
     struct musl_sockaddr kname;
 
 
-    if (!lwp_user_accessable((void*)name, namelen))
+    if (!lwp_user_accessable((void *)name, namelen))
     {
     {
         rt_set_errno(EINVAL);
         rt_set_errno(EINVAL);
         return -1;
         return -1;
     }
     }
-    lwp_get_from_user(&kname, (void*)name, namelen);
+    lwp_get_from_user(&kname, (void *)name, namelen);
 
 
     sockaddr_tolwip(&kname, &sa);
     sockaddr_tolwip(&kname, &sa);
 
 
@@ -1724,15 +1934,25 @@ static int netflags_muslc_2_lwip(int flags)
     int flgs = 0;
     int flgs = 0;
 
 
     if (flags & MUSLC_MSG_PEEK)
     if (flags & MUSLC_MSG_PEEK)
+    {
         flgs |= MSG_PEEK;
         flgs |= MSG_PEEK;
+    }
     if (flags & MUSLC_MSG_WAITALL)
     if (flags & MUSLC_MSG_WAITALL)
+    {
         flgs |= MSG_WAITALL;
         flgs |= MSG_WAITALL;
+    }
     if (flags & MUSLC_MSG_OOB)
     if (flags & MUSLC_MSG_OOB)
+    {
         flgs |= MSG_OOB;
         flgs |= MSG_OOB;
+    }
     if (flags & MUSLC_MSG_DONTWAIT)
     if (flags & MUSLC_MSG_DONTWAIT)
+    {
         flgs |= MSG_DONTWAIT;
         flgs |= MSG_DONTWAIT;
+    }
     if (flags & MUSLC_MSG_MORE)
     if (flags & MUSLC_MSG_MORE)
+    {
         flgs |= MSG_MORE;
         flgs |= MSG_MORE;
+    }
     return flgs;
     return flgs;
 }
 }
 
 
@@ -1753,7 +1973,7 @@ int sys_recvfrom(int socket, void *mem, size_t len, int flags,
         return -1;
         return -1;
     }
     }
 
 
-    if (!lwp_user_accessable((void*)mem, len))
+    if (!lwp_user_accessable((void *)mem, len))
     {
     {
         rt_set_errno(EINVAL);
         rt_set_errno(EINVAL);
         return -1;
         return -1;
@@ -1766,7 +1986,8 @@ int sys_recvfrom(int socket, void *mem, size_t len, int flags,
         return -1;
         return -1;
     }
     }
 
 
-    if (flags == 0x2) {
+    if (flags == 0x2)
+    {
         flags = 0x1;
         flags = 0x1;
     }
     }
 
 
@@ -1776,11 +1997,16 @@ int sys_recvfrom(int socket, void *mem, size_t len, int flags,
 
 
         ret = recvfrom(socket, kmem, len, flgs, &sa, fromlen);
         ret = recvfrom(socket, kmem, len, flgs, &sa, fromlen);
         sockaddr_tomusl(&sa, from);
         sockaddr_tomusl(&sa, from);
-    } else
+    }
+    else
+    {
         ret = recvfrom(socket, kmem, len, flgs, NULL, NULL);
         ret = recvfrom(socket, kmem, len, flgs, NULL, NULL);
+    }
 
 
     if (ret > 0)
     if (ret > 0)
+    {
         lwp_put_to_user(mem, kmem, len);
         lwp_put_to_user(mem, kmem, len);
+    }
 
 
     kmem_put(kmem);
     kmem_put(kmem);
     return ret;
     return ret;
@@ -1824,7 +2050,7 @@ int sys_sendto(int socket, const void *dataptr, size_t size, int flags,
         return -1;
         return -1;
     }
     }
 
 
-    if (!lwp_user_accessable((void*)dataptr, size))
+    if (!lwp_user_accessable((void *)dataptr, size))
     {
     {
         rt_set_errno(EINVAL);
         rt_set_errno(EINVAL);
         return -1;
         return -1;
@@ -1847,7 +2073,9 @@ int sys_sendto(int socket, const void *dataptr, size_t size, int flags,
         ret = sendto(socket, kmem, size, flgs, &sa, tolen);
         ret = sendto(socket, kmem, size, flgs, &sa, tolen);
     }
     }
     else
     else
+    {
         ret = sendto(socket, kmem, size, flgs, NULL, tolen);
         ret = sendto(socket, kmem, size, flgs, NULL, tolen);
+    }
 
 
     kmem_put(kmem);
     kmem_put(kmem);
     return ret;
     return ret;
@@ -1876,7 +2104,10 @@ int sys_socket(int domain, int type, int protocol)
     int fd = -1;
     int fd = -1;
     int nonblock = 0;
     int nonblock = 0;
     /* not support SOCK_CLOEXEC type */
     /* not support SOCK_CLOEXEC type */
-    if (type & SOCK_CLOEXEC) type &= ~SOCK_CLOEXEC;
+    if (type & SOCK_CLOEXEC)
+    {
+        type &= ~SOCK_CLOEXEC;
+    }
     if (type & SOCK_NONBLOCK)
     if (type & SOCK_NONBLOCK)
     {
     {
         nonblock = 1;
         nonblock = 1;
@@ -1940,7 +2171,7 @@ int sys_sigaction(int sig, const struct sigaction *act,
     }
     }
     if (oact)
     if (oact)
     {
     {
-        if (!lwp_user_accessable((void*)oact, sigsetsize))
+        if (!lwp_user_accessable((void *)oact, sigsetsize))
         {
         {
             rt_set_errno(EINVAL);
             rt_set_errno(EINVAL);
             goto out;
             goto out;
@@ -1949,7 +2180,7 @@ int sys_sigaction(int sig, const struct sigaction *act,
     }
     }
     if (act)
     if (act)
     {
     {
-        if (!lwp_user_accessable((void*)act, sigsetsize))
+        if (!lwp_user_accessable((void *)act, sigsetsize))
         {
         {
             rt_set_errno(EINVAL);
             rt_set_errno(EINVAL);
             goto out;
             goto out;
@@ -1993,7 +2224,7 @@ int sys_sigprocmask(int how, const sigset_t *sigset, sigset_t *oset, size_t size
     }
     }
     if (oset)
     if (oset)
     {
     {
-        if (!lwp_user_accessable((void*)oset, size))
+        if (!lwp_user_accessable((void *)oset, size))
         {
         {
             rt_set_errno(EINVAL);
             rt_set_errno(EINVAL);
             return ret;
             return ret;
@@ -2002,12 +2233,12 @@ int sys_sigprocmask(int how, const sigset_t *sigset, sigset_t *oset, size_t size
     }
     }
     if (sigset)
     if (sigset)
     {
     {
-        if (!lwp_user_accessable((void*)sigset, size))
+        if (!lwp_user_accessable((void *)sigset, size))
         {
         {
             rt_set_errno(EINVAL);
             rt_set_errno(EINVAL);
             return ret;
             return ret;
         }
         }
-        lwp_get_from_user(&newset, (void*)sigset, size);
+        lwp_get_from_user(&newset, (void *)sigset, size);
         pnewset = &newset;
         pnewset = &newset;
     }
     }
     ret = lwp_sigprocmask(how, pnewset, poldset);
     ret = lwp_sigprocmask(how, pnewset, poldset);
@@ -2022,7 +2253,6 @@ int sys_sigprocmask(int how, const sigset_t *sigset, sigset_t *oset, size_t size
     return ret;
     return ret;
 }
 }
 
 
-
 int sys_tkill(int tid, int sig)
 int sys_tkill(int tid, int sig)
 {
 {
     rt_thread_t thread = RT_NULL;
     rt_thread_t thread = RT_NULL;
@@ -2059,7 +2289,7 @@ int sys_thread_sigprocmask(int how, const lwp_sigset_t *sigset, lwp_sigset_t *os
     }
     }
     if (oset)
     if (oset)
     {
     {
-        if (!lwp_user_accessable((void*)oset, size))
+        if (!lwp_user_accessable((void *)oset, size))
         {
         {
             rt_set_errno(EINVAL);
             rt_set_errno(EINVAL);
             return ret;
             return ret;
@@ -2068,12 +2298,12 @@ int sys_thread_sigprocmask(int how, const lwp_sigset_t *sigset, lwp_sigset_t *os
     }
     }
     if (sigset)
     if (sigset)
     {
     {
-        if (!lwp_user_accessable((void*)sigset, size))
+        if (!lwp_user_accessable((void *)sigset, size))
         {
         {
             rt_set_errno(EINVAL);
             rt_set_errno(EINVAL);
             return ret;
             return ret;
         }
         }
-        lwp_get_from_user(&newset, (void*)sigset, sizeof(lwp_sigset_t));
+        lwp_get_from_user(&newset, (void *)sigset, sizeof(lwp_sigset_t));
         pnewset = &newset;
         pnewset = &newset;
     }
     }
     ret = lwp_thread_sigprocmask(how, pnewset, poldset);
     ret = lwp_thread_sigprocmask(how, pnewset, poldset);
@@ -2108,7 +2338,10 @@ struct musl_addrinfo
     struct musl_addrinfo *ai_next;
     struct musl_addrinfo *ai_next;
 };
 };
 
 
-int sys_getaddrinfo(const char *nodename, const char *servname, const struct musl_addrinfo *hints, struct musl_addrinfo *res)
+int sys_getaddrinfo(const char *nodename,
+        const char *servname,
+        const struct musl_addrinfo *hints,
+        struct musl_addrinfo *res)
 {
 {
     int ret = -1;
     int ret = -1;
     struct addrinfo *k_res = NULL;
     struct addrinfo *k_res = NULL;
@@ -2137,7 +2370,7 @@ int sys_getaddrinfo(const char *nodename, const char *servname, const struct mus
 
 
     if (hints)
     if (hints)
     {
     {
-        k_hints = (struct addrinfo*) rt_malloc(sizeof *hints);
+        k_hints = (struct addrinfo *) rt_malloc(sizeof *hints);
         if (!k_hints)
         if (!k_hints)
         {
         {
             rt_set_errno(ENOMEM);
             rt_set_errno(ENOMEM);
@@ -2220,7 +2453,7 @@ int sys_gethostbyname2_r(const char *name, int af, struct hostent *ret,
     }
     }
 
 
     *result = ret;
     *result = ret;
-    sal_buf = (char *)malloc (HOSTENT_BUFSZ);
+    sal_buf = (char *)malloc(HOSTENT_BUFSZ);
     if (sal_buf == NULL)
     if (sal_buf == NULL)
     {
     {
         rt_set_errno(ENOMEM);
         rt_set_errno(ENOMEM);
@@ -2245,7 +2478,7 @@ int sys_gethostbyname2_r(const char *name, int af, struct hostent *ret,
         index = 0;
         index = 0;
         while (sal_he.h_addr_list[index] != NULL)
         while (sal_he.h_addr_list[index] != NULL)
         {
         {
-            index ++;
+            index++;
         }
         }
         cnt = index + 1;
         cnt = index + 1;
 
 
@@ -2258,7 +2491,7 @@ int sys_gethostbyname2_r(const char *name, int af, struct hostent *ret,
         ptr += rt_strlen(k_name);
         ptr += rt_strlen(k_name);
 
 
         ret->h_addr_list = (char**)ptr;
         ret->h_addr_list = (char**)ptr;
-        ptr += cnt * sizeof(char*);
+        ptr += cnt * sizeof(char *);
 
 
         index = 0;
         index = 0;
         while (sal_he.h_addr_list[index] != NULL)
         while (sal_he.h_addr_list[index] != NULL)
@@ -2267,7 +2500,7 @@ int sys_gethostbyname2_r(const char *name, int af, struct hostent *ret,
             rt_memcpy(ptr, sal_he.h_addr_list[index], sal_he.h_length);
             rt_memcpy(ptr, sal_he.h_addr_list[index], sal_he.h_length);
 
 
             ptr += sal_he.h_length;
             ptr += sal_he.h_length;
-            index ++;
+            index++;
         }
         }
         ret->h_addr_list[index] = NULL;
         ret->h_addr_list[index] = NULL;
     }
     }
@@ -2276,8 +2509,14 @@ int sys_gethostbyname2_r(const char *name, int af, struct hostent *ret,
 
 
 __exit:
 __exit:
     /* release buffer */
     /* release buffer */
-    if (sal_buf) free(sal_buf);
-    if (k_name) free(k_name);
+    if (sal_buf)
+    {
+        free(sal_buf);
+    }
+    if (k_name)
+    {
+        free(k_name);
+    }
 
 
     return ret_val;
     return ret_val;
 }
 }
@@ -2325,7 +2564,7 @@ int sys_getdents(int fd, struct libc_dirent *dirp, size_t nbytes)
         return -1;
         return -1;
     }
     }
     rtt_nbytes = cnt * sizeof(struct dirent);
     rtt_nbytes = cnt * sizeof(struct dirent);
-    rtt_dirp = (struct dirent*)rt_malloc(rtt_nbytes);
+    rtt_dirp = (struct dirent *)rt_malloc(rtt_nbytes);
     if (!rtt_dirp)
     if (!rtt_dirp)
     {
     {
         rt_set_errno(ENOMEM);
         rt_set_errno(ENOMEM);
@@ -2382,7 +2621,7 @@ int sys_access(const char *filename, int mode)
     rt_size_t len = 0;
     rt_size_t len = 0;
     char *kname = RT_NULL;
     char *kname = RT_NULL;
 
 
-    if (!lwp_user_accessable((void*)filename, 1))
+    if (!lwp_user_accessable((void *)filename, 1))
     {
     {
         rt_set_errno(EINVAL);
         rt_set_errno(EINVAL);
         return -1;
         return -1;
@@ -2432,12 +2671,16 @@ int sys_clock_settime(clockid_t clk, const struct timespec *ts)
     size_t size = sizeof(struct timespec);
     size_t size = sizeof(struct timespec);
     struct timespec *kts = NULL;
     struct timespec *kts = NULL;
 
 
-    if (!lwp_user_accessable((void*)ts, size))
+    if (!lwp_user_accessable((void *)ts, size))
+    {
         return -EINVAL;
         return -EINVAL;
+    }
 
 
     kts = kmem_get(size);
     kts = kmem_get(size);
     if (!kts)
     if (!kts)
+    {
         return -ENOMEM;
         return -ENOMEM;
+    }
 
 
     lwp_get_from_user(kts, (void *)ts, size);
     lwp_get_from_user(kts, (void *)ts, size);
     now = kts->tv_sec;
     now = kts->tv_sec;
@@ -2466,12 +2709,16 @@ int sys_clock_gettime(clockid_t clk, struct timespec *ts)
     size_t size = sizeof(struct timespec);
     size_t size = sizeof(struct timespec);
     struct timespec *kts = NULL;
     struct timespec *kts = NULL;
 
 
-    if (!lwp_user_accessable((void*)ts, size))
+    if (!lwp_user_accessable((void *)ts, size))
+    {
         return -EINVAL;
         return -EINVAL;
+    }
 
 
     kts = kmem_get(size);
     kts = kmem_get(size);
     if (!kts)
     if (!kts)
+    {
         return -ENOMEM;
         return -ENOMEM;
+    }
 
 
     kts->tv_sec = now;
     kts->tv_sec = now;
     kts->tv_nsec = 0;
     kts->tv_nsec = 0;
@@ -2491,8 +2738,10 @@ int sys_clock_getres(clockid_t clk, struct timespec *ts)
     struct timespec kts;
     struct timespec kts;
     size_t size = sizeof(struct timespec);
     size_t size = sizeof(struct timespec);
 
 
-    if (!lwp_user_accessable((void*)ts, size))
+    if (!lwp_user_accessable((void *)ts, size))
+    {
         return -EINVAL;
         return -EINVAL;
+    }
 
 
     kts.tv_sec = 1;
     kts.tv_sec = 1;
     kts.tv_nsec = 0;
     kts.tv_nsec = 0;
@@ -2517,57 +2766,57 @@ int sys_rename(const char *oldpath,const char *newpath)
 
 
 const static void* func_table[] =
 const static void* func_table[] =
 {
 {
-    (void*)sys_exit,            /* 01 */
-    (void*)sys_read,
-    (void*)sys_write,
-    (void*)sys_lseek,
-    (void*)sys_open,            /* 05 */
-    (void*)sys_close,
-    (void*)sys_ioctl,
-    (void*)sys_fstat,
-    (void*)sys_poll,
-    (void*)sys_nanosleep,       /* 10 */
-    (void*)sys_gettimeofday,
-    (void*)sys_settimeofday,
-    (void*)sys_exec,
-    (void*)sys_kill,
-    (void*)sys_getpid,          /* 15 */
-    (void*)sys_getpriority,
-    (void*)sys_setpriority,
-    (void*)sys_sem_create,
-    (void*)sys_sem_delete,
-    (void*)sys_sem_take,        /* 20 */
-    (void*)sys_sem_release,
-    (void*)sys_mutex_create,
-    (void*)sys_mutex_delete,
-    (void*)sys_mutex_take,
-    (void*)sys_mutex_release,   /* 25 */
-    (void*)sys_event_create,
-    (void*)sys_event_delete,
-    (void*)sys_event_send,
-    (void*)sys_event_recv,
-    (void*)sys_mb_create,       /* 30 */
-    (void*)sys_mb_delete,
-    (void*)sys_mb_send,
-    (void*)sys_mb_send_wait,
-    (void*)sys_mb_recv,
-    (void*)sys_mq_create,       /* 35 */
-    (void*)sys_mq_delete,
-    (void*)sys_mq_send,
-    (void*)sys_mq_urgent,
-    (void*)sys_mq_recv,
-    (void*)sys_thread_create,   /* 40 */
-    (void*)sys_thread_delete,
-    (void*)sys_thread_startup,
-    (void*)sys_thread_self,
-    (void*)sys_channel_open,
-    (void*)sys_channel_close,   /* 45 */
-    (void*)sys_channel_send,
-    (void*)sys_channel_send_recv_timeout,
-    (void*)sys_channel_reply,
-    (void*)sys_channel_recv_timeout,
-    (void*)sys_enter_critical,  /* 50 */
-    (void*)sys_exit_critical,
+    (void *)sys_exit,            /* 01 */
+    (void *)sys_read,
+    (void *)sys_write,
+    (void *)sys_lseek,
+    (void *)sys_open,            /* 05 */
+    (void *)sys_close,
+    (void *)sys_ioctl,
+    (void *)sys_fstat,
+    (void *)sys_poll,
+    (void *)sys_nanosleep,       /* 10 */
+    (void *)sys_gettimeofday,
+    (void *)sys_settimeofday,
+    (void *)sys_exec,
+    (void *)sys_kill,
+    (void *)sys_getpid,          /* 15 */
+    (void *)sys_getpriority,
+    (void *)sys_setpriority,
+    (void *)sys_sem_create,
+    (void *)sys_sem_delete,
+    (void *)sys_sem_take,        /* 20 */
+    (void *)sys_sem_release,
+    (void *)sys_mutex_create,
+    (void *)sys_mutex_delete,
+    (void *)sys_mutex_take,
+    (void *)sys_mutex_release,   /* 25 */
+    (void *)sys_event_create,
+    (void *)sys_event_delete,
+    (void *)sys_event_send,
+    (void *)sys_event_recv,
+    (void *)sys_mb_create,       /* 30 */
+    (void *)sys_mb_delete,
+    (void *)sys_mb_send,
+    (void *)sys_mb_send_wait,
+    (void *)sys_mb_recv,
+    (void *)sys_mq_create,       /* 35 */
+    (void *)sys_mq_delete,
+    (void *)sys_mq_send,
+    (void *)sys_mq_urgent,
+    (void *)sys_mq_recv,
+    (void *)sys_thread_create,   /* 40 */
+    (void *)sys_thread_delete,
+    (void *)sys_thread_startup,
+    (void *)sys_thread_self,
+    (void *)sys_channel_open,
+    (void *)sys_channel_close,   /* 45 */
+    (void *)sys_channel_send,
+    (void *)sys_channel_send_recv_timeout,
+    (void *)sys_channel_reply,
+    (void *)sys_channel_recv_timeout,
+    (void *)sys_enter_critical,  /* 50 */
+    (void *)sys_exit_critical,
 
 
     SYSCALL_USPACE(sys_brk),
     SYSCALL_USPACE(sys_brk),
     SYSCALL_USPACE(sys_mmap2),
     SYSCALL_USPACE(sys_mmap2),
@@ -2668,11 +2917,12 @@ const static void* func_table[] =
     (void *)sys_dup,
     (void *)sys_dup,
     (void *)sys_dup2,
     (void *)sys_dup2,
     (void *)sys_rename,			/* 135 */
     (void *)sys_rename,			/* 135 */
+    (void *)sys_fork,
 };
 };
 
 
 const void *lwp_get_sys_api(rt_uint32_t number)
 const void *lwp_get_sys_api(rt_uint32_t number)
 {
 {
-    const void *func = (const void*)sys_notimpl;
+    const void *func = (const void *)sys_notimpl;
 
 
     if (number == 0xff)
     if (number == 0xff)
     {
     {
@@ -2681,7 +2931,7 @@ const void *lwp_get_sys_api(rt_uint32_t number)
     else
     else
     {
     {
         number -= 1;
         number -= 1;
-        if (number < sizeof(func_table)/sizeof(func_table[0]))
+        if (number < sizeof(func_table) / sizeof(func_table[0]))
         {
         {
             func = func_table[number];
             func = func_table[number];
         }
         }

+ 115 - 41
components/lwp/lwp_user_mm.c

@@ -38,8 +38,8 @@ void lwp_mmu_switch(struct rt_thread *thread)
 
 
     if (thread->lwp)
     if (thread->lwp)
     {
     {
-        l = (struct rt_lwp*)thread->lwp;
-        new_mmu_table = (void*)((char*)l->mmu_info.vtable + l->mmu_info.pv_off);
+        l = (struct rt_lwp *)thread->lwp;
+        new_mmu_table = (void *)((char *)l->mmu_info.vtable + l->mmu_info.pv_off);
 #ifdef LWP_DEBUG
 #ifdef LWP_DEBUG
         {
         {
             int i = 0;
             int i = 0;
@@ -49,7 +49,7 @@ void lwp_mmu_switch(struct rt_thread *thread)
             for (i = 0; i < 0x1000; i++)
             for (i = 0; i < 0x1000; i++)
             {
             {
                 rt_kprintf("0x%08x ", *p++);
                 rt_kprintf("0x%08x ", *p++);
-                if (( i & 0xf) == 0xf)
+                if ((i & 0xf) == 0xf)
                 {
                 {
                     rt_kprintf("\n");
                     rt_kprintf("\n");
                 }
                 }
@@ -94,7 +94,7 @@ static void unmap_range(struct rt_lwp *lwp, void *addr, size_t size, int pa_need
     void *va = RT_NULL, *pa = RT_NULL;
     void *va = RT_NULL, *pa = RT_NULL;
     int i = 0;
     int i = 0;
 
 
-    for (va = addr, i = 0; i < size; va = (void*)((char*)va + ARCH_PAGE_SIZE), i += ARCH_PAGE_SIZE)
+    for (va = addr, i = 0; i < size; va = (void *)((char *)va + ARCH_PAGE_SIZE), i += ARCH_PAGE_SIZE)
     {
     {
         pa = rt_hw_mmu_v2p(&lwp->mmu_info, va);
         pa = rt_hw_mmu_v2p(&lwp->mmu_info, va);
         if (pa)
         if (pa)
@@ -102,7 +102,7 @@ static void unmap_range(struct rt_lwp *lwp, void *addr, size_t size, int pa_need
             rt_hw_mmu_unmap(&lwp->mmu_info, va, ARCH_PAGE_SIZE);
             rt_hw_mmu_unmap(&lwp->mmu_info, va, ARCH_PAGE_SIZE);
             if (pa_need_free)
             if (pa_need_free)
             {
             {
-                rt_pages_free((void*)((char*)pa - PV_OFFSET), 0);
+                rt_pages_free((void *)((char *)pa - PV_OFFSET), 0);
             }
             }
         }
         }
     }
     }
@@ -110,19 +110,25 @@ static void unmap_range(struct rt_lwp *lwp, void *addr, size_t size, int pa_need
 
 
 void lwp_unmap_user_space(struct rt_lwp *lwp)
 void lwp_unmap_user_space(struct rt_lwp *lwp)
 {
 {
-    struct lwp_avl_struct* node = RT_NULL;
+    struct lwp_avl_struct *node = RT_NULL;
     rt_mmu_info *m_info = &lwp->mmu_info;
     rt_mmu_info *m_info = &lwp->mmu_info;
 
 
     while ((node = lwp_map_find_first(lwp->map_area)) != 0)
     while ((node = lwp_map_find_first(lwp->map_area)) != 0)
     {
     {
-        struct rt_mm_area_struct *ma = (struct rt_mm_area_struct*)node->data;
+        struct rt_mm_area_struct *ma = (struct rt_mm_area_struct *)node->data;
         int pa_need_free = 0;
         int pa_need_free = 0;
 
 
         RT_ASSERT(ma->type < MM_AREA_TYPE_UNKNOW);
         RT_ASSERT(ma->type < MM_AREA_TYPE_UNKNOW);
 
 
-        if ((ma->type == MM_AREA_TYPE_DATA) || (ma->type == MM_AREA_TYPE_TEXT))
+        switch (ma->type)
         {
         {
-            pa_need_free = 1;
+            case MM_AREA_TYPE_DATA:
+            case MM_AREA_TYPE_TEXT:
+                pa_need_free = 1;
+                break;
+            case MM_AREA_TYPE_SHM:
+                lwp_shm_ref_dec(lwp, (void *)ma->addr);
+                break;
         }
         }
         unmap_range(lwp, (void *)ma->addr, ma->size, pa_need_free);
         unmap_range(lwp, (void *)ma->addr, ma->size, pa_need_free);
         lwp_map_area_remove(&lwp->map_area, ma->addr);
         lwp_map_area_remove(&lwp->map_area, ma->addr);
@@ -180,6 +186,70 @@ int lwp_unmap_user(struct rt_lwp *lwp, void *va)
     return 0;
     return 0;
 }
 }
 
 
+int lwp_dup_user(struct lwp_avl_struct *ptree, void *arg)
+{
+    struct rt_lwp *self_lwp = lwp_self();
+    struct rt_lwp *new_lwp = (struct rt_lwp *)arg;
+    struct rt_mm_area_struct *ma = (struct rt_mm_area_struct *)ptree->data;
+    void *pa = RT_NULL;
+    void *va = RT_NULL;
+
+    switch (ma->type)
+    {
+        case MM_AREA_TYPE_PHY:
+            pa = rt_hw_mmu_v2p(&self_lwp->mmu_info, (void *)ma->addr);
+            va = lwp_map_user_type(new_lwp, (void *)ma->addr, pa, ma->size, 0, MM_AREA_TYPE_PHY);
+            break;
+        case MM_AREA_TYPE_PHY_CACHED:
+            pa = rt_hw_mmu_v2p(&self_lwp->mmu_info, (void *)ma->addr);
+            va = lwp_map_user_type(new_lwp, (void *)ma->addr, pa, ma->size, 0, MM_AREA_TYPE_PHY_CACHED);
+            break;
+        case MM_AREA_TYPE_SHM:
+            va = (void *)ma->addr;
+            if (lwp_shm_ref_inc(self_lwp, va) > 0)
+            {
+                pa = rt_hw_mmu_v2p(&self_lwp->mmu_info, va);
+                va = lwp_map_user_type(new_lwp, va, pa, ma->size, 1, MM_AREA_TYPE_SHM);
+            }
+            break;
+        case MM_AREA_TYPE_DATA:
+            va = lwp_map_user(new_lwp, (void *)ma->addr, ma->size, 0);
+            if (va == (void *)ma->addr)
+            {
+                lwp_data_put(&new_lwp->mmu_info, va, va, ma->size);
+            }
+            break;
+        case MM_AREA_TYPE_TEXT:
+            {
+                char *addr = (char *)ma->addr;
+                size_t size = ma->size;
+
+                while (size)
+                {
+                    pa = rt_hw_mmu_v2p(&self_lwp->mmu_info, (void *)addr);
+                    rt_page_ref_inc((char *)pa - self_lwp->mmu_info.pv_off, 0);
+                    va = lwp_map_user_type(new_lwp, addr, pa, ARCH_PAGE_SIZE, 1, MM_AREA_TYPE_TEXT);
+                    if (va != addr)
+                    {
+                        return -1;
+                    }
+                    addr += ARCH_PAGE_SIZE;
+                    size -= ARCH_PAGE_SIZE;
+                }
+                va = (void *)ma->addr;
+            }
+            break;
+        default:
+            RT_ASSERT(0);
+            break;
+    }
+    if (va != (void *)ma->addr)
+    {
+        return -1;
+    }
+    return 0;
+}
+
 int lwp_unmap_user_phy(struct rt_lwp *lwp, void *va)
 int lwp_unmap_user_phy(struct rt_lwp *lwp, void *va)
 {
 {
     return lwp_unmap_user(lwp, va);
     return lwp_unmap_user(lwp, va);
@@ -203,14 +273,14 @@ void *lwp_map_user(struct rt_lwp *lwp, void *map_va, size_t map_size, int text)
     offset = (size_t)map_va & ARCH_PAGE_MASK;
     offset = (size_t)map_va & ARCH_PAGE_MASK;
     map_size += (offset + ARCH_PAGE_SIZE - 1);
     map_size += (offset + ARCH_PAGE_SIZE - 1);
     map_size &= ~ARCH_PAGE_MASK;
     map_size &= ~ARCH_PAGE_MASK;
-    map_va = (void*)((size_t)map_va & ~ARCH_PAGE_MASK);
+    map_va = (void *)((size_t)map_va & ~ARCH_PAGE_MASK);
 
 
     level = rt_hw_interrupt_disable();
     level = rt_hw_interrupt_disable();
     ret = _lwp_map_user(lwp, map_va, map_size, text);
     ret = _lwp_map_user(lwp, map_va, map_size, text);
     rt_hw_interrupt_enable(level);
     rt_hw_interrupt_enable(level);
     if (ret)
     if (ret)
     {
     {
-        ret = (void*)((char*)ret + offset);
+        ret = (void *)((char *)ret + offset);
     }
     }
     return ret;
     return ret;
 }
 }
@@ -225,6 +295,10 @@ static void *_lwp_map_user_type(struct rt_lwp *lwp, void *map_va, void *map_pa,
     if (cached)
     if (cached)
     {
     {
         attr = MMU_MAP_U_RWCB;
         attr = MMU_MAP_U_RWCB;
+        if (type == MM_AREA_TYPE_PHY)
+        {
+            type = MM_AREA_TYPE_PHY_CACHED;
+        }
     }
     }
     else
     else
     {
     {
@@ -261,14 +335,14 @@ void *lwp_map_user_type(struct rt_lwp *lwp, void *map_va, void *map_pa, size_t m
     offset = (size_t)map_pa & ARCH_PAGE_MASK;
     offset = (size_t)map_pa & ARCH_PAGE_MASK;
     map_size += (offset + ARCH_PAGE_SIZE - 1);
     map_size += (offset + ARCH_PAGE_SIZE - 1);
     map_size &= ~ARCH_PAGE_MASK;
     map_size &= ~ARCH_PAGE_MASK;
-    map_pa = (void*)((size_t)map_pa & ~ARCH_PAGE_MASK);
+    map_pa = (void *)((size_t)map_pa & ~ARCH_PAGE_MASK);
 
 
     level = rt_hw_interrupt_disable();
     level = rt_hw_interrupt_disable();
     ret = _lwp_map_user_type(lwp, map_va, map_pa, map_size, cached, type);
     ret = _lwp_map_user_type(lwp, map_va, map_pa, map_size, cached, type);
     rt_hw_interrupt_enable(level);
     rt_hw_interrupt_enable(level);
     if (ret)
     if (ret)
     {
     {
-        ret = (void*)((char*)ret + offset);
+        ret = (void *)((char *)ret + offset);
     }
     }
     return ret;
     return ret;
 }
 }
@@ -297,7 +371,7 @@ int lwp_brk(void *addr)
         void *va;
         void *va;
 
 
         size = (((size_t)addr - lwp->end_heap) + ARCH_PAGE_SIZE - 1) & ~ARCH_PAGE_MASK;
         size = (((size_t)addr - lwp->end_heap) + ARCH_PAGE_SIZE - 1) & ~ARCH_PAGE_MASK;
-        va = lwp_map_user(lwp, (void*)lwp->end_heap, size, 0);
+        va = lwp_map_user(lwp, (void *)lwp->end_heap, size, 0);
         if (va)
         if (va)
         {
         {
             lwp->end_heap += size;
             lwp->end_heap += size;
@@ -316,7 +390,7 @@ void* lwp_mmap2(void *addr, size_t length, int prot,
         int flags, int fd, off_t pgoffset)
         int flags, int fd, off_t pgoffset)
 {
 {
     rt_base_t level = 0;
     rt_base_t level = 0;
-    void *ret = (void*)-1;
+    void *ret = (void *)-1;
     struct rt_lwp *lwp = RT_NULL;
     struct rt_lwp *lwp = RT_NULL;
 
 
     level = rt_hw_interrupt_disable();
     level = rt_hw_interrupt_disable();
@@ -326,7 +400,7 @@ void* lwp_mmap2(void *addr, size_t length, int prot,
         ret = lwp_map_user(lwp, addr, length, 0);
         ret = lwp_map_user(lwp, addr, length, 0);
         if (!ret)
         if (!ret)
         {
         {
-            ret = (void*)-1;
+            ret = (void *)-1;
         }
         }
     }
     }
     rt_hw_interrupt_enable(level);
     rt_hw_interrupt_enable(level);
@@ -352,11 +426,11 @@ size_t lwp_get_from_user(void *dst, void *src, size_t size)
     rt_mmu_info *m_info = RT_NULL;
     rt_mmu_info *m_info = RT_NULL;
 
 
     /* check src */
     /* check src */
-    if (src >= (void*)KERNEL_VADDR_START)
+    if (src >= (void *)KERNEL_VADDR_START)
     {
     {
         return 0;
         return 0;
     }
     }
-    if ((void*)((char*)src + size) > (void*)KERNEL_VADDR_START)
+    if ((void *)((char *)src + size) > (void *)KERNEL_VADDR_START)
     {
     {
         return 0;
         return 0;
     }
     }
@@ -377,11 +451,11 @@ size_t lwp_put_to_user(void *dst, void *src, size_t size)
     rt_mmu_info *m_info = RT_NULL;
     rt_mmu_info *m_info = RT_NULL;
 
 
     /* check dst */
     /* check dst */
-    if (dst >= (void*)KERNEL_VADDR_START)
+    if (dst >= (void *)KERNEL_VADDR_START)
     {
     {
         return 0;
         return 0;
     }
     }
-    if ((void*)((char*)dst + size) > (void*)KERNEL_VADDR_START)
+    if ((void *)((char *)dst + size) > (void *)KERNEL_VADDR_START)
     {
     {
         return 0;
         return 0;
     }
     }
@@ -411,8 +485,8 @@ int lwp_user_accessable(void *addr, size_t size)
         return 0;
         return 0;
     }
     }
     addr_start = addr;
     addr_start = addr;
-    addr_end = (void*)((char*)addr + size);
-    if (addr_start >= (void*)KERNEL_VADDR_START)
+    addr_end = (void *)((char *)addr + size);
+    if (addr_start >= (void *)KERNEL_VADDR_START)
     {
     {
         return 0;
         return 0;
     }
     }
@@ -422,10 +496,10 @@ int lwp_user_accessable(void *addr, size_t size)
     }
     }
 
 
     mmu_info = &lwp->mmu_info;
     mmu_info = &lwp->mmu_info;
-    next_page = (void*)(((size_t)addr_start + ARCH_PAGE_SIZE) & ~(ARCH_PAGE_SIZE - 1));
+    next_page = (void *)(((size_t)addr_start + ARCH_PAGE_SIZE) & ~(ARCH_PAGE_SIZE - 1));
     do
     do
     {
     {
-        size_t len = (char*)next_page - (char*)addr_start;
+        size_t len = (char *)next_page - (char *)addr_start;
 
 
         if (size < len)
         if (size < len)
         {
         {
@@ -436,9 +510,9 @@ int lwp_user_accessable(void *addr, size_t size)
         {
         {
             return 0;
             return 0;
         }
         }
-        addr_start = (void*)((char*)addr_start + len);
+        addr_start = (void *)((char *)addr_start + len);
         size -= len;
         size -= len;
-        next_page = (void*)((char*)next_page + ARCH_PAGE_SIZE);
+        next_page = (void *)((char *)next_page + ARCH_PAGE_SIZE);
     } while (addr_start < addr_end);
     } while (addr_start < addr_end);
     return 1;
     return 1;
 }
 }
@@ -456,11 +530,11 @@ size_t lwp_data_get(rt_mmu_info *mmu_info, void *dst, void *src, size_t size)
     }
     }
     tmp_dst = dst;
     tmp_dst = dst;
     addr_start = src;
     addr_start = src;
-    addr_end = (void*)((char*)src + size);
-    next_page = (void*)(((size_t)addr_start + ARCH_PAGE_SIZE) & ~(ARCH_PAGE_SIZE - 1));
+    addr_end = (void *)((char *)src + size);
+    next_page = (void *)(((size_t)addr_start + ARCH_PAGE_SIZE) & ~(ARCH_PAGE_SIZE - 1));
     do
     do
     {
     {
-        size_t len = (char*)next_page - (char*)addr_start;
+        size_t len = (char *)next_page - (char *)addr_start;
 
 
         if (size < len)
         if (size < len)
         {
         {
@@ -471,12 +545,12 @@ size_t lwp_data_get(rt_mmu_info *mmu_info, void *dst, void *src, size_t size)
         {
         {
             break;
             break;
         }
         }
-        tmp_src = (void*)((char*)rt_hw_mmu_v2p(mmu_info, addr_start) - PV_OFFSET);
+        tmp_src = (void *)((char *)rt_hw_mmu_v2p(mmu_info, addr_start) - PV_OFFSET);
         rt_memcpy(tmp_dst, tmp_src, len);
         rt_memcpy(tmp_dst, tmp_src, len);
-        tmp_dst = (void*)((char*)tmp_dst + len);
-        addr_start = (void*)((char*)addr_start + len);
+        tmp_dst = (void *)((char *)tmp_dst + len);
+        addr_start = (void *)((char *)addr_start + len);
         size -= len;
         size -= len;
-        next_page = (void*)((char*)next_page + ARCH_PAGE_SIZE);
+        next_page = (void *)((char *)next_page + ARCH_PAGE_SIZE);
         copy_len += len;
         copy_len += len;
     } while (addr_start < addr_end);
     } while (addr_start < addr_end);
     return copy_len;
     return copy_len;
@@ -495,11 +569,11 @@ size_t lwp_data_put(rt_mmu_info *mmu_info, void *dst, void *src, size_t size)
     }
     }
     tmp_src = src;
     tmp_src = src;
     addr_start = dst;
     addr_start = dst;
-    addr_end = (void*)((char*)dst + size);
-    next_page = (void*)(((size_t)addr_start + ARCH_PAGE_SIZE) & ~(ARCH_PAGE_SIZE - 1));
+    addr_end = (void *)((char *)dst + size);
+    next_page = (void *)(((size_t)addr_start + ARCH_PAGE_SIZE) & ~(ARCH_PAGE_SIZE - 1));
     do
     do
     {
     {
-        size_t len = (char*)next_page - (char*)addr_start;
+        size_t len = (char *)next_page - (char *)addr_start;
 
 
         if (size < len)
         if (size < len)
         {
         {
@@ -510,12 +584,12 @@ size_t lwp_data_put(rt_mmu_info *mmu_info, void *dst, void *src, size_t size)
         {
         {
             break;
             break;
         }
         }
-        tmp_dst = (void*)((char*)rt_hw_mmu_v2p(mmu_info, addr_start) - PV_OFFSET);
+        tmp_dst = (void *)((char *)rt_hw_mmu_v2p(mmu_info, addr_start) - PV_OFFSET);
         rt_memcpy(tmp_dst, tmp_src, len);
         rt_memcpy(tmp_dst, tmp_src, len);
-        tmp_src = (void*)((char*)tmp_src + len);
-        addr_start = (void*)((char*)addr_start + len);
+        tmp_src = (void *)((char *)tmp_src + len);
+        addr_start = (void *)((char *)addr_start + len);
         size -= len;
         size -= len;
-        next_page = (void*)((char*)next_page + ARCH_PAGE_SIZE);
+        next_page = (void *)((char *)next_page + ARCH_PAGE_SIZE);
         copy_len += len;
         copy_len += len;
     } while (addr_start < addr_end);
     } while (addr_start < addr_end);
     return copy_len;
     return copy_len;
@@ -526,7 +600,7 @@ void lwp_data_cache_flush(rt_mmu_info *mmu_info, void *vaddr, size_t size)
     void *paddr = RT_NULL;
     void *paddr = RT_NULL;
 
 
     paddr = rt_hw_mmu_v2p(mmu_info, vaddr);
     paddr = rt_hw_mmu_v2p(mmu_info, vaddr);
-    paddr = (void*)((char*)paddr - PV_OFFSET);
+    paddr = (void *)((char *)paddr - PV_OFFSET);
 
 
     rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, paddr, size);
     rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, paddr, size);
 }
 }

+ 3 - 3
libcpu/arm/cortex-a/mmu.c

@@ -298,7 +298,7 @@ int rt_hw_mmu_ioremap_init(rt_mmu_info *mmu_info, void* v_address, size_t size)
         }
         }
 
 
 #ifndef RT_USING_USERSPACE
 #ifndef RT_USING_USERSPACE
-        ref_cnt = mmu_l2 + (ARCH_SECTION_SIZE/ARCH_PAGE_SIZE);
+        ref_cnt = mmu_l2 + (ARCH_SECTION_SIZE / ARCH_PAGE_SIZE);
         *ref_cnt = 1;
         *ref_cnt = 1;
 #endif
 #endif
 
 
@@ -455,7 +455,7 @@ static void __rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t npages
                 rt_hw_cpu_dcache_clean(mmu_l1, 4);
                 rt_hw_cpu_dcache_clean(mmu_l1, 4);
             }
             }
 #else
 #else
-            ref_cnt = mmu_l2 + (ARCH_SECTION_SIZE/ARCH_PAGE_SIZE);
+            ref_cnt = mmu_l2 + (ARCH_SECTION_SIZE / ARCH_PAGE_SIZE);
             (*ref_cnt)--;
             (*ref_cnt)--;
             if (!*ref_cnt)
             if (!*ref_cnt)
             {
             {
@@ -523,7 +523,7 @@ static int __rt_hw_mmu_map(rt_mmu_info *mmu_info, void* v_addr, void* p_addr, si
         }
         }
 
 
 #ifndef RT_USING_USERSPACE
 #ifndef RT_USING_USERSPACE
-        ref_cnt = mmu_l2 + (ARCH_SECTION_SIZE/ARCH_PAGE_SIZE);
+        ref_cnt = mmu_l2 + (ARCH_SECTION_SIZE / ARCH_PAGE_SIZE);
         (*ref_cnt)++;
         (*ref_cnt)++;
 #endif
 #endif
 
 

+ 1 - 1
libcpu/arm/cortex-a/page.c

@@ -134,7 +134,7 @@ static void _pages_ref_inc(struct page *p, uint32_t size_bits)
     }
     }
     idx = idx & ~((1UL << size_bits) - 1);
     idx = idx & ~((1UL << size_bits) - 1);
 
 
-    page_head= page_start + idx;
+    page_head = page_start + idx;
     page_head->ref_cnt++;
     page_head->ref_cnt++;
 }
 }
 
 

+ 1 - 1
src/object.c

@@ -487,7 +487,7 @@ rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
 #ifdef RT_USING_LWP
 #ifdef RT_USING_LWP
     {
     {
         struct rt_lwp *lwp = lwp_self();
         struct rt_lwp *lwp = lwp_self();
-        if (lwp)
+        if (lwp && type != RT_Object_Class_Thread)
         {
         {
             /* insert object into lwP object list */
             /* insert object into lwP object list */
             rt_list_insert_after(&(lwp->object_list), &(object->lwp_obj_list));
             rt_list_insert_after(&(lwp->object_list), &(object->lwp_obj_list));