github.com/afumu/libc@v0.0.6/musl/src/thread/pthread_mutex_unlock.c (about) 1 #include "pthread_impl.h" 2 3 int __pthread_mutex_unlock(pthread_mutex_t *m) 4 { 5 pthread_t self; 6 int waiters = m->_m_waiters; 7 int cont; 8 int type = m->_m_type & 15; 9 int priv = (m->_m_type & 128) ^ 128; 10 int new = 0; 11 int old; 12 13 if (type != PTHREAD_MUTEX_NORMAL) { 14 self = __pthread_self(); 15 old = m->_m_lock; 16 int own = old & 0x3fffffff; 17 if (own != self->tid) 18 return EPERM; 19 if ((type&3) == PTHREAD_MUTEX_RECURSIVE && m->_m_count) 20 return m->_m_count--, 0; 21 if ((type&4) && (old&0x40000000)) 22 new = 0x7fffffff; 23 if (!priv) { 24 self->robust_list.pending = &m->_m_next; 25 __vm_lock(); 26 } 27 volatile void *prev = m->_m_prev; 28 volatile void *next = m->_m_next; 29 *(volatile void *volatile *)prev = next; 30 if (next != &self->robust_list.head) *(volatile void *volatile *) 31 ((char *)next - sizeof(void *)) = prev; 32 } 33 if (type&8) { 34 if (old<0 || a_cas(&m->_m_lock, old, new)!=old) { 35 if (new) a_store(&m->_m_waiters, -1); 36 __syscall(SYS_futex, &m->_m_lock, FUTEX_UNLOCK_PI|priv); 37 } 38 cont = 0; 39 waiters = 0; 40 } else { 41 cont = a_swap(&m->_m_lock, new); 42 } 43 if (type != PTHREAD_MUTEX_NORMAL && !priv) { 44 self->robust_list.pending = 0; 45 __vm_unlock(); 46 } 47 if (waiters || cont<0) 48 __wake(&m->_m_lock, 1, priv); 49 return 0; 50 } 51 52 weak_alias(__pthread_mutex_unlock, pthread_mutex_unlock);