blob: 7bb9236a512ddd78a7dc7629d752d8ea4ba93f4c [file] [log] [blame]
#include "pthread_impl.h"
#include "futex_impl.h"
int pthread_mutex_unlock(pthread_mutex_t* m) {
int waiters = atomic_load(&m->_m_waiters);
int cont;
int type = m->_m_type & PTHREAD_MUTEX_MASK;
if (type != PTHREAD_MUTEX_NORMAL) {
if ((atomic_load(&m->_m_lock) & PTHREAD_MUTEX_OWNED_LOCK_MASK) != __thread_get_tid())
return EPERM;
if ((type & PTHREAD_MUTEX_MASK) == PTHREAD_MUTEX_RECURSIVE && m->_m_count)
return m->_m_count--, 0;
}
cont = atomic_exchange(&m->_m_lock, 0);
if (waiters || cont < 0)
__wake(&m->_m_lock, 1);
return 0;
}