[lwP] fix _m_lock in posix mutex
This commit is contained in:
parent
c377c4bea3
commit
0ea687e0cb
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue