From 04fa330012f9f46b664a27974bbcc9f84be87269 Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Mon, 25 Jan 2021 11:22:06 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E4=BF=AE=E6=AD=A3lwp=20free=20object?= =?UTF-8?q?=E6=97=B6=E5=A6=82=E6=9E=9C=E5=BD=93=E5=89=8D=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E7=9A=84=E5=88=A0=E9=99=A4=E6=B6=89=E5=8F=8A=E5=88=B0=E5=85=B6?= =?UTF-8?q?=E4=BB=96=E5=AF=B9=E8=B1=A1=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/lwp/lwp_pid.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/components/lwp/lwp_pid.c b/components/lwp/lwp_pid.c index dff3d3f590..35e93d94d9 100644 --- a/components/lwp/lwp_pid.c +++ b/components/lwp/lwp_pid.c @@ -126,14 +126,12 @@ static void lwp_user_obj_free(struct rt_lwp *lwp) struct rt_list_node *list = RT_NULL, *node = RT_NULL; struct rt_object *object = RT_NULL; - list = &(lwp->object_list), node = list->next; + list = &(lwp->object_list); level = rt_hw_interrupt_disable(); - while (list != node) + while ((node = list->next) != list) { object = rt_list_entry(node, struct rt_object, lwp_obj_list); - node = node->next; - /* remove from kernel object list */ switch (object->type) { @@ -168,12 +166,16 @@ static void lwp_user_obj_free(struct rt_lwp *lwp) rt_timer_delete((rt_timer_t)object); break; case RT_Object_Class_Channel: + /* remove from object list */ + rt_list_remove(&object->list); break; case RT_Object_Class_Custom: 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; } } -- Gitee From fa75b66356229b738e0ec91e571fdcb6b13265cd Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Mon, 25 Jan 2021 11:38:10 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BB=A5=E7=9B=B4=E6=8E=A5=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E8=B0=83=E7=94=A8=E6=96=B9=E5=BC=8F=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=AF=B9=E7=94=A8=E6=88=B7=E6=80=81posix=20mutex=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/lwp/lwp.h | 1 + components/lwp/lwp_pid.c | 1 + components/lwp/lwp_pmutex.c | 261 +++++++++++++++++++++++++++++++++++ components/lwp/lwp_syscall.c | 9 ++ 4 files changed, 272 insertions(+) create mode 100644 components/lwp/lwp_pmutex.c diff --git a/components/lwp/lwp.h b/components/lwp/lwp.h index 5901ee74dd..a07c22fc02 100644 --- a/components/lwp/lwp.h +++ b/components/lwp/lwp.h @@ -93,6 +93,7 @@ struct rt_lwp struct rt_wqueue wait_queue; /*for console */ struct lwp_avl_struct *futex_head; + struct lwp_avl_struct *pmutex_head; #ifdef RT_USING_GDBSERVER int debug; uint32_t bak_first_ins; diff --git a/components/lwp/lwp_pid.c b/components/lwp/lwp_pid.c index 35e93d94d9..febc100c68 100644 --- a/components/lwp/lwp_pid.c +++ b/components/lwp/lwp_pid.c @@ -112,6 +112,7 @@ struct rt_lwp* lwp_new(void) rt_list_init(&lwp->t_grp); rt_list_init(&lwp->object_list); lwp->futex_head = RT_NULL; + lwp->pmutex_head = RT_NULL; rt_wqueue_init(&lwp->wait_queue); lwp->ref = 1; diff --git a/components/lwp/lwp_pmutex.c b/components/lwp/lwp_pmutex.c new file mode 100644 index 0000000000..684c5064ad --- /dev/null +++ b/components/lwp/lwp_pmutex.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021/01/02 bernard the first version + */ + +#include +#include +#ifdef RT_USING_USERSPACE +#include +#endif +#include "clock_time.h" + +struct rt_pmutex +{ + rt_mutex_t kmutex; + struct lwp_avl_struct node; + struct rt_object *custom_obj; +}; + +static struct rt_mutex _pmutex_lock; + +static int pmutex_system_init(void) +{ + rt_mutex_init(&_pmutex_lock, "pmtxLock", RT_IPC_FLAG_FIFO); + return 0; +} +INIT_PREV_EXPORT(pmutex_system_init); + +static void pmutex_destory(void *data) +{ + rt_base_t level = 0; + struct rt_pmutex *pmutex = (struct rt_pmutex *)data; + + if (pmutex) + { + level = rt_hw_interrupt_disable(); + /* remove pmutex from pmutext avl */ + lwp_avl_remove(&pmutex->node, (struct lwp_avl_struct **)pmutex->node.data); + rt_hw_interrupt_enable(level); + + rt_mutex_delete(pmutex->kmutex); + + /* release object */ + rt_free(pmutex); + } + + return ; +} + +static struct rt_pmutex* pmutex_create(void *umutex, struct rt_lwp *lwp) +{ + struct rt_pmutex *pmutex = RT_NULL; + struct rt_object *obj = RT_NULL; + + if (!lwp) + { + return RT_NULL; + } + pmutex = (struct rt_pmutex *)rt_malloc(sizeof(struct rt_pmutex)); + if (!pmutex) + { + return RT_NULL; + } + pmutex->kmutex = rt_mutex_create("pmutex", RT_IPC_FLAG_PRIO); + if (!pmutex->kmutex) + { + rt_free(pmutex); + return RT_NULL; + } + obj = rt_custom_object_create("pmutex", (void *)pmutex, pmutex_destory); + if (!obj) + { + rt_mutex_delete(pmutex->kmutex); + rt_free(pmutex); + return RT_NULL; + } + + pmutex->node.avl_key = (avl_key_t)umutex; + pmutex->node.data = &lwp->pmutex_head; + pmutex->custom_obj = obj; + + /* insert into pmutex head */ + lwp_avl_insert(&pmutex->node, &lwp->pmutex_head); + return pmutex; +} + +static struct rt_pmutex* pmutex_get(void *umutex, struct rt_lwp *lwp) +{ + struct rt_pmutex *pmutex = RT_NULL; + struct lwp_avl_struct *node = RT_NULL; + + node = lwp_avl_find((avl_key_t)umutex, lwp->pmutex_head); + if (!node) + { + return RT_NULL; + } + pmutex = rt_container_of(node, struct rt_pmutex, node); + return pmutex; +} + +int sys_pthread_mutex_init(void *umutex) +{ + struct rt_lwp *lwp = RT_NULL; + struct rt_pmutex *pmutex = RT_NULL; + rt_err_t lock_ret = 0; + + /* umutex union is 6 x (void *) */ + if (!lwp_user_accessable(umutex, sizeof(void *) * 6)) + { + rt_set_errno(EINVAL); + return -RT_EINVAL; + } + + lock_ret = rt_mutex_take_interruptible(&_pmutex_lock, RT_WAITING_FOREVER); + if (lock_ret != RT_EOK) + { + rt_set_errno(EAGAIN); + return -RT_EINTR; + } + + lwp = lwp_self(); + pmutex = pmutex_get(umutex, lwp); + if (pmutex == RT_NULL) + { + /* create a pmutex according to this umutex */ + pmutex = pmutex_create(umutex, lwp); + if (pmutex == RT_NULL) + { + rt_mutex_release(&_pmutex_lock); + rt_set_errno(ENOMEM); + return -RT_ENOMEM; + } + } + else + { + rt_base_t level = rt_hw_interrupt_disable(); + + pmutex->kmutex->value = 1; + pmutex->kmutex->owner = RT_NULL; + pmutex->kmutex->original_priority = 0xFF; + pmutex->kmutex->hold = 0; + + rt_hw_interrupt_enable(level); + } + + rt_mutex_release(&_pmutex_lock); + + return 0; +} + +int sys_pthread_mutex_lock_timeout(void *umutex, struct timespec *timeout) +{ + struct rt_lwp *lwp = RT_NULL; + struct rt_pmutex *pmutex = RT_NULL; + rt_err_t lock_ret = 0; + rt_int32_t time = RT_WAITING_FOREVER; + + if (timeout) + { + if (!lwp_user_accessable((void *)timeout, sizeof(struct timespec))) + { + rt_set_errno(EINVAL); + return -RT_EINVAL; + } + time = clock_time_to_tick(timeout); + } + + lock_ret = rt_mutex_take_interruptible(&_pmutex_lock, RT_WAITING_FOREVER); + if (lock_ret != RT_EOK) + { + rt_set_errno(EAGAIN); + return -RT_EINTR; + } + + lwp = lwp_self(); + pmutex = pmutex_get(umutex, lwp); + if (pmutex == RT_NULL) + { + rt_mutex_release(&_pmutex_lock); + rt_set_errno(EINVAL); + return -RT_EINVAL; + } + + rt_mutex_release(&_pmutex_lock); + + lock_ret = rt_mutex_take_interruptible(pmutex->kmutex, time); + if (lock_ret != RT_EOK) + { + rt_set_errno(EAGAIN); + } + return lock_ret; +} + +int sys_pthread_mutex_unlock(void *umutex) +{ + struct rt_lwp *lwp = RT_NULL; + struct rt_pmutex *pmutex = RT_NULL; + rt_err_t lock_ret = 0; + + lock_ret = rt_mutex_take_interruptible(&_pmutex_lock, RT_WAITING_FOREVER); + if (lock_ret != RT_EOK) + { + rt_set_errno(EAGAIN); + return -RT_EINTR; + } + + lwp = lwp_self(); + pmutex = pmutex_get(umutex, lwp); + if (pmutex == RT_NULL) + { + rt_mutex_release(&_pmutex_lock); + rt_set_errno(EINVAL); + return -RT_EINVAL; + } + + rt_mutex_release(&_pmutex_lock); + + lock_ret = rt_mutex_release(pmutex->kmutex); + if (lock_ret != RT_EOK) + { + rt_set_errno(EPERM); + } + return lock_ret; +} + +int sys_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) + { + rt_set_errno(EAGAIN); + return -RT_EINTR; + } + + lwp = lwp_self(); + pmutex = pmutex_get(umutex, lwp); + if (pmutex == RT_NULL) + { + rt_mutex_release(&_pmutex_lock); + rt_set_errno(EINVAL); + return -RT_EINVAL; + } + + level = rt_hw_interrupt_disable(); + rt_custom_object_destroy(pmutex->custom_obj); + rt_hw_interrupt_enable(level); + + rt_mutex_release(&_pmutex_lock); + + return RT_EOK; +} diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c index bac6291fca..cfa15f61eb 100644 --- a/components/lwp/lwp_syscall.c +++ b/components/lwp/lwp_syscall.c @@ -2519,6 +2519,11 @@ int sys_clock_getres(clockid_t clk, struct timespec *ts) int sys_futex(int *uaddr, int op, int val, void *timeout, void *uaddr2, int val3); +int sys_pthread_mutex_init(void *umutex); +int sys_pthread_mutex_lock_timeout(void *umutex, struct timespec *timeout); +int sys_pthread_mutex_unlock(void *umutex); +int sys_pthread_mutex_destroy(void *umutex); + const static void* func_table[] = { (void*)sys_exit, /* 01 */ @@ -2668,6 +2673,10 @@ const static void* func_table[] = (void *)sys_clock_getres, (void *)sys_clone, /* 130 */ (void *)sys_futex, + (void *)sys_pthread_mutex_init, + (void *)sys_pthread_mutex_lock_timeout, + (void *)sys_pthread_mutex_unlock, + (void *)sys_pthread_mutex_destroy, /* 135 */ }; const void *lwp_get_sys_api(rt_uint32_t number) -- Gitee From d72297af78bd1f6cf4a67a351e275908559aff29 Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Tue, 26 Jan 2021 08:55:02 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E5=90=88=E5=B9=B6futex=EF=BC=8Cpmutex?= =?UTF-8?q?=E6=AD=A4=E7=B1=BB=E5=9C=B0=E5=9D=80=E7=9B=B8=E5=85=B3=E7=9A=84?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=80=81=E5=AF=B9=E8=B1=A1=E7=9A=84lwp?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E6=A0=91=E5=A4=B4=E6=8C=87=E9=92=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/lwp/lwp.h | 3 +-- components/lwp/lwp_futex.c | 6 +++--- components/lwp/lwp_pid.c | 3 +-- components/lwp/lwp_pmutex.c | 6 +++--- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/components/lwp/lwp.h b/components/lwp/lwp.h index a07c22fc02..3934d2ec61 100644 --- a/components/lwp/lwp.h +++ b/components/lwp/lwp.h @@ -92,8 +92,7 @@ struct rt_lwp struct rt_wqueue wait_queue; /*for console */ - struct lwp_avl_struct *futex_head; - struct lwp_avl_struct *pmutex_head; + struct lwp_avl_struct *address_search_head; /* for addressed object fast rearch */ #ifdef RT_USING_GDBSERVER int debug; uint32_t bak_first_ins; diff --git a/components/lwp/lwp_futex.c b/components/lwp/lwp_futex.c index f4704f4209..0d5afa859a 100644 --- a/components/lwp/lwp_futex.c +++ b/components/lwp/lwp_futex.c @@ -73,11 +73,11 @@ 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->futex_head; + futex->node.data = &lwp->address_search_head; rt_list_init(&(futex->waiting_thread)); /* insert into futex head */ - lwp_avl_insert(&futex->node, &lwp->futex_head); + lwp_avl_insert(&futex->node, &lwp->address_search_head); return futex; } @@ -86,7 +86,7 @@ static struct rt_futex* futex_get(void *uaddr, struct rt_lwp *lwp) struct rt_futex *futex = RT_NULL; struct lwp_avl_struct *node = RT_NULL; - node = lwp_avl_find((avl_key_t)uaddr, lwp->futex_head); + node = lwp_avl_find((avl_key_t)uaddr, lwp->address_search_head); if (!node) { return RT_NULL; diff --git a/components/lwp/lwp_pid.c b/components/lwp/lwp_pid.c index febc100c68..4221493624 100644 --- a/components/lwp/lwp_pid.c +++ b/components/lwp/lwp_pid.c @@ -111,8 +111,7 @@ struct rt_lwp* lwp_new(void) pid_struct.pidmap[i] = lwp; rt_list_init(&lwp->t_grp); rt_list_init(&lwp->object_list); - lwp->futex_head = RT_NULL; - lwp->pmutex_head = RT_NULL; + lwp->address_search_head = RT_NULL; rt_wqueue_init(&lwp->wait_queue); lwp->ref = 1; diff --git a/components/lwp/lwp_pmutex.c b/components/lwp/lwp_pmutex.c index 684c5064ad..621f4329b8 100644 --- a/components/lwp/lwp_pmutex.c +++ b/components/lwp/lwp_pmutex.c @@ -81,11 +81,11 @@ static struct rt_pmutex* pmutex_create(void *umutex, struct rt_lwp *lwp) } pmutex->node.avl_key = (avl_key_t)umutex; - pmutex->node.data = &lwp->pmutex_head; + pmutex->node.data = &lwp->address_search_head; pmutex->custom_obj = obj; /* insert into pmutex head */ - lwp_avl_insert(&pmutex->node, &lwp->pmutex_head); + lwp_avl_insert(&pmutex->node, &lwp->address_search_head); return pmutex; } @@ -94,7 +94,7 @@ static struct rt_pmutex* pmutex_get(void *umutex, struct rt_lwp *lwp) struct rt_pmutex *pmutex = RT_NULL; struct lwp_avl_struct *node = RT_NULL; - node = lwp_avl_find((avl_key_t)umutex, lwp->pmutex_head); + node = lwp_avl_find((avl_key_t)umutex, lwp->address_search_head); if (!node) { return RT_NULL; -- Gitee From 8cebc313106211e7eac5e01bc6f8bbbe1d4fe420 Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Tue, 26 Jan 2021 10:07:45 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E5=90=88=E5=B9=B6phread=20mutex=20?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E8=B0=83=E7=94=A8=E4=B8=BA=E5=8D=95=E4=B8=AA?= =?UTF-8?q?=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/lwp/lwp.h | 6 ++++++ components/lwp/lwp_pmutex.c | 33 +++++++++++++++++++++++++++++---- components/lwp/lwp_syscall.c | 11 ++--------- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/components/lwp/lwp.h b/components/lwp/lwp.h index 3934d2ec61..fcecc76e69 100644 --- a/components/lwp/lwp.h +++ b/components/lwp/lwp.h @@ -174,6 +174,12 @@ struct __pthread { #define FUTEX_WAIT 0 #define FUTEX_WAKE 1 +/* for pmutex op */ +#define PMUTEX_INIT 0 +#define PMUTEX_LOCK 1 +#define PMUTEX_UNLOCK 2 +#define PMUTEX_DESTROY 3 + #ifdef __cplusplus } #endif diff --git a/components/lwp/lwp_pmutex.c b/components/lwp/lwp_pmutex.c index 621f4329b8..f60ae0046a 100644 --- a/components/lwp/lwp_pmutex.c +++ b/components/lwp/lwp_pmutex.c @@ -103,7 +103,7 @@ static struct rt_pmutex* pmutex_get(void *umutex, struct rt_lwp *lwp) return pmutex; } -int sys_pthread_mutex_init(void *umutex) +static int _pthread_mutex_init(void *umutex) { struct rt_lwp *lwp = RT_NULL; struct rt_pmutex *pmutex = RT_NULL; @@ -153,7 +153,7 @@ int sys_pthread_mutex_init(void *umutex) return 0; } -int sys_pthread_mutex_lock_timeout(void *umutex, struct timespec *timeout) +static int _pthread_mutex_lock_timeout(void *umutex, struct timespec *timeout) { struct rt_lwp *lwp = RT_NULL; struct rt_pmutex *pmutex = RT_NULL; @@ -196,7 +196,7 @@ int sys_pthread_mutex_lock_timeout(void *umutex, struct timespec *timeout) return lock_ret; } -int sys_pthread_mutex_unlock(void *umutex) +static int _pthread_mutex_unlock(void *umutex) { struct rt_lwp *lwp = RT_NULL; struct rt_pmutex *pmutex = RT_NULL; @@ -228,7 +228,7 @@ int sys_pthread_mutex_unlock(void *umutex) return lock_ret; } -int sys_pthread_mutex_destroy(void *umutex) +static int _pthread_mutex_destroy(void *umutex) { struct rt_lwp *lwp = RT_NULL; struct rt_pmutex *pmutex = RT_NULL; @@ -259,3 +259,28 @@ int sys_pthread_mutex_destroy(void *umutex) return RT_EOK; } + +int sys_pmutex(void *umutex, int op, void *arg) +{ + int ret = -RT_EINVAL; + + switch (op) + { + case PMUTEX_INIT: + ret = _pthread_mutex_init(umutex); + break; + case PMUTEX_LOCK: + ret = _pthread_mutex_lock_timeout(umutex, (struct timespec*)arg); + break; + case PMUTEX_UNLOCK: + ret = _pthread_mutex_unlock(umutex); + break; + case PMUTEX_DESTROY: + ret = _pthread_mutex_destroy(umutex); + break; + default: + rt_set_errno(EINVAL); + break; + } + return ret; +} diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c index cfa15f61eb..781dd3176e 100644 --- a/components/lwp/lwp_syscall.c +++ b/components/lwp/lwp_syscall.c @@ -2518,11 +2518,7 @@ int sys_clock_getres(clockid_t clk, struct timespec *ts) } int sys_futex(int *uaddr, int op, int val, void *timeout, void *uaddr2, int val3); - -int sys_pthread_mutex_init(void *umutex); -int sys_pthread_mutex_lock_timeout(void *umutex, struct timespec *timeout); -int sys_pthread_mutex_unlock(void *umutex); -int sys_pthread_mutex_destroy(void *umutex); +int sys_pmutex(void *umutex, int op, void *arg); const static void* func_table[] = { @@ -2673,10 +2669,7 @@ const static void* func_table[] = (void *)sys_clock_getres, (void *)sys_clone, /* 130 */ (void *)sys_futex, - (void *)sys_pthread_mutex_init, - (void *)sys_pthread_mutex_lock_timeout, - (void *)sys_pthread_mutex_unlock, - (void *)sys_pthread_mutex_destroy, /* 135 */ + (void *)sys_pmutex, }; const void *lwp_get_sys_api(rt_uint32_t number) -- Gitee