Explorar el Código

!167 解决lwp的object自动释放行为及完成一些测试问题修正
Merge pull request !167 from jesven/lwp_object

bernard hace 4 años
padre
commit
a8eb4459aa

+ 7 - 0
components/dfs/filesystems/cromfs/dfs_cromfs.c

@@ -937,6 +937,11 @@ static int dfs_cromfs_open(struct dfs_fd *file)
     RT_ASSERT(file->fnode->ref_count > 0);
     if (file->fnode->ref_count > 1)
     {
+        if (file->fnode->type == FT_DIRECTORY
+                && !(file->flags & O_DIRECTORY))
+        {
+            return -ENOENT;
+        }
         file->pos = 0;
         return 0;
     }
@@ -959,6 +964,7 @@ static int dfs_cromfs_open(struct dfs_fd *file)
             ret = -ENOENT;
             goto end;
         }
+        file->fnode->type = FT_DIRECTORY;
     }
     else
     {
@@ -968,6 +974,7 @@ static int dfs_cromfs_open(struct dfs_fd *file)
             ret = -ENOENT;
             goto end;
         }
+        file->fnode->type = FT_REGULAR;
     }
 
     result =  rt_mutex_take(&ci->lock, RT_WAITING_FOREVER);

+ 12 - 0
components/dfs/filesystems/devfs/devfs.c

@@ -90,6 +90,12 @@ int dfs_device_fs_close(struct dfs_fd *file)
     rt_device_t dev_id;
 
     RT_ASSERT(file != RT_NULL);
+    RT_ASSERT(file->fnode->ref_count > 0);
+
+    if (file->fnode->ref_count > 1)
+    {
+        return 0;
+    }
 
     if (file->fnode->type == FT_DIRECTORY)
     {
@@ -125,6 +131,12 @@ int dfs_device_fs_open(struct dfs_fd *file)
     rt_device_t device;
     rt_base_t level;
 
+    RT_ASSERT(file->fnode->ref_count > 0);
+    if (file->fnode->ref_count > 1)
+    {
+        file->pos = 0;
+        return 0;
+    }
     /* open root directory */
     if ((file->fnode->path[0] == '/') && (file->fnode->path[1] == '\0') &&
         (file->flags & O_DIRECTORY))

+ 73 - 2
components/dfs/filesystems/elmfat/dfs_elm.c

@@ -86,10 +86,12 @@ static int get_disk(rt_device_t id)
 {
     int index;
 
-    for (index = 0; index < _VOLUMES; index ++)
+    for (index = 0; index < _VOLUMES; index++)
     {
         if (disk[index] == id)
+        {
             return index;
+        }
     }
 
     return -1;
@@ -106,7 +108,9 @@ int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *d
     /* get an empty position */
     index = get_disk(RT_NULL);
     if (index == -1)
+    {
         return -ENOENT;
+    }
     logic_nbr[0] = '0' + index;
 
     /* save device */
@@ -148,7 +152,9 @@ int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *d
         /* open the root directory to test whether the fatfs is valid */
         result = f_opendir(dir, drive);
         if (result != FR_OK)
+        {
             goto __err;
+        }
 
         /* mount succeed! */
         fs->data = fat;
@@ -177,12 +183,16 @@ int dfs_elm_unmount(struct dfs_filesystem *fs)
     /* find the device index and then umount it */
     index = get_disk(fs->dev_id);
     if (index == -1) /* not found */
+    {
         return -ENOENT;
+    }
 
     logic_nbr[0] = '0' + index;
     result = f_mount(RT_NULL, logic_nbr, (BYTE)1);
     if (result != FR_OK)
+    {
         return elm_result_to_dfs(result);
+    }
 
     fs->data = RT_NULL;
     disk[index] = RT_NULL;
@@ -304,7 +314,9 @@ int dfs_elm_statfs(struct dfs_filesystem *fs, struct statfs *buf)
     rt_snprintf(driver, sizeof(driver), "%d:", f->drv);
     res = f_getfree(driver, &fre_clust, &f);
     if (res)
+    {
         return elm_result_to_dfs(res);
+    }
 
     /* Get total sectors and free sectors */
     tot_sect = (f->n_fatent - 2) * f->csize;
@@ -333,13 +345,29 @@ int dfs_elm_open(struct dfs_fd *file)
     struct dfs_filesystem *fs = file->fnode->fs;
     extern int elm_get_vol(FATFS * fat);
 
+    RT_ASSERT(file->fnode->ref_count > 0);
+    if (file->fnode->ref_count > 1)
+    {
+        if (file->fnode->type == FT_DIRECTORY
+                && !(file->flags & O_DIRECTORY))
+        {
+            return -ENOENT;
+        }
+        file->pos = 0;
+        return 0;
+    }
+
     if (fs == NULL)
+    {
         return -ENOENT;
+    }
 
     /* add path for ELM FatFS driver support */
     vol = elm_get_vol((FATFS *)fs->data);
     if (vol < 0)
+    {
         return -ENOENT;
+    }
     drivers_fn = (char *)rt_malloc(256);
     if (drivers_fn == RT_NULL)
     {
@@ -388,6 +416,7 @@ int dfs_elm_open(struct dfs_fd *file)
         }
 
         file->data = dir;
+        file->fnode->type = FT_DIRECTORY;
         return RT_EOK;
     }
     else
@@ -436,6 +465,7 @@ int dfs_elm_open(struct dfs_fd *file)
         {
             file->pos  = fd->fptr;
             file->fnode->size = f_size(fd);
+            file->fnode->type = FT_REGULAR;
             file->data = fd;
 
             if (file->flags & O_APPEND)
@@ -460,6 +490,11 @@ int dfs_elm_close(struct dfs_fd *file)
 {
     FRESULT result;
 
+    RT_ASSERT(file->fnode->ref_count > 0);
+    if (file->fnode->ref_count > 1)
+    {
+        return 0;
+    }
     result = FR_OK;
     if (file->fnode->type == FT_DIRECTORY)
     {
@@ -538,7 +573,9 @@ int dfs_elm_read(struct dfs_fd *file, void *buf, size_t len)
     /* update position */
     file->pos  = fd->fptr;
     if (result == FR_OK)
+    {
         return byte_read;
+    }
 
     return elm_result_to_dfs(result);
 }
@@ -634,7 +671,9 @@ int dfs_elm_getdents(struct dfs_fd *file, struct dirent *dirp, uint32_t count)
     /* make integer count */
     count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
     if (count == 0)
+    {
         return -EINVAL;
+    }
 
     index = 0;
     while (1)
@@ -645,7 +684,9 @@ int dfs_elm_getdents(struct dfs_fd *file, struct dirent *dirp, uint32_t count)
 
         result = f_readdir(dir, &fno);
         if (result != FR_OK || fno.fname[0] == 0)
+        {
             break;
+        }
 
 #if _USE_LFN
         fn = *fno.fname ? fno.fname : fno.altname;
@@ -655,21 +696,29 @@ int dfs_elm_getdents(struct dfs_fd *file, struct dirent *dirp, uint32_t count)
 
         d->d_type = DT_UNKNOWN;
         if (fno.fattrib & AM_DIR)
+        {
             d->d_type = DT_DIR;
+        }
         else
+        {
             d->d_type = DT_REG;
+        }
 
         d->d_namlen = (rt_uint8_t)rt_strlen(fn);
         d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
         rt_strncpy(d->d_name, fn, rt_strlen(fn) + 1);
 
-        index ++;
+        index++;
         if (index * sizeof(struct dirent) >= count)
+        {
             break;
+        }
     }
 
     if (index == 0)
+    {
         return elm_result_to_dfs(result);
+    }
 
     file->pos += index * sizeof(struct dirent);
 
@@ -688,10 +737,14 @@ int dfs_elm_unlink(struct dfs_filesystem *fs, const char *path)
     /* add path for ELM FatFS driver support */
     vol = elm_get_vol((FATFS *)fs->data);
     if (vol < 0)
+    {
         return -ENOENT;
+    }
     drivers_fn = (char *)rt_malloc(256);
     if (drivers_fn == RT_NULL)
+    {
         return -ENOMEM;
+    }
 
     rt_snprintf(drivers_fn, 256, "%d:%s", vol, path);
 #else
@@ -719,11 +772,15 @@ int dfs_elm_rename(struct dfs_filesystem *fs, const char *oldpath, const char *n
     /* add path for ELM FatFS driver support */
     vol = elm_get_vol((FATFS *)fs->data);
     if (vol < 0)
+    {
         return -ENOENT;
+    }
 
     drivers_oldfn = (char *)rt_malloc(256);
     if (drivers_oldfn == RT_NULL)
+    {
         return -ENOMEM;
+    }
     drivers_newfn = newpath;
 
     rt_snprintf(drivers_oldfn, 256, "%d:%s", vol, oldpath);
@@ -754,10 +811,14 @@ int dfs_elm_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
     /* add path for ELM FatFS driver support */
     vol = elm_get_vol((FATFS *)fs->data);
     if (vol < 0)
+    {
         return -ENOENT;
+    }
     drivers_fn = (char *)rt_malloc(256);
     if (drivers_fn == RT_NULL)
+    {
         return -ENOMEM;
+    }
 
     rt_snprintf(drivers_fn, 256, "%d:%s", vol, path);
 #else
@@ -782,7 +843,9 @@ int dfs_elm_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
             st->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
         }
         if (file_info.fattrib & AM_RDO)
+        {
             st->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
+        }
 
         st->st_size  = file_info.fsize;
 
@@ -912,7 +975,9 @@ DRESULT disk_ioctl(BYTE drv, BYTE ctrl, void *buff)
     rt_device_t device = disk[drv];
 
     if (device == RT_NULL)
+    {
         return RES_ERROR;
+    }
 
     if (ctrl == GET_SECTOR_COUNT)
     {
@@ -923,7 +988,9 @@ DRESULT disk_ioctl(BYTE drv, BYTE ctrl, void *buff)
 
         *(DWORD *)buff = geometry.sector_count;
         if (geometry.sector_count == 0)
+        {
             return RES_ERROR;
+        }
     }
     else if (ctrl == GET_SECTOR_SIZE)
     {
@@ -1007,7 +1074,9 @@ int ff_cre_syncobj(BYTE drv, _SYNC_t *m)
 int ff_del_syncobj(_SYNC_t m)
 {
     if (m != RT_NULL)
+    {
         rt_mutex_delete(m);
+    }
 
     return RT_TRUE;
 }
@@ -1015,7 +1084,9 @@ int ff_del_syncobj(_SYNC_t m)
 int ff_req_grant(_SYNC_t m)
 {
     if (rt_mutex_take(m, _FS_TIMEOUT) == RT_EOK)
+    {
         return RT_TRUE;
+    }
 
     return RT_FALSE;
 }

+ 20 - 0
components/dfs/filesystems/jffs2/dfs_jffs2.c

@@ -223,6 +223,18 @@ static int dfs_jffs2_open(struct dfs_fd* file)
     struct dfs_filesystem *fs;
     struct cyg_mtab_entry * mte;
 
+    RT_ASSERT(file->fnode->ref_count > 0);
+    if (file->fnode->ref_count > 1)
+    {
+        if (file->fnode->type == FT_DIRECTORY
+                && !(file->flags & O_DIRECTORY))
+        {
+            return -ENOENT;
+        }
+        file->pos = 0;
+        return 0;
+    }
+
     oflag = file->flags;
     fs = file->fnode->fs;
     RT_ASSERT(fs != RT_NULL);
@@ -282,6 +294,7 @@ static int dfs_jffs2_open(struct dfs_fd* file)
 #endif
         /* save this pointer, it will be used by dfs_jffs2_getdents*/
         file->fnode->data = jffs2_file;
+        file->fnode->type = FT_DIRECTORY;
         return 0;
     }
     /* regular file operations */
@@ -309,6 +322,7 @@ static int dfs_jffs2_open(struct dfs_fd* file)
     file->fnode->data = jffs2_file;
     file->pos = jffs2_file->f_offset;
     file->fnode->size = 0;
+    file->fnode->type = FT_REGULAR;
     jffs2_file_lseek(jffs2_file, (off_t *)(&(file->fnode->size)), SEEK_END);
     jffs2_file->f_offset = (off_t)file->pos;
     rt_mutex_release(&jffs2_lock);
@@ -328,6 +342,12 @@ static int dfs_jffs2_close(struct dfs_fd* file)
     cyg_file * jffs2_file;
 
     RT_ASSERT(file->fnode->data != NULL);
+    RT_ASSERT(file->fnode->ref_count > 0);
+    if (file->fnode->ref_count > 1)
+    {
+        return 0;
+    }
+
     jffs2_file = (cyg_file *)(file->fnode->data);
 
     if (file->flags & O_DIRECTORY) /* operations about dir */

+ 20 - 0
components/dfs/filesystems/nfs/dfs_nfs.c

@@ -714,6 +714,13 @@ int nfs_close(struct dfs_fd *file)
     nfs_filesystem *nfs;
     RT_ASSERT(file->fnode->data != NULL);
     struct dfs_filesystem *dfs_nfs  = ((struct dfs_filesystem *)(file->fnode->data));
+
+    RT_ASSERT(file->fnode->ref_count > 0);
+    if (file->fnode->ref_count > 1)
+    {
+        return 0;
+    }
+
     nfs = (struct nfs_filesystem *)(dfs_nfs->data);
 
     if (file->fnode->type == FT_DIRECTORY)
@@ -747,6 +754,18 @@ int nfs_open(struct dfs_fd *file)
     nfs = (struct nfs_filesystem *)(dfs_nfs->data);
     RT_ASSERT(nfs != NULL);
 
+    RT_ASSERT(file->fnode->ref_count > 0);
+    if (file->fnode->ref_count > 1)
+    {
+        if (file->fnode->type == FT_DIRECTORY
+                && !(file->flags & O_DIRECTORY))
+        {
+            return -ENOENT;
+        }
+        file->pos = 0;
+        return 0;
+    }
+
     if (file->flags & O_DIRECTORY)
     {
         nfs_dir *dir;
@@ -812,6 +831,7 @@ int nfs_open(struct dfs_fd *file)
         /* set private file */
         nfs->data = fp;
         file->fnode->size = fp->size;
+        file->fnode->type = FT_REGULAR;
     }
 
     return 0;

+ 20 - 0
components/dfs/filesystems/ramfs/dfs_ramfs.c

@@ -165,6 +165,12 @@ int dfs_ramfs_lseek(struct dfs_fd *file, off_t offset)
 
 int dfs_ramfs_close(struct dfs_fd *file)
 {
+    RT_ASSERT(file->fnode->ref_count > 0);
+    if (file->fnode->ref_count > 1)
+    {
+        return 0;
+    }
+
     file->fnode->data = NULL;
 
     return RT_EOK;
@@ -177,6 +183,18 @@ int dfs_ramfs_open(struct dfs_fd *file)
     struct ramfs_dirent *dirent;
     struct dfs_filesystem *fs;
 
+    RT_ASSERT(file->fnode->ref_count > 0);
+    if (file->fnode->ref_count > 1)
+    {
+        if (file->fnode->type == FT_DIRECTORY
+                && !(file->flags & O_DIRECTORY))
+        {
+            return -ENOENT;
+        }
+        file->pos = 0;
+        return 0;
+    }
+
     fs = file->fnode->fs;
 
     ramfs = (struct dfs_ramfs *)fs->data;
@@ -200,6 +218,7 @@ int dfs_ramfs_open(struct dfs_fd *file)
                 return -ENOENT;
             }
         }
+        file->fnode->type = FT_DIRECTORY;
     }
     else
     {
@@ -236,6 +255,7 @@ int dfs_ramfs_open(struct dfs_fd *file)
                 dirent->data = NULL;
                 dirent->size = 0;
                 dirent->fs = ramfs;
+                file->fnode->type = FT_DIRECTORY;
 
                 /* add to the root directory */
                 rt_list_insert_after(&(ramfs->root.list), &(dirent->list));

+ 17 - 1
components/dfs/filesystems/romfs/dfs_romfs.c

@@ -165,6 +165,7 @@ int dfs_romfs_lseek(struct dfs_fd *file, off_t offset)
 
 int dfs_romfs_close(struct dfs_fd *file)
 {
+    RT_ASSERT(file->fnode->ref_count > 0);
     if (file->fnode->ref_count > 1)
     {
         return RT_EOK;
@@ -180,10 +181,23 @@ int dfs_romfs_open(struct dfs_fd *file)
     struct romfs_dirent *root_dirent;
     struct dfs_filesystem *fs;
 
+    if (file->flags & (O_CREAT | O_WRONLY | O_APPEND | O_TRUNC | O_RDWR))
+    {
+        return -EINVAL;
+    }
+
+    RT_ASSERT(file->fnode->ref_count > 0);
     if (file->fnode->ref_count > 1)
     {
-        return RT_EOK;
+        if (file->fnode->type == FT_DIRECTORY
+                && !(file->flags & O_DIRECTORY))
+        {
+            return -ENOENT;
+        }
+        file->pos = 0;
+        return 0;
     }
+
     fs = file->fnode->fs;
     root_dirent = (struct romfs_dirent *)fs->data;
 
@@ -210,6 +224,7 @@ int dfs_romfs_open(struct dfs_fd *file)
         {
             return -ENOENT;
         }
+        file->fnode->type = FT_DIRECTORY;
     }
     else
     {
@@ -218,6 +233,7 @@ int dfs_romfs_open(struct dfs_fd *file)
         {
             return -ENOENT;
         }
+        file->fnode->type = FT_REGULAR;
     }
 
     file->fnode->data = dirent;

+ 19 - 0
components/dfs/filesystems/uffs/dfs_uffs.c

@@ -281,6 +281,18 @@ static int dfs_uffs_open(struct dfs_fd *file)
     int oflag, mode;
     char *file_path;
 
+    RT_ASSERT(file->fnode->ref_count > 0);
+    if (file->fnode->ref_count > 1)
+    {
+        if (file->fnode->type == FT_DIRECTORY
+                && !(file->flags & O_DIRECTORY))
+        {
+            return -ENOENT;
+        }
+        file->pos = 0;
+        return 0;
+    }
+
     oflag = file->flags;
     if (oflag & O_DIRECTORY)   /* operations about dir */
     {
@@ -313,6 +325,7 @@ static int dfs_uffs_open(struct dfs_fd *file)
         }
         /* save this pointer,will used by  dfs_uffs_getdents*/
         file->fnode->data = dir;
+        file->fnode->type = FT_DIRECTORY;
         rt_free(file_path);
         return RT_EOK;
     }
@@ -356,6 +369,12 @@ static int dfs_uffs_close(struct dfs_fd *file)
     int oflag;
     int fd;
 
+    RT_ASSERT(file->fnode->ref_count > 0);
+    if (file->fnode->ref_count > 1)
+    {
+        return 0;
+    }
+
     oflag = file->flags;
     if (oflag & O_DIRECTORY)
     {

+ 1 - 0
components/dfs/src/dfs_file.c

@@ -159,6 +159,7 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags)
         fd->pos   = 0;
         fd->fnode = fnode;
         dfs_fm_unlock();
+        rt_free(fullpath); /* release path */
     }
     else
     {

+ 3 - 5
components/lwp/lwp.h

@@ -80,13 +80,15 @@ struct rt_lwp
     struct dfs_fdtable fdt;
     char cmd[RT_NAME_MAX];
 
+    int sa_flags;
     lwp_sigset_t signal;
     lwp_sigset_t signal_mask;
     int signal_mask_bak;
     rt_uint32_t signal_in_process;
     lwp_sighandler_t signal_handler[_LWP_NSIG];
 
-    rt_list_t object_list;
+    struct lwp_avl_struct *object_root;
+    struct rt_mutex object_mutex;
     struct rt_user_context user_ctx;
 
     struct rt_wqueue wait_queue; /*for console */
@@ -116,10 +118,6 @@ void lwp_set_thread_area(void *p);
 void* rt_cpu_get_thread_idr(void);
 void rt_cpu_set_thread_idr(void *p);
 
-pid_t lwp_pid_get(void);
-void lwp_pid_put(pid_t pid);
-void lwp_pid_set_lwp(pid_t pid, struct rt_lwp *lwp);
-
 int lwp_tid_get(void);
 void lwp_tid_put(int tid);
 rt_thread_t lwp_tid_get_thread(int tid);

+ 13 - 4
components/lwp/lwp_futex.c

@@ -20,6 +20,7 @@ struct rt_futex
     int *uaddr;
     rt_list_t waiting_thread;
     struct lwp_avl_struct node;
+    struct rt_object *custom_obj;
 };
 
 static struct rt_mutex _futex_lock;
@@ -31,9 +32,10 @@ static int futex_system_init(void)
 }
 INIT_PREV_EXPORT(futex_system_init);
 
-void futex_destory(void *data)
+rt_err_t futex_destory(void *data)
 {
-    rt_base_t level = 0;
+    rt_err_t ret = -1;
+    rt_base_t level;
     struct rt_futex *futex = (struct rt_futex *)data;
 
     if (futex)
@@ -45,9 +47,9 @@ void futex_destory(void *data)
 
         /* release object */
         rt_free(futex);
+        ret = 0;
     }
-
-    return ;
+    return ret;
 }
 
 struct rt_futex* futex_create(int *uaddr, struct rt_lwp *lwp)
@@ -74,6 +76,7 @@ struct rt_futex* futex_create(int *uaddr, struct rt_lwp *lwp)
     futex->uaddr = uaddr;
     futex->node.avl_key = (avl_key_t)uaddr;
     futex->node.data = &lwp->address_search_head;
+    futex->custom_obj = obj;
     rt_list_init(&(futex->waiting_thread));
 
     /* insert into futex head */
@@ -212,6 +215,12 @@ int sys_futex(int *uaddr, int op, int val, const struct timespec *timeout,
             rt_set_errno(ENOMEM);
             return -RT_ENOMEM;
         }
+        if (lwp_user_object_add(lwp, futex->custom_obj) != 0)
+        {
+            rt_custom_object_destroy(futex->custom_obj);
+            rt_set_errno(ENOMEM);
+            return -RT_ENOMEM;
+        }
     }
 
     switch (op)

+ 270 - 100
components/lwp/lwp_pid.c

@@ -31,24 +31,31 @@
 #define DBG_LVL    DBG_INFO
 #include <rtdbg.h>
 
+#define PID_MAX 10000
+
 #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);
+PID_CT_ASSERT(pid_min_nr, RT_LWP_MAX_NR > 1);
+PID_CT_ASSERT(pid_max_nr, RT_LWP_MAX_NR < PID_MAX);
 
-static struct rt_lwp *lwp_pid_ary[RT_LWP_MAX_NR];
-static struct rt_lwp **lwp_pid_free_head = RT_NULL;
-static pid_t lwp_pid_ary_alloced = 1; /* 0 is reserved */
+static struct lwp_avl_struct lwp_pid_ary[RT_LWP_MAX_NR];
+static struct lwp_avl_struct *lwp_pid_free_head = RT_NULL;
+static int lwp_pid_ary_alloced = 0;
+static struct lwp_avl_struct *lwp_pid_root = RT_NULL;
+static pid_t current_pid = 0;
 
-pid_t lwp_pid_get(void)
+static pid_t lwp_pid_get(void)
 {
-    pid_t ret = 0;
-    rt_base_t level = rt_hw_interrupt_disable();
-    struct rt_lwp **p = lwp_pid_free_head;
+    rt_base_t level;
+    struct lwp_avl_struct *p;
+    pid_t pid = 0;
 
+    level = rt_hw_interrupt_disable();
+    p = lwp_pid_free_head;
     if (p)
     {
-        lwp_pid_free_head = (struct rt_lwp **)*p;
+        lwp_pid_free_head = (struct lwp_avl_struct *)p->avl_right;
     }
     else if (lwp_pid_ary_alloced < RT_LWP_MAX_NR)
     {
@@ -57,33 +64,65 @@ pid_t lwp_pid_get(void)
     }
     if (p)
     {
-        *p = RT_NULL;
-        ret = p - lwp_pid_ary;
+        int found_noused = 0;
+
+        RT_ASSERT(p->data == RT_NULL);
+        for (pid = current_pid + 1; pid < PID_MAX; pid++)
+        {
+            if (!lwp_avl_find(pid, lwp_pid_root))
+            {
+                found_noused = 1;
+                break;
+            }
+        }
+        if (!found_noused)
+        {
+            for (pid = 1; pid <= current_pid; pid++)
+            {
+                if (!lwp_avl_find(pid, lwp_pid_root))
+                {
+                    found_noused = 1;
+                    break;
+                }
+            }
+        }
+        p->avl_key = pid;
+        lwp_avl_insert(p, &lwp_pid_root);
+        current_pid = pid;
     }
     rt_hw_interrupt_enable(level);
-    return ret;
+    return pid;
 }
 
-void lwp_pid_put(pid_t pid)
+static void lwp_pid_put(pid_t pid)
 {
-    struct rt_lwp **p = RT_NULL;
-    rt_base_t level = rt_hw_interrupt_disable();
+    rt_base_t level;
+    struct lwp_avl_struct *p;
 
-    if (pid > 0 && pid < RT_LWP_MAX_NR)
+    level = rt_hw_interrupt_disable();
+    p  = lwp_avl_find(pid, lwp_pid_root);
+    if (p)
     {
-        p = lwp_pid_ary + pid;
-        *p = (struct rt_lwp *)lwp_pid_free_head;
+        p->data = RT_NULL;
+        lwp_avl_remove(p, &lwp_pid_root);
+        p->avl_right = lwp_pid_free_head;
         lwp_pid_free_head = p;
     }
     rt_hw_interrupt_enable(level);
 }
 
-void lwp_pid_set_lwp(pid_t pid, struct rt_lwp *lwp)
+static void lwp_pid_set_lwp(pid_t pid, struct rt_lwp *lwp)
 {
-    if (pid > 0 && pid < RT_LWP_MAX_NR)
+    rt_base_t level;
+    struct lwp_avl_struct *p;
+
+    level = rt_hw_interrupt_disable();
+    p  = lwp_avl_find(pid, lwp_pid_root);
+    if (p)
     {
-        lwp_pid_ary[pid] = lwp;
+        p->data = lwp;
     }
+    rt_hw_interrupt_enable(level);
 }
 
 int libc_stdio_get_console(void);
@@ -106,104 +145,208 @@ static void __exit_files(struct rt_lwp *lwp)
     }
 }
 
-struct rt_lwp* lwp_new(void)
+void lwp_user_object_lock_init(struct rt_lwp *lwp)
 {
-    pid_t pid;
-    rt_base_t level;
-    struct rt_lwp* lwp = RT_NULL;
+    rt_mutex_init(&lwp->object_mutex, "lwp_obj", RT_IPC_FLAG_PRIO);
+}
 
-    level = rt_hw_interrupt_disable();
+void lwp_user_object_lock_destroy(struct rt_lwp *lwp)
+{
+    rt_mutex_detach(&lwp->object_mutex);
+}
 
-    pid = lwp_pid_get();
-    if (pid == 0)
+void lwp_user_object_lock(struct rt_lwp *lwp)
+{
+    if (lwp)
     {
-        LOG_E("pid slot fulled!\n");
-        goto out;
+        rt_mutex_take(&lwp->object_mutex, RT_WAITING_FOREVER);
     }
-    lwp = (struct rt_lwp *)rt_malloc(sizeof(struct rt_lwp));
-    if (lwp == RT_NULL)
+    else
     {
-        LOG_E("no memory for lwp struct!\n");
-        goto out;
+        RT_ASSERT(0);
     }
-    rt_memset(lwp, 0, sizeof(*lwp));
-    rt_list_init(&lwp->wait_list);
-    lwp->pid = pid;
-    lwp_pid_set_lwp(pid, lwp);
-    rt_list_init(&lwp->t_grp);
-    rt_list_init(&lwp->object_list);
-    lwp->address_search_head = RT_NULL;
-    rt_wqueue_init(&lwp->wait_queue);
+}
 
-    lwp->ref = 1;
-out:
-    rt_hw_interrupt_enable(level);
-    return lwp;
+void lwp_user_object_unlock(struct rt_lwp *lwp)
+{
+    if (lwp)
+    {
+        rt_mutex_release(&lwp->object_mutex);
+    }
+    else
+    {
+        RT_ASSERT(0);
+    }
 }
 
-void lwp_user_obj_free(struct rt_lwp *lwp)
+int lwp_user_object_add(struct rt_lwp *lwp, rt_object_t object)
 {
-    rt_base_t level = 0;
-    struct rt_list_node *list = RT_NULL, *node = RT_NULL;
-    struct rt_object *object = RT_NULL;
+    int ret = -1;
 
-    list = &(lwp->object_list);
+    if (lwp && object)
+    {
+        lwp_user_object_lock(lwp);
+        if (!lwp_avl_find((avl_key_t)object, lwp->object_root))
+        {
+            struct lwp_avl_struct *node;
 
-    level = rt_hw_interrupt_disable();
-    while ((node = list->next) != list)
+            node = (struct lwp_avl_struct *)rt_malloc(sizeof(struct lwp_avl_struct));
+            if (node)
+            {
+                rt_base_t level;
+
+                level = rt_hw_interrupt_disable();
+                object->lwp_ref_count++;
+                rt_hw_interrupt_enable(level);
+                node->avl_key = (avl_key_t)object;
+                lwp_avl_insert(node, &lwp->object_root);
+                ret = 0;
+            }
+        }
+        lwp_user_object_unlock(lwp);
+    }
+    return ret;
+}
+
+static rt_err_t _object_node_delete(struct rt_lwp *lwp, struct lwp_avl_struct *node)
+{
+    rt_err_t ret = -1;
+    rt_object_t object;
+
+    if (!lwp || !node)
+    {
+        return ret;
+    }
+    object = (rt_object_t)node->avl_key;
+    object->lwp_ref_count--;
+    if (object->lwp_ref_count == 0)
     {
-        object = rt_list_entry(node, struct rt_object, lwp_obj_list);
         /* remove from kernel object list */
         switch (object->type)
         {
-        case RT_Object_Class_Thread:
-        {
-            RT_ASSERT(0);
-            break;
-        }
         case RT_Object_Class_Semaphore:
-            rt_sem_delete((rt_sem_t)object);
+            ret = rt_sem_delete((rt_sem_t)object);
             break;
         case RT_Object_Class_Mutex:
-            rt_mutex_delete((rt_mutex_t)object);
+            ret = rt_mutex_delete((rt_mutex_t)object);
             break;
         case RT_Object_Class_Event:
-            rt_event_delete((rt_event_t)object);
+            ret = rt_event_delete((rt_event_t)object);
             break;
         case RT_Object_Class_MailBox:
-            rt_mb_delete((rt_mailbox_t)object);
+            ret = rt_mb_delete((rt_mailbox_t)object);
             break;
         case RT_Object_Class_MessageQueue:
-            rt_mq_delete((rt_mq_t)object);
-            break;
-        case RT_Object_Class_Device:
-            rt_device_close((rt_device_t)object);
+            ret = rt_mq_delete((rt_mq_t)object);
             break;
         case RT_Object_Class_Timer:
-            rt_timer_delete((rt_timer_t)object);
-            break;
-        case RT_Object_Class_Channel:
-            /* remove from object list */
-            rt_list_remove(&object->list);
+            ret = rt_timer_delete((rt_timer_t)object);
             break;
         case RT_Object_Class_Custom:
-            rt_custom_object_destroy(object);
+            ret = rt_custom_object_destroy(object);
             break;
         default:
             LOG_E("input object type(%d) error", object->type);
-            /* remove from object list */
-            rt_list_remove(&object->list);
             break;
         }
     }
+    else
+    {
+        ret = 0;
+    }
+    lwp_avl_remove(node, &lwp->object_root);
+    rt_free(node);
+    return ret;
+}
+
+rt_err_t lwp_user_object_delete(struct rt_lwp *lwp, rt_object_t object)
+{
+    rt_err_t ret = -1;
+
+    if (lwp && object)
+    {
+        struct lwp_avl_struct *node;
+
+        lwp_user_object_lock(lwp);
+        node = lwp_avl_find((avl_key_t)object, lwp->object_root);
+        ret = _object_node_delete(lwp, node);
+        lwp_user_object_unlock(lwp);
+    }
+    return ret;
+}
+
+void lwp_user_object_clear(struct rt_lwp *lwp)
+{
+    struct lwp_avl_struct *node;
+
+    lwp_user_object_lock(lwp);
+    while ((node = lwp_map_find_first(lwp->object_root)) != RT_NULL)
+    {
+        _object_node_delete(lwp, node);
+    }
+    lwp_user_object_unlock(lwp);
+}
+
+static int _object_dup(struct lwp_avl_struct *node, void *arg)
+{
+    rt_object_t object;
+    struct rt_lwp *dst_lwp = (struct rt_lwp *)arg;
+
+    object = (rt_object_t)node->avl_key;
+    lwp_user_object_add(dst_lwp, object);
+    return 0;
+}
+
+void lwp_user_object_dup(struct rt_lwp *dst_lwp, struct rt_lwp *src_lwp)
+{
+    lwp_user_object_lock(src_lwp);
+    lwp_avl_traversal(src_lwp->object_root, _object_dup, dst_lwp);
+    lwp_user_object_unlock(src_lwp);
+}
+
+struct rt_lwp* lwp_new(void)
+{
+    pid_t pid;
+    rt_base_t level;
+    struct rt_lwp* lwp = RT_NULL;
+
+    level = rt_hw_interrupt_disable();
+
+    pid = lwp_pid_get();
+    if (pid == 0)
+    {
+        LOG_E("pid slot fulled!\n");
+        goto out;
+    }
+    lwp = (struct rt_lwp *)rt_malloc(sizeof(struct rt_lwp));
+    if (lwp == RT_NULL)
+    {
+        LOG_E("no memory for lwp struct!\n");
+        goto out;
+    }
+    rt_memset(lwp, 0, sizeof(*lwp));
+    rt_list_init(&lwp->wait_list);
+    lwp->pid = pid;
+    lwp_pid_set_lwp(pid, lwp);
+    rt_list_init(&lwp->t_grp);
+    lwp_user_object_lock_init(lwp);
+    lwp->address_search_head = RT_NULL;
+    rt_wqueue_init(&lwp->wait_queue);
+
+    lwp->ref = 1;
+out:
     rt_hw_interrupt_enable(level);
+    return lwp;
 }
 
 void lwp_free(struct rt_lwp* lwp)
 {
     rt_base_t level;
 
-    if (lwp == NULL) return ;
+    if (lwp == RT_NULL)
+    {
+        return;
+    }
 
     LOG_D("lwp free: %p\n", lwp);
 
@@ -222,11 +365,13 @@ void lwp_free(struct rt_lwp* lwp)
     {
         /* auto clean fds */
         __exit_files(lwp);
-        lwp_user_obj_free(lwp);
         rt_free(lwp->fdt.fds);
         lwp->fdt.fds = RT_NULL;
     }
 
+    lwp_user_object_clear(lwp);
+    lwp_user_object_lock_destroy(lwp);
+
     /* free data section */
     if (lwp->data_entry != RT_NULL)
     {
@@ -293,13 +438,22 @@ void lwp_free(struct rt_lwp* lwp)
                 thread->error = RT_EOK;
                 thread->msg_ret = (void*)(rt_size_t)lwp->lwp_ret;
                 rt_thread_resume(thread);
+                rt_hw_interrupt_enable(level);
+                return;
+            }
+            else
+            {
+                struct rt_lwp **it = &lwp->parent->first_child;
+
+                while (*it != lwp)
+                {
+                    it = &(*it)->sibling;
+                }
+                *it = lwp->sibling;
             }
         }
-        else
-        {
-            lwp_pid_put(lwp_to_pid(lwp));
-            rt_free(lwp);
-        }
+        lwp_pid_put(lwp_to_pid(lwp));
+        rt_free(lwp);
     }
 
     rt_hw_interrupt_enable(level);
@@ -343,11 +497,18 @@ void lwp_ref_dec(struct rt_lwp *lwp)
 
 struct rt_lwp* lwp_from_pid(pid_t pid)
 {
-    if ((pid <= 0) || (pid >= RT_LWP_MAX_NR))
+    rt_base_t level;
+    struct lwp_avl_struct *p;
+    struct rt_lwp *lwp = RT_NULL;
+
+    level = rt_hw_interrupt_disable();
+    p  = lwp_avl_find(pid, lwp_pid_root);
+    if (p)
     {
-        return NULL;
+        lwp = (struct rt_lwp *)p->data;
     }
-    return lwp_pid_ary[pid];
+    rt_hw_interrupt_enable(level);
+    return lwp;
 }
 
 pid_t lwp_to_pid(struct rt_lwp* lwp)
@@ -373,18 +534,21 @@ char* lwp_pid2name(int32_t pid)
     return process_name;
 }
 
-int32_t lwp_name2pid(const char *name)
+pid_t lwp_name2pid(const char *name)
 {
-    pid_t pid;
+    int idx;
+    pid_t pid = 0;
     rt_thread_t main_thread;
     char* process_name = RT_NULL;
+    rt_base_t level;
 
-    for (pid = 1; pid < RT_LWP_MAX_NR; pid++)
+    level = rt_hw_interrupt_disable();
+    for (idx = 0; idx < RT_LWP_MAX_NR; idx++)
     {
         /* 0 is reserved */
-        struct rt_lwp *lwp = lwp_pid_ary[pid];
+        struct rt_lwp *lwp = (struct rt_lwp *)lwp_pid_ary[idx].data;
 
-        if (lwp && (lwp < (struct rt_lwp *)&lwp_pid_ary[0] || lwp >= (struct rt_lwp *)&lwp_pid_ary[RT_LWP_MAX_NR]))
+        if (lwp)
         {
             process_name = strrchr(lwp->cmd, '/');
             process_name = process_name? process_name + 1: lwp->cmd;
@@ -393,12 +557,13 @@ int32_t lwp_name2pid(const char *name)
                 main_thread = rt_list_entry(lwp->t_grp.prev, struct rt_thread, sibling);
                 if (!(main_thread->stat & RT_THREAD_CLOSE))
                 {
-                    return pid;
+                    pid = lwp->pid;
                 }
             }
         }
     }
-    return -1;
+    rt_hw_interrupt_enable(level);
+    return pid;
 }
 
 int lwp_getpid(void)
@@ -477,7 +642,10 @@ quit:
 /* copy from components/finsh/cmd.c */
 static void object_split(int len)
 {
-    while (len--) rt_kprintf("-");
+    while (len--)
+    {
+        rt_kprintf("-");
+    }
 }
 
 static void print_thread_info(struct rt_thread* thread, int maxlen)
@@ -503,7 +671,7 @@ static void print_thread_info(struct rt_thread* thread, int maxlen)
 
 #if defined(ARCH_CPU_STACK_GROWS_UPWARD)
     ptr = (rt_uint8_t *)thread->stack_addr + thread->stack_size;
-    while (*ptr == '#')ptr --;
+    while (*ptr == '#')ptr--;
 
     rt_kprintf(" 0x%08x 0x%08x    %02d%%   0x%08x %03d\n",
             ((rt_uint32_t)thread->sp - (rt_uint32_t)thread->stack_addr),
@@ -513,7 +681,7 @@ static void print_thread_info(struct rt_thread* thread, int maxlen)
             thread->error);
 #else
     ptr = (rt_uint8_t *)thread->stack_addr;
-    while (*ptr == '#')ptr ++;
+    while (*ptr == '#')ptr++;
 
     rt_kprintf(" 0x%08x 0x%08x    %02d%%   0x%08x %03d\n",
             (thread->stack_size + (rt_uint32_t)(rt_size_t)thread->stack_addr - (rt_uint32_t)(rt_size_t)thread->sp),
@@ -559,7 +727,7 @@ long list_process(void)
 
             if (index > 0)
             {
-                for (index = 0; index <count; index ++)
+                for (index = 0; index <count; index++)
                 {
                     struct rt_thread th;
 
@@ -574,7 +742,6 @@ long list_process(void)
                     rt_memcpy(&th, thread, sizeof(struct rt_thread));
                     rt_hw_interrupt_enable(level);
 
-
                     if (th.lwp == RT_NULL)
                     {
                         rt_kprintf("     %-*.*s ", maxlen, RT_NAME_MAX, "kernel");
@@ -588,9 +755,9 @@ long list_process(void)
 
     for (index = 0; index < RT_LWP_MAX_NR; index++)
     {
-        struct rt_lwp *lwp = lwp_pid_ary[index];
+        struct rt_lwp *lwp = (struct rt_lwp *)lwp_pid_ary[index].data;
 
-        if (lwp && (lwp < (struct rt_lwp *)&lwp_pid_ary[0] || lwp >= (struct rt_lwp *)&lwp_pid_ary[RT_LWP_MAX_NR]))
+        if (lwp)
         {
             list = &lwp->t_grp;
             for (node = list->next; node != list; node = node->next)
@@ -784,7 +951,10 @@ void lwp_wait_subthread_exit(void)
     rt_thread_t main_thread;
 
     lwp = lwp_self();
-    if (!lwp) return;
+    if (!lwp)
+    {
+        return;
+    }
 
     thread = rt_thread_self();
     main_thread = rt_list_entry(lwp->t_grp.prev, struct rt_thread, sibling);

+ 10 - 1
components/lwp/lwp_pid.h

@@ -26,7 +26,7 @@ void lwp_ref_dec(struct rt_lwp *lwp);
 struct rt_lwp* lwp_from_pid(pid_t pid);
 pid_t lwp_to_pid(struct rt_lwp* lwp);
 
-int32_t lwp_name2pid(const char* name);
+pid_t lwp_name2pid(const char* name);
 char* lwp_pid2name(int32_t pid);
 
 int lwp_getpid(void);
@@ -34,6 +34,15 @@ int lwp_getpid(void);
 pid_t waitpid(pid_t pid, int *status, int options);
 long list_process(void);
 
+void lwp_user_object_lock_init(struct rt_lwp *lwp);
+void lwp_user_object_lock_destroy(struct rt_lwp *lwp);
+void lwp_user_object_lock(struct rt_lwp *lwp);
+void lwp_user_object_unlock(struct rt_lwp *lwp);
+int lwp_user_object_add(struct rt_lwp *lwp, rt_object_t object);
+rt_err_t lwp_user_object_delete(struct rt_lwp *lwp, rt_object_t object);
+void lwp_user_object_clear(struct rt_lwp *lwp);
+void lwp_user_object_dup(struct rt_lwp *dst_lwp, struct rt_lwp *src_lwp);
+
 #ifdef __cplusplus
 }
 #endif

+ 11 - 9
components/lwp/lwp_pmutex.c

@@ -31,8 +31,9 @@ static int pmutex_system_init(void)
 }
 INIT_PREV_EXPORT(pmutex_system_init);
 
-static void pmutex_destory(void *data)
+static rt_err_t pmutex_destory(void *data)
 {
+    rt_err_t ret = -1;
     rt_base_t level = 0;
     struct rt_pmutex *pmutex = (struct rt_pmutex *)data;
 
@@ -47,9 +48,9 @@ static void pmutex_destory(void *data)
 
         /* release object */
         rt_free(pmutex);
+        ret = 0;
     }
-
-    return ;
+    return ret;
 }
 
 static struct rt_pmutex* pmutex_create(void *umutex, struct rt_lwp *lwp)
@@ -79,7 +80,6 @@ static struct rt_pmutex* pmutex_create(void *umutex, struct rt_lwp *lwp)
         rt_free(pmutex);
         return RT_NULL;
     }
-
     pmutex->node.avl_key = (avl_key_t)umutex;
     pmutex->node.data = &lwp->address_search_head;
     pmutex->custom_obj = obj;
@@ -135,6 +135,12 @@ static int _pthread_mutex_init(void *umutex)
             rt_set_errno(ENOMEM);
             return -RT_ENOMEM;
         }
+        if (lwp_user_object_add(lwp, pmutex->custom_obj) != 0)
+        {
+            rt_custom_object_destroy(pmutex->custom_obj);
+            rt_set_errno(ENOMEM);
+            return -RT_ENOMEM;
+        }
     }
     else
     {
@@ -233,7 +239,6 @@ static int _pthread_mutex_destroy(void *umutex)
     struct rt_lwp *lwp = RT_NULL;
     struct rt_pmutex *pmutex = RT_NULL;
     rt_err_t lock_ret = 0;
-    rt_base_t level = 0;
 
     lock_ret = rt_mutex_take_interruptible(&_pmutex_lock, RT_WAITING_FOREVER);
     if (lock_ret != RT_EOK)
@@ -251,10 +256,7 @@ static int _pthread_mutex_destroy(void *umutex)
         return -RT_EINVAL;
     }
 
-    level = rt_hw_interrupt_disable();
-    rt_custom_object_destroy(pmutex->custom_obj);
-    rt_hw_interrupt_enable(level);
-
+    lwp_user_object_delete(lwp, pmutex->custom_obj);
     rt_mutex_release(&_pmutex_lock);
 
     return RT_EOK;

+ 29 - 19
components/lwp/lwp_signal.c

@@ -343,13 +343,14 @@ int lwp_sigaction(int sig, const struct lwp_sigaction *act,
     }
     if (oact)
     {
+        oact->sa_flags = lwp->sa_flags;
         oact->sa_mask = lwp->signal_mask;
-        oact->sa_flags = 0;
         oact->sa_restorer = RT_NULL;
         oact->__sa_handler._sa_handler = lwp->signal_handler[sig - 1];
     }
     if (act)
     {
+        lwp->sa_flags = act->sa_flags;
         newset = act->sa_mask;
         lwp_sigdelset(&newset, SIGKILL);
         lwp_sigdelset(&newset, SIGSTOP);
@@ -516,27 +517,31 @@ int lwp_kill(pid_t pid, int sig)
 {
     rt_base_t level;
     struct rt_lwp *lwp;
-    int ret = -RT_EINVAL;
+    int ret = -1;
     rt_thread_t thread;
 
-    if (sig == 0 || sig > _LWP_NSIG)
+    if (sig < 0 || sig >= _LWP_NSIG)
+    {
+        rt_set_errno(EINVAL);
         return ret;
+    }
     level = rt_hw_interrupt_disable();
     lwp = lwp_from_pid(pid);
     if (!lwp)
     {
+        rt_set_errno(ESRCH);
         goto out;
     }
-
-    /* check main thread */
-    thread = rt_list_entry(lwp->t_grp.prev, struct rt_thread, sibling);
-    if (lwp_sigismember(&lwp->signal_mask, sig)) /* if signal masked */
+    if (sig)
     {
-        goto out;
+        /* check main thread */
+        thread = rt_list_entry(lwp->t_grp.prev, struct rt_thread, sibling);
+        if (!lwp_sigismember(&lwp->signal_mask, sig)) /* if signal masked */
+        {
+            lwp_sigaddset(&lwp->signal, sig);
+            _do_signal_wakeup(thread, sig);
+        }
     }
-
-    lwp_sigaddset(&lwp->signal, sig);
-    _do_signal_wakeup(thread, sig);
     ret = 0;
 out:
     rt_hw_interrupt_enable(level);
@@ -548,22 +553,27 @@ int lwp_thread_kill(rt_thread_t thread, int sig)
     rt_base_t level;
     int ret = -RT_EINVAL;
 
-    if (!thread) return ret;
-
-    if (sig == 0 || sig > _LWP_NSIG)
+    if (!thread)
+    {
+        rt_set_errno(ESRCH);
         return ret;
+    }
+    if (sig < 0 || sig >= _LWP_NSIG)
+    {
+        rt_set_errno(EINVAL);
+        return ret;
+    }
     level = rt_hw_interrupt_disable();
     if (!thread->lwp)
     {
+        rt_set_errno(EPERM);
         goto out;
     }
-    if (lwp_sigismember(&thread->signal_mask, sig)) /* if signal masked */
+    if (!lwp_sigismember(&thread->signal_mask, sig)) /* if signal masked */
     {
-        goto out;
+        lwp_sigaddset(&thread->signal, sig);
+        _do_signal_wakeup(thread, sig);
     }
-
-    lwp_sigaddset(&thread->signal, sig);
-    _do_signal_wakeup(thread, sig);
     ret = 0;
 out:
     rt_hw_interrupt_enable(level);

+ 92 - 30
components/lwp/lwp_syscall.c

@@ -973,12 +973,18 @@ int sys_setpriority(int which, id_t who, int prio)
 
 rt_sem_t sys_sem_create(const char *name, rt_uint32_t value, rt_uint8_t flag)
 {
-    return rt_sem_create(name, value, flag);
+    rt_sem_t sem = rt_sem_create(name, value, flag);
+    if (lwp_user_object_add(lwp_self(), (rt_object_t)sem) != 0)
+    {
+        rt_sem_delete(sem);
+        sem = NULL;
+    }
+    return sem;
 }
 
 rt_err_t sys_sem_delete(rt_sem_t sem)
 {
-    return rt_sem_delete(sem);
+    return lwp_user_object_delete(lwp_self(), (rt_object_t)sem);
 }
 
 rt_err_t sys_sem_take(rt_sem_t sem, rt_int32_t time)
@@ -993,12 +999,18 @@ rt_err_t sys_sem_release(rt_sem_t sem)
 
 rt_mutex_t sys_mutex_create(const char *name, rt_uint8_t flag)
 {
-    return rt_mutex_create(name, flag);
+    rt_mutex_t mutex = rt_mutex_create(name, flag);
+    if (lwp_user_object_add(lwp_self(), (rt_object_t)mutex) != 0)
+    {
+        rt_mutex_delete(mutex);
+        mutex = NULL;
+    }
+    return mutex;
 }
 
 rt_err_t sys_mutex_delete(rt_mutex_t mutex)
 {
-    return rt_mutex_delete(mutex);
+    return lwp_user_object_delete(lwp_self(), (rt_object_t)mutex);
 }
 
 rt_err_t sys_mutex_take(rt_mutex_t mutex, rt_int32_t time)
@@ -1036,12 +1048,18 @@ int sys_munmap(void *addr, size_t length)
 
 rt_event_t sys_event_create(const char *name, rt_uint8_t flag)
 {
-    return rt_event_create(name, flag);
+    rt_event_t event = rt_event_create(name, flag);
+    if (lwp_user_object_add(lwp_self(), (rt_object_t)event) != 0)
+    {
+        rt_event_delete(event);
+        event = NULL;
+    }
+    return event;
 }
 
 rt_err_t sys_event_delete(rt_event_t event)
 {
-    return rt_event_delete(event);
+    return lwp_user_object_delete(lwp_self(), (rt_object_t)event);
 }
 
 rt_err_t sys_event_send(rt_event_t event, rt_uint32_t set)
@@ -1060,12 +1078,18 @@ rt_err_t sys_event_recv(rt_event_t   event,
 
 rt_mailbox_t sys_mb_create(const char *name, rt_size_t size, rt_uint8_t flag)
 {
-    return rt_mb_create(name, size, flag);
+    rt_mailbox_t mb = rt_mb_create(name, size, flag);
+    if (lwp_user_object_add(lwp_self(), (rt_object_t)mb) != 0)
+    {
+        rt_mb_delete(mb);
+        mb = NULL;
+    }
+    return mb;
 }
 
 rt_err_t sys_mb_delete(rt_mailbox_t mb)
 {
-    return rt_mb_delete(mb);
+    return lwp_user_object_delete(lwp_self(), (rt_object_t)mb);
 }
 
 rt_err_t sys_mb_send(rt_mailbox_t mb, rt_uint32_t value)
@@ -1090,12 +1114,18 @@ rt_mq_t sys_mq_create(const char *name,
                      rt_size_t   max_msgs,
                      rt_uint8_t  flag)
 {
-    return rt_mq_create(name, msg_size, max_msgs, flag);
+    rt_mq_t mq = rt_mq_create(name, msg_size, max_msgs, flag);
+    if (lwp_user_object_add(lwp_self(), (rt_object_t)mq) != 0)
+    {
+        rt_mq_delete(mq);
+        mq = NULL;
+    }
+    return mq;
 }
 
 rt_err_t sys_mq_delete(rt_mq_t mq)
 {
-    return rt_mq_delete(mq);
+    return lwp_user_object_delete(lwp_self(), (rt_object_t)mq);
 }
 
 rt_err_t sys_mq_send(rt_mq_t mq, void *buffer, rt_size_t size)
@@ -1127,12 +1157,18 @@ rt_timer_t sys_timer_create(const char *name,
         rt_tick_t   time,
         rt_uint8_t  flag)
 {
-    return rt_timer_create(name, timer_timeout_callback, (void *)data, time, flag);
+    rt_timer_t timer = rt_timer_create(name, timer_timeout_callback, (void *)data, time, flag);
+    if (lwp_user_object_add(lwp_self(), (rt_object_t)timer) != 0)
+    {
+        rt_timer_delete(timer);
+        timer = NULL;
+    }
+    return timer;
 }
 
 rt_err_t sys_timer_delete(rt_timer_t timer)
 {
-    return rt_timer_delete(timer);
+    return lwp_user_object_delete(lwp_self(), (rt_object_t)timer);
 }
 
 rt_err_t sys_timer_start(rt_timer_t timer)
@@ -1387,6 +1423,7 @@ static void lwp_struct_copy(struct rt_lwp *dst, struct rt_lwp *src)
     dst->args = src->args;
     rt_memcpy(dst->cmd, src->cmd, RT_NAME_MAX);
 
+    dst->sa_flags = src->sa_flags;
     dst->signal_mask = src->signal_mask;
     rt_memcpy(dst->signal_handler, src->signal_handler, sizeof dst->signal_handler);
 }
@@ -1538,6 +1575,9 @@ int _sys_fork(void)
     rt_memcpy(thread->stack_addr, self_thread->stack_addr, self_thread->stack_size);
     lwp_tid_set_thread(tid, thread);
 
+    /* duplicate user objects */
+    lwp_user_object_dup(lwp, self_lwp);
+
     level = rt_hw_interrupt_disable();
     user_stack = lwp_get_user_sp();
     rt_hw_interrupt_enable(level);
@@ -1923,6 +1963,7 @@ int sys_execve(const char *path, char *const argv[], char *const envp[])
     }
     rt_memset(new_lwp, 0, sizeof(struct rt_lwp));
     new_lwp->ref = 1;
+    lwp_user_object_lock_init(new_lwp);
     ret = arch_user_space_init(new_lwp);
     if (ret != 0)
     {
@@ -1958,6 +1999,9 @@ int sys_execve(const char *path, char *const argv[], char *const envp[])
         int last_backslash = 0;
         char *run_name = args_info.argv[0];
 
+        /* clear all user objects */
+        lwp_user_object_clear(lwp);
+
         /* find last \ or / */
         while (1)
         {
@@ -1993,6 +2037,9 @@ int sys_execve(const char *path, char *const argv[], char *const envp[])
 
         _swap_lwp_data(lwp, new_lwp, void *, args);
 
+        rt_memset(&thread->signal_mask, 0, sizeof(thread->signal_mask));
+        rt_memset(&thread->signal_mask_bak, 0, sizeof(thread->signal_mask_bak));
+        lwp->sa_flags = 0;
         rt_memset(&lwp->signal_mask, 0, sizeof(lwp->signal_mask));
         rt_memset(&lwp->signal_mask_bak, 0, sizeof(lwp->signal_mask_bak));
         rt_memset(lwp->signal_handler, 0, sizeof(lwp->signal_handler));
@@ -2620,8 +2667,15 @@ rt_err_t sys_thread_mdelay(rt_int32_t ms)
     return rt_thread_mdelay(ms);
 }
 
-int sys_sigaction(int sig, const struct sigaction *act,
-                     struct sigaction *oact, size_t sigsetsize)
+struct k_sigaction {
+    void (*handler)(int);
+    unsigned long flags;
+    void (*restorer)(void);
+    unsigned mask[2];
+};
+
+int sys_sigaction(int sig, const struct k_sigaction *act,
+                     struct k_sigaction *oact, size_t sigsetsize)
 {
     int ret = -RT_EINVAL;
     struct lwp_sigaction kact, *pkact = RT_NULL;
@@ -2643,7 +2697,7 @@ int sys_sigaction(int sig, const struct sigaction *act,
     }
     if (oact)
     {
-        if (!lwp_user_accessable((void *)oact, sigsetsize))
+        if (!lwp_user_accessable((void *)oact, sizeof(*oact)))
         {
             rt_set_errno(EFAULT);
             goto out;
@@ -2652,23 +2706,25 @@ int sys_sigaction(int sig, const struct sigaction *act,
     }
     if (act)
     {
-        if (!lwp_user_accessable((void *)act, sigsetsize))
+        if (!lwp_user_accessable((void *)act, sizeof(*act)))
         {
             rt_set_errno(EFAULT);
             goto out;
         }
-        kact.__sa_handler._sa_handler = act->sa_handler;
-        memcpy(&kact.sa_mask, &act->sa_mask, sigsetsize);
+        kact.sa_flags = act->flags;
+        kact.__sa_handler._sa_handler = act->handler;
+        memcpy(&kact.sa_mask, &act->mask, sigsetsize);
+        kact.sa_restorer = act->restorer;
         pkact = &kact;
     }
 
     ret = lwp_sigaction(sig, pkact, pkoact, sigsetsize);
-    if (ret == 0)
+    if (ret == 0 && oact)
     {
-        lwp_put_to_user(&oact->sa_handler, &pkoact->__sa_handler._sa_handler, sizeof(void (*)(int)));
-        lwp_put_to_user(&oact->sa_mask, &pkoact->sa_mask, sigsetsize);
-        lwp_put_to_user(&oact->sa_flags, &pkoact->sa_flags, sizeof(int));
-        lwp_put_to_user(&oact->sa_restorer, &pkoact->sa_restorer, sizeof(void (*)(void)));
+        lwp_put_to_user(&oact->handler, &pkoact->__sa_handler._sa_handler, sizeof(void (*)(int)));
+        lwp_put_to_user(&oact->mask, &pkoact->sa_mask, sigsetsize);
+        lwp_put_to_user(&oact->flags, &pkoact->sa_flags, sizeof(int));
+        lwp_put_to_user(&oact->restorer, &pkoact->sa_restorer, sizeof(void (*)(void)));
     }
 out:
     return ret;
@@ -2727,15 +2783,15 @@ int sys_sigprocmask(int how, const sigset_t *sigset, sigset_t *oset, size_t size
 
 int sys_tkill(int tid, int sig)
 {
-    rt_thread_t thread = RT_NULL;
+    rt_base_t level;
+    rt_thread_t thread;
+    int ret;
 
-    if (tid <= 0)
-    {
-        rt_set_errno(EINVAL);
-        return -RT_EINVAL;
-    }
+    level = rt_hw_interrupt_disable();
     thread = lwp_tid_get_thread(tid);
-    return lwp_thread_kill(thread, sig);
+    ret =  lwp_thread_kill(thread, sig);
+    rt_hw_interrupt_enable(level);
+    return ret;
 }
 
 int sys_thread_sigprocmask(int how, const lwp_sigset_t *sigset, lwp_sigset_t *oset, size_t size)
@@ -3208,6 +3264,11 @@ int sys_set_tid_address(int *tidptr)
     return thread->tid;
 }
 
+int sys_gettid(void)
+{
+    return rt_thread_self()->tid;
+}
+
 int sys_access(const char *filename, int mode)
 {
     int ret = 0;
@@ -3536,6 +3597,7 @@ const static void* func_table[] =
     (void *)sys_fork,
     (void *)sys_execve,
     (void *)sys_vfork,
+    (void *)sys_gettid,
 };
 
 const void *lwp_get_sys_api(rt_uint32_t number)

+ 64 - 26
components/lwp/lwp_tid.c

@@ -27,24 +27,31 @@
 #define DBG_LVL    DBG_INFO
 #include <rtdbg.h>
 
+#define TID_MAX 10000
+
 #define TID_CT_ASSERT(name, x) \
     struct assert_##name {char ary[2 * (x) - 1];}
 
-TID_CT_ASSERT(tid_max_nr, LWP_TID_MAX_NR > 1);
+TID_CT_ASSERT(tid_min_nr, LWP_TID_MAX_NR > 1);
+TID_CT_ASSERT(tid_max_nr, LWP_TID_MAX_NR < TID_MAX);
 
-static rt_thread_t lwp_tid_ary[LWP_TID_MAX_NR];
-static rt_thread_t *lwp_tid_free_head = RT_NULL;
-static int lwp_tid_ary_alloced = 1; /* 0 is reserved */
+static struct lwp_avl_struct lwp_tid_ary[LWP_TID_MAX_NR];
+static struct lwp_avl_struct *lwp_tid_free_head = RT_NULL;
+static int lwp_tid_ary_alloced = 0;
+static struct lwp_avl_struct *lwp_tid_root = RT_NULL;
+static int current_tid = 0;
 
 int lwp_tid_get(void)
 {
-    int ret = 0;
-    rt_base_t level = rt_hw_interrupt_disable();
-    rt_thread_t *p = lwp_tid_free_head;
+    rt_base_t level;
+    struct lwp_avl_struct *p;
+    int tid = 0;
 
+    level = rt_hw_interrupt_disable();
+    p = lwp_tid_free_head;
     if (p)
     {
-        lwp_tid_free_head = (rt_thread_t *)*p;
+        lwp_tid_free_head = (struct lwp_avl_struct *)p->avl_right;
     }
     else if (lwp_tid_ary_alloced < LWP_TID_MAX_NR)
     {
@@ -53,22 +60,48 @@ int lwp_tid_get(void)
     }
     if (p)
     {
-        *p = RT_NULL;
-        ret = p - lwp_tid_ary;
+        int found_noused = 0;
+
+        RT_ASSERT(p->data == RT_NULL);
+        for (tid = current_tid + 1; tid < TID_MAX; tid++)
+        {
+            if (!lwp_avl_find(tid, lwp_tid_root))
+            {
+                found_noused = 1;
+                break;
+            }
+        }
+        if (!found_noused)
+        {
+            for (tid = 1; tid <= current_tid; tid++)
+            {
+                if (!lwp_avl_find(tid, lwp_tid_root))
+                {
+                    found_noused = 1;
+                    break;
+                }
+            }
+        }
+        p->avl_key = tid;
+        lwp_avl_insert(p, &lwp_tid_root);
+        current_tid = tid;
     }
     rt_hw_interrupt_enable(level);
-    return ret;
+    return tid;
 }
 
 void lwp_tid_put(int tid)
 {
-    rt_thread_t *p = RT_NULL;
-    rt_base_t level = rt_hw_interrupt_disable();
+    rt_base_t level;
+    struct lwp_avl_struct *p;
 
-    if (tid > 0 && tid < LWP_TID_MAX_NR)
+    level = rt_hw_interrupt_disable();
+    p  = lwp_avl_find(tid, lwp_tid_root);
+    if (p)
     {
-        p = lwp_tid_ary + tid;
-        *p = (rt_thread_t)lwp_tid_free_head;
+        p->data = RT_NULL;
+        lwp_avl_remove(p, &lwp_tid_root);
+        p->avl_right = lwp_tid_free_head;
         lwp_tid_free_head = p;
     }
     rt_hw_interrupt_enable(level);
@@ -76,25 +109,30 @@ void lwp_tid_put(int tid)
 
 rt_thread_t lwp_tid_get_thread(int tid)
 {
+    rt_base_t level;
+    struct lwp_avl_struct *p;
     rt_thread_t thread = RT_NULL;
 
-    if (tid > 0 && tid < LWP_TID_MAX_NR)
+    level = rt_hw_interrupt_disable();
+    p  = lwp_avl_find(tid, lwp_tid_root);
+    if (p)
     {
-        thread = lwp_tid_ary[tid];
-        if ((thread >= (rt_thread_t)lwp_tid_ary)
-                && (thread < (rt_thread_t)(lwp_tid_ary + LWP_TID_MAX_NR)))
-        {
-            /* the tid is not used */
-            thread = RT_NULL;
-        }
+        thread = (rt_thread_t)p->data;
     }
+    rt_hw_interrupt_enable(level);
     return thread;
 }
 
 void lwp_tid_set_thread(int tid, rt_thread_t thread)
 {
-    if (tid > 0 && tid < LWP_TID_MAX_NR)
+    rt_base_t level;
+    struct lwp_avl_struct *p;
+
+    level = rt_hw_interrupt_disable();
+    p  = lwp_avl_find(tid, lwp_tid_root);
+    if (p)
     {
-        lwp_tid_ary[tid] = thread;
+        p->data = thread;
     }
+    rt_hw_interrupt_enable(level);
 }

+ 2 - 2
include/rtdef.h

@@ -365,7 +365,7 @@ struct rt_object
 #endif
 
 #ifdef RT_USING_LWP
-    rt_list_t  lwp_obj_list;                            /**< list node of kernel object for lwp */
+    int       lwp_ref_count;                            /**< ref count for lwp */
 #endif
 
     rt_list_t  list;                                    /**< list node of kernel object */
@@ -650,7 +650,7 @@ struct rt_thread
 #endif
 
 #ifdef RT_USING_LWP
-    rt_list_t  lwp_obj_list;                            /**< list node of kernel object for lwp */
+    int       lwp_ref_count;                            /**< ref count for lwp */
 #endif
 
     rt_list_t   list;                                   /**< the object list */

+ 2 - 2
include/rtthread.h

@@ -57,8 +57,8 @@ rt_object_t rt_object_find(const char *name, rt_uint8_t type);
 
 #ifdef RT_USING_HEAP
 /* custom object */
-rt_object_t rt_custom_object_create(const char *name, void *data, void (*data_destroy)(void *));
-void rt_custom_object_destroy(rt_object_t obj);
+rt_object_t rt_custom_object_create(const char *name, void *data, rt_err_t (*data_destroy)(void *));
+rt_err_t rt_custom_object_destroy(rt_object_t obj);
 #endif
 
 #ifdef RT_USING_HOOK

+ 13 - 31
src/object.c

@@ -29,7 +29,7 @@
 struct rt_custom_object
 {
     struct rt_object parent;
-    void (*destroy)(void *);
+    rt_err_t (*destroy)(void *);
     void *data;
 };
 
@@ -484,21 +484,6 @@ rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
         rt_list_insert_after(&(information->object_list), &(object->list));
     }
 
-#ifdef RT_USING_LWP
-    {
-        struct rt_lwp *lwp = lwp_self();
-        if (lwp && type != RT_Object_Class_Thread)
-        {
-            /* insert object into lwP object list */
-            rt_list_insert_after(&(lwp->object_list), &(object->lwp_obj_list));
-        }
-        else
-        {
-            rt_list_init(&(object->lwp_obj_list));
-        }
-    }
-#endif
-
     /* unlock interrupt */
     rt_hw_interrupt_enable(temp);
 
@@ -530,11 +515,6 @@ void rt_object_delete(rt_object_t object)
     /* remove from old list */
     rt_list_remove(&(object->list));
 
-#ifdef RT_USING_LWP
-    /* remove from the object list of lwP */
-    rt_list_remove(&(object->lwp_obj_list));
-#endif
-
     /* unlock interrupt */
     rt_hw_interrupt_enable(temp);
 
@@ -643,7 +623,7 @@ rt_object_t rt_object_find(const char *name, rt_uint8_t type)
  * @note this function shall not be invoked in interrupt status.
  */
 
-rt_object_t rt_custom_object_create(const char *name, void *data, void (*data_destroy)(void *))
+rt_object_t rt_custom_object_create(const char *name, void *data, rt_err_t (*data_destroy)(void *))
 {
     struct rt_custom_object *cobj = RT_NULL;
 
@@ -661,23 +641,25 @@ rt_object_t rt_custom_object_create(const char *name, void *data, void (*data_de
  * This function will destroy a custom object
  * container.
  *
- * @param name the specified name of object.
+ * @param obj the specified name of object.
  *
  * @note this function shall not be invoked in interrupt status.
  */
-void rt_custom_object_destroy(rt_object_t obj)
+rt_err_t rt_custom_object_destroy(rt_object_t obj)
 {
+    rt_err_t ret = -1;
+
     struct rt_custom_object *cobj = (struct rt_custom_object *)obj;
 
-    if (!obj || obj->type != RT_Object_Class_Custom)
+    if (obj && obj->type == RT_Object_Class_Custom)
     {
-        return;
-    }
-    if (cobj->destroy)
-    {
-        cobj->destroy(cobj->data);
+        if (cobj->destroy)
+        {
+            ret = cobj->destroy(cobj->data);
+        }
+        rt_object_delete(obj);
     }
-    rt_object_delete(obj);
+    return ret;
 }
 #endif