github.com/afumu/libc@v0.0.6/musl/src/thread/pthread_mutex_trylock.c (about)

     1  #include "pthread_impl.h"
     2  
     3  int __pthread_mutex_trylock_owner(pthread_mutex_t *m)
     4  {
     5  	int old, own;
     6  	int type = m->_m_type;
     7  	pthread_t self = __pthread_self();
     8  	int tid = self->tid;
     9  
    10  	old = m->_m_lock;
    11  	own = old & 0x3fffffff;
    12  	if (own == tid) {
    13  		if ((type&8) && m->_m_count<0) {
    14  			old &= 0x40000000;
    15  			m->_m_count = 0;
    16  			goto success;
    17  		}
    18  		if ((type&3) == PTHREAD_MUTEX_RECURSIVE) {
    19  			if ((unsigned)m->_m_count >= INT_MAX) return EAGAIN;
    20  			m->_m_count++;
    21  			return 0;
    22  		}
    23  	}
    24  	if (own == 0x3fffffff) return ENOTRECOVERABLE;
    25  	if (own || (old && !(type & 4))) return EBUSY;
    26  
    27  	if (type & 128) {
    28  		if (!self->robust_list.off) {
    29  			self->robust_list.off = (char*)&m->_m_lock-(char *)&m->_m_next;
    30  			__syscall(SYS_set_robust_list, &self->robust_list, 3*sizeof(long));
    31  		}
    32  		if (m->_m_waiters) tid |= 0x80000000;
    33  		self->robust_list.pending = &m->_m_next;
    34  	}
    35  	tid |= old & 0x40000000;
    36  
    37  	if (a_cas(&m->_m_lock, old, tid) != old) {
    38  		self->robust_list.pending = 0;
    39  		if ((type&12)==12 && m->_m_waiters) return ENOTRECOVERABLE;
    40  		return EBUSY;
    41  	}
    42  
    43  success:
    44  	if ((type&8) && m->_m_waiters) {
    45  		int priv = (type & 128) ^ 128;
    46  		__syscall(SYS_futex, &m->_m_lock, FUTEX_UNLOCK_PI|priv);
    47  		self->robust_list.pending = 0;
    48  		return (type&4) ? ENOTRECOVERABLE : EBUSY;
    49  	}
    50  
    51  	volatile void *next = self->robust_list.head;
    52  	m->_m_next = next;
    53  	m->_m_prev = &self->robust_list.head;
    54  	if (next != &self->robust_list.head) *(volatile void *volatile *)
    55  		((char *)next - sizeof(void *)) = &m->_m_next;
    56  	self->robust_list.head = &m->_m_next;
    57  	self->robust_list.pending = 0;
    58  
    59  	if (old) {
    60  		m->_m_count = 0;
    61  		return EOWNERDEAD;
    62  	}
    63  
    64  	return 0;
    65  }
    66  
    67  int __pthread_mutex_trylock(pthread_mutex_t *m)
    68  {
    69  	if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL)
    70  		return a_cas(&m->_m_lock, 0, EBUSY) & EBUSY;
    71  	return __pthread_mutex_trylock_owner(m);
    72  }
    73  
    74  weak_alias(__pthread_mutex_trylock, pthread_mutex_trylock);