提交 d6bcd088 编写于 作者: W wjj

feat: 支持互斥锁的强壮性属性

支持互斥锁强壮性标志,添加加解锁函数对robust链表的处理

Change-Id: Idef4e0de44d7fac0a7ef293ebb570d7641623e27
上级 326e92cc
......@@ -83,7 +83,6 @@ int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict a, int *res
int pthread_mutexattr_getrobust(const pthread_mutexattr_t *restrict a, int *restrict robust)
{
unsupported_api(__FUNCTION__);
*robust = a->__attr / 4U % 2;
return 0;
}
......
......@@ -101,7 +101,6 @@ _Noreturn void __pthread_exit(void *result)
/* Process robust list in userspace to handle non-pshared mutexes
* and the detached thread case where the robust list head will
* be invalid when the kernel would process it. */
#if 0
__vm_lock();
volatile void *volatile *rp;
while ((rp=self->robust_list.head) && rp != &self->robust_list.head) {
......@@ -117,7 +116,6 @@ _Noreturn void __pthread_exit(void *result)
__wake(&m->_m_lock, 1, priv);
}
__vm_unlock();
#endif
__do_orphaned_stdio_locks();
__dl_thread_cleanup();
......
#include <pthread.h>
#include <unsupported_api.h>
int pthread_getconcurrency()
{
unsupported_api(__FUNCTION__);
return 0;
}
#include <unsupported_api.h>
#include "pthread_impl.h"
#include "atomic.h"
int pthread_mutex_consistent(pthread_mutex_t *m)
{
unsupported_api(__FUNCTION__);
int old = m->_m_lock;
int own = old & 0x3fffffff;
if (!(m->_m_type & 4) || !own || !(old & 0x40000000))
return EINVAL;
if (own != __pthread_self()->tid)
return EPERM;
a_and(&m->_m_lock, ~0x40000000);
return 0;
}
......@@ -71,7 +71,7 @@ int __pthread_mutex_timedlock(pthread_mutex_t *restrict m, const struct timespec
while ((r=__pthread_mutex_trylock(m)) == EBUSY) {
r = m->_m_lock;
int own = r & 0x3fffffff;
if (!r)
if (!own && (!r || (type&4)))
continue;
if ((type&3) == PTHREAD_MUTEX_ERRORCHECK
&& own == __pthread_self()->tid)
......
......@@ -17,14 +17,22 @@ int __pthread_mutex_trylock_owner(pthread_mutex_t *m)
}
}
if (own == 0x3fffffff) return ENOTRECOVERABLE;
tid |= 0x80000000;
if (own) return EBUSY;
if (own || (old && !(type & 4))) return EBUSY;
if (type & 128) {
if (!self->robust_list.off) {
self->robust_list.off = (char*)&m->_m_lock-(char *)&m->_m_next;
}
if (m->_m_waiters) tid |= 0x80000000;
self->robust_list.pending = &m->_m_next;
}
tid |= old & 0x40000000;
if (a_cas(&m->_m_lock, old, tid) != old) {
self->robust_list.pending = 0;
return EBUSY;
}
#if 0
volatile void *next = self->robust_list.head;
m->_m_next = next;
m->_m_prev = &self->robust_list.head;
......@@ -32,13 +40,18 @@ int __pthread_mutex_trylock_owner(pthread_mutex_t *m)
((char *)next - sizeof(void *)) = &m->_m_next;
self->robust_list.head = &m->_m_next;
self->robust_list.pending = 0;
#endif
if (old) {
m->_m_count = 0;
return EOWNERDEAD;
}
return 0;
}
int __pthread_mutex_trylock(pthread_mutex_t *m)
{
if ((m->_m_type&PTHREAD_MUTEX_TYPE_MASK) == PTHREAD_MUTEX_NORMAL)
if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL)
return a_cas(&m->_m_lock, 0, EBUSY) & EBUSY;
return __pthread_mutex_trylock_owner(m);
}
......
......@@ -5,7 +5,7 @@ int __pthread_mutex_unlock(pthread_mutex_t *m)
pthread_t self;
int waiters = m->_m_waiters;
int cont;
int type = m->_m_type & PTHREAD_MUTEX_TYPE_MASK;
int type = m->_m_type & 15;
int priv = (m->_m_type & 128) ^ 128;
int new = 0;
int old;
......@@ -18,11 +18,25 @@ int __pthread_mutex_unlock(pthread_mutex_t *m)
return EPERM;
if ((type&PTHREAD_MUTEX_TYPE_MASK) == PTHREAD_MUTEX_RECURSIVE && m->_m_count)
return m->_m_count--, 0;
if ((type&4) && (old&0x40000000))
new = 0x7fffffff;
if (!priv) {
self->robust_list.pending = &m->_m_next;
__vm_lock();
}
volatile void *prev = m->_m_prev;
volatile void *next = m->_m_next;
*(volatile void *volatile *)prev = next;
if (next != &self->robust_list.head) *(volatile void *volatile *)
((char *)next - sizeof(void *)) = prev;
}
cont = a_swap(&m->_m_lock, new);
if (type != PTHREAD_MUTEX_NORMAL && !priv) {
self->robust_list.pending = 0;
__vm_unlock();
}
if (waiters || cont<0)
__wake(&m->_m_lock, 1, priv);
return 0;
......
#include "pthread_impl.h"
#include <unsupported_api.h>
#include "syscall.h"
static pthread_once_t check_robust_once;
static int check_robust_result;
static void check_robust()
{
void *p;
size_t l;
check_robust_result = -__syscall(SYS_get_robust_list, 0, &p, &l);
}
int pthread_mutexattr_setrobust(pthread_mutexattr_t *a, int robust)
{
unsupported_api(__FUNCTION__);
if (robust > 1U) return EINVAL;
if (robust) {
pthread_once(&check_robust_once, check_robust);
if (check_robust_result) return check_robust_result;
a->__attr |= 4;
return 0;
}
......
#include <pthread.h>
#include <errno.h>
#include <unsupported_api.h>
int pthread_setconcurrency(int val)
{
unsupported_api(__FUNCTION__);
if (val < 0) return EINVAL;
if (val > 0) return EAGAIN;
return 0;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册