#include "pthread_impl.h"
+#include "atomic.h"
int pthread_mutex_consistent(pthread_mutex_t *m)
{
- if (!(m->_m_type & 8)) return EINVAL;
- if ((m->_m_lock & 0x7fffffff) != __pthread_self()->tid)
+ 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;
- m->_m_type &= ~8U;
+ a_and(&m->_m_lock, ~0x40000000);
return 0;
}
while (spins-- && m->_m_lock && !m->_m_waiters) a_spin();
while ((r=__pthread_mutex_trylock(m)) == EBUSY) {
- if (!(r=m->_m_lock) || ((r&0x40000000) && (type&4)))
+ r = m->_m_lock;
+ int own = r & 0x3fffffff;
+ if (!own && (!r || (type&4)))
continue;
if ((type&3) == PTHREAD_MUTEX_ERRORCHECK
- && (r&0x7fffffff) == __pthread_self()->tid)
+ && own == __pthread_self()->tid)
return EDEADLK;
a_inc(&m->_m_waiters);
int tid = self->tid;
old = m->_m_lock;
- own = old & 0x7fffffff;
+ own = old & 0x3fffffff;
if (own == tid && (type&3) == PTHREAD_MUTEX_RECURSIVE) {
if ((unsigned)m->_m_count >= INT_MAX) return EAGAIN;
m->_m_count++;
return 0;
}
- if (own == 0x7fffffff) return ENOTRECOVERABLE;
- if (own && (!(own & 0x40000000) || !(type & 4))) return EBUSY;
+ if (own == 0x3fffffff) return ENOTRECOVERABLE;
+ if (own || (old && !(type & 4))) return EBUSY;
if (m->_m_type & 128) {
if (!self->robust_list.off) {
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;
self->robust_list.head = &m->_m_next;
self->robust_list.pending = 0;
- if (own) {
+ if (old) {
m->_m_count = 0;
- m->_m_type |= 8;
return EOWNERDEAD;
}
int cont;
int type = m->_m_type & 15;
int priv = (m->_m_type & 128) ^ 128;
+ int new = 0;
if (type != PTHREAD_MUTEX_NORMAL) {
self = __pthread_self();
- if ((m->_m_lock&0x7fffffff) != self->tid)
+ int old = m->_m_lock;
+ int own = old & 0x3fffffff;
+ if (own != self->tid)
return EPERM;
if ((type&3) == 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();
if (next != &self->robust_list.head) *(volatile void *volatile *)
((char *)next - sizeof(void *)) = prev;
}
- cont = a_swap(&m->_m_lock, (type & 8) ? 0x7fffffff : 0);
+ cont = a_swap(&m->_m_lock, new);
if (type != PTHREAD_MUTEX_NORMAL && !priv) {
self->robust_list.pending = 0;
__vm_unlock();