[lwP] fix _m_lock in posix mutex

This commit is contained in:
Bernard Xiong 2022-12-19 00:02:15 +08:00 committed by guo
parent c377c4bea3
commit 0ea687e0cb
1 changed files with 41 additions and 1 deletions

View File

@ -6,6 +6,7 @@
* Change Logs: * Change Logs:
* Date Author Notes * Date Author Notes
* 2021/01/02 bernard the first version * 2021/01/02 bernard the first version
* 2022/12/18 bernard fix the _m_lock to tid in user land.
*/ */
#include <rtthread.h> #include <rtthread.h>
@ -32,6 +33,25 @@ struct rt_pmutex
rt_uint8_t type; /* pmutex type */ rt_uint8_t type; /* pmutex type */
}; };
/*
* userspace mutex definitions in musl
*/
struct rt_umutex
{
union
{
int __i[6];
volatile int __vi[6];
volatile void *volatile __p[6];
} __u;
};
#define _m_type __u.__i[0]
#define _m_lock __u.__vi[1]
#define _m_waiters __u.__vi[2]
#define _m_prev __u.__p[3]
#define _m_next __u.__p[4]
#define _m_count __u.__i[5]
static struct rt_mutex _pmutex_lock; static struct rt_mutex _pmutex_lock;
static int pmutex_system_init(void) static int pmutex_system_init(void)
@ -218,10 +238,17 @@ static int _pthread_mutex_lock_timeout(void *umutex, struct timespec *timeout)
{ {
struct rt_lwp *lwp = RT_NULL; struct rt_lwp *lwp = RT_NULL;
struct rt_pmutex *pmutex = RT_NULL; struct rt_pmutex *pmutex = RT_NULL;
struct rt_umutex *umutex_p = (struct rt_umutex*)umutex;
rt_err_t lock_ret = 0; rt_err_t lock_ret = 0;
rt_int32_t time = RT_WAITING_FOREVER; rt_int32_t time = RT_WAITING_FOREVER;
register rt_base_t temp; register rt_base_t temp;
if (!lwp_user_accessable((void *)umutex, sizeof(struct rt_umutex)))
{
rt_set_errno(EINVAL);
return -EINVAL;
}
if (timeout) if (timeout)
{ {
if (!lwp_user_accessable((void *)timeout, sizeof(struct timespec))) if (!lwp_user_accessable((void *)timeout, sizeof(struct timespec)))
@ -257,6 +284,10 @@ static int _pthread_mutex_lock_timeout(void *umutex, struct timespec *timeout)
break; break;
case PMUTEX_RECURSIVE: case PMUTEX_RECURSIVE:
lock_ret = rt_mutex_take_interruptible(pmutex->lock.kmutex, time); lock_ret = rt_mutex_take_interruptible(pmutex->lock.kmutex, time);
if (lock_ret == RT_EOK)
{
umutex_p->_m_lock = rt_thread_self()->tid;
}
break; break;
case PMUTEX_ERRORCHECK: case PMUTEX_ERRORCHECK:
temp = rt_hw_interrupt_disable(); temp = rt_hw_interrupt_disable();
@ -267,6 +298,10 @@ static int _pthread_mutex_lock_timeout(void *umutex, struct timespec *timeout)
return -EDEADLK; return -EDEADLK;
} }
lock_ret = rt_mutex_take_interruptible(pmutex->lock.kmutex, time); lock_ret = rt_mutex_take_interruptible(pmutex->lock.kmutex, time);
if (lock_ret == RT_EOK)
{
umutex_p->_m_lock = rt_thread_self()->tid;
}
rt_hw_interrupt_enable(temp); rt_hw_interrupt_enable(temp);
break; break;
default: /* unknown type */ default: /* unknown type */
@ -299,9 +334,10 @@ static int _pthread_mutex_lock_timeout(void *umutex, struct timespec *timeout)
static int _pthread_mutex_unlock(void *umutex) static int _pthread_mutex_unlock(void *umutex)
{ {
rt_err_t lock_ret = 0;
struct rt_lwp *lwp = RT_NULL; struct rt_lwp *lwp = RT_NULL;
struct rt_pmutex *pmutex = RT_NULL; struct rt_pmutex *pmutex = RT_NULL;
rt_err_t lock_ret = 0; struct rt_umutex *umutex_p = (struct rt_umutex*)umutex;
lock_ret = rt_mutex_take_interruptible(&_pmutex_lock, RT_WAITING_FOREVER); lock_ret = rt_mutex_take_interruptible(&_pmutex_lock, RT_WAITING_FOREVER);
if (lock_ret != RT_EOK) if (lock_ret != RT_EOK)
@ -337,6 +373,10 @@ static int _pthread_mutex_unlock(void *umutex)
case PMUTEX_RECURSIVE: case PMUTEX_RECURSIVE:
case PMUTEX_ERRORCHECK: case PMUTEX_ERRORCHECK:
lock_ret = rt_mutex_release(pmutex->lock.kmutex); lock_ret = rt_mutex_release(pmutex->lock.kmutex);
if ((lock_ret == RT_EOK) && pmutex->lock.kmutex->owner == NULL)
{
umutex_p->_m_lock = 0;
}
break; break;
default: /* unknown type */ default: /* unknown type */
return -EINVAL; return -EINVAL;