提交 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 ...@@ -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) int pthread_mutexattr_getrobust(const pthread_mutexattr_t *restrict a, int *restrict robust)
{ {
unsupported_api(__FUNCTION__);
*robust = a->__attr / 4U % 2; *robust = a->__attr / 4U % 2;
return 0; return 0;
} }
......
...@@ -101,7 +101,6 @@ _Noreturn void __pthread_exit(void *result) ...@@ -101,7 +101,6 @@ _Noreturn void __pthread_exit(void *result)
/* Process robust list in userspace to handle non-pshared mutexes /* Process robust list in userspace to handle non-pshared mutexes
* and the detached thread case where the robust list head will * and the detached thread case where the robust list head will
* be invalid when the kernel would process it. */ * be invalid when the kernel would process it. */
#if 0
__vm_lock(); __vm_lock();
volatile void *volatile *rp; volatile void *volatile *rp;
while ((rp=self->robust_list.head) && rp != &self->robust_list.head) { while ((rp=self->robust_list.head) && rp != &self->robust_list.head) {
...@@ -117,7 +116,6 @@ _Noreturn void __pthread_exit(void *result) ...@@ -117,7 +116,6 @@ _Noreturn void __pthread_exit(void *result)
__wake(&m->_m_lock, 1, priv); __wake(&m->_m_lock, 1, priv);
} }
__vm_unlock(); __vm_unlock();
#endif
__do_orphaned_stdio_locks(); __do_orphaned_stdio_locks();
__dl_thread_cleanup(); __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 ...@@ -71,7 +71,7 @@ int __pthread_mutex_timedlock(pthread_mutex_t *restrict m, const struct timespec
while ((r=__pthread_mutex_trylock(m)) == EBUSY) { while ((r=__pthread_mutex_trylock(m)) == EBUSY) {
r = m->_m_lock; r = m->_m_lock;
int own = r & 0x3fffffff; int own = r & 0x3fffffff;
if (!r) if (!own && (!r || (type&4)))
continue; continue;
if ((type&3) == PTHREAD_MUTEX_ERRORCHECK if ((type&3) == PTHREAD_MUTEX_ERRORCHECK
&& own == __pthread_self()->tid) && own == __pthread_self()->tid)
......
...@@ -17,14 +17,22 @@ int __pthread_mutex_trylock_owner(pthread_mutex_t *m) ...@@ -17,14 +17,22 @@ int __pthread_mutex_trylock_owner(pthread_mutex_t *m)
} }
} }
if (own == 0x3fffffff) return ENOTRECOVERABLE; if (own == 0x3fffffff) return ENOTRECOVERABLE;
tid |= 0x80000000; if (own || (old && !(type & 4))) return EBUSY;
if (own) 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) { if (a_cas(&m->_m_lock, old, tid) != old) {
self->robust_list.pending = 0; self->robust_list.pending = 0;
return EBUSY; return EBUSY;
} }
#if 0
volatile void *next = self->robust_list.head; volatile void *next = self->robust_list.head;
m->_m_next = next; m->_m_next = next;
m->_m_prev = &self->robust_list.head; m->_m_prev = &self->robust_list.head;
...@@ -32,13 +40,18 @@ int __pthread_mutex_trylock_owner(pthread_mutex_t *m) ...@@ -32,13 +40,18 @@ int __pthread_mutex_trylock_owner(pthread_mutex_t *m)
((char *)next - sizeof(void *)) = &m->_m_next; ((char *)next - sizeof(void *)) = &m->_m_next;
self->robust_list.head = &m->_m_next; self->robust_list.head = &m->_m_next;
self->robust_list.pending = 0; self->robust_list.pending = 0;
#endif
if (old) {
m->_m_count = 0;
return EOWNERDEAD;
}
return 0; return 0;
} }
int __pthread_mutex_trylock(pthread_mutex_t *m) 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 a_cas(&m->_m_lock, 0, EBUSY) & EBUSY;
return __pthread_mutex_trylock_owner(m); return __pthread_mutex_trylock_owner(m);
} }
......
...@@ -5,7 +5,7 @@ int __pthread_mutex_unlock(pthread_mutex_t *m) ...@@ -5,7 +5,7 @@ int __pthread_mutex_unlock(pthread_mutex_t *m)
pthread_t self; pthread_t self;
int waiters = m->_m_waiters; int waiters = m->_m_waiters;
int cont; 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 priv = (m->_m_type & 128) ^ 128;
int new = 0; int new = 0;
int old; int old;
...@@ -18,11 +18,25 @@ int __pthread_mutex_unlock(pthread_mutex_t *m) ...@@ -18,11 +18,25 @@ int __pthread_mutex_unlock(pthread_mutex_t *m)
return EPERM; return EPERM;
if ((type&PTHREAD_MUTEX_TYPE_MASK) == PTHREAD_MUTEX_RECURSIVE && m->_m_count) if ((type&PTHREAD_MUTEX_TYPE_MASK) == PTHREAD_MUTEX_RECURSIVE && m->_m_count)
return m->_m_count--, 0; 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); cont = a_swap(&m->_m_lock, new);
if (type != PTHREAD_MUTEX_NORMAL && !priv) {
self->robust_list.pending = 0;
__vm_unlock();
}
if (waiters || cont<0) if (waiters || cont<0)
__wake(&m->_m_lock, 1, priv); __wake(&m->_m_lock, 1, priv);
return 0; return 0;
......
#include "pthread_impl.h" #include "pthread_impl.h"
#include <unsupported_api.h>
#include "syscall.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) int pthread_mutexattr_setrobust(pthread_mutexattr_t *a, int robust)
{ {
unsupported_api(__FUNCTION__);
if (robust > 1U) return EINVAL; if (robust > 1U) return EINVAL;
if (robust) { if (robust) {
pthread_once(&check_robust_once, check_robust);
if (check_robust_result) return check_robust_result;
a->__attr |= 4; a->__attr |= 4;
return 0; 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.
先完成此消息的编辑!
想要评论请 注册