FreeBSD/sys/kern/kern_umtx.c
/*
 * Unlock PTHREAD_PRIO_NONE protocol POSIX mutex.
 */
Unlock PTHREAD_PRIO_NONE protocol POSIX mutex.
Unlock PTHREAD_PRIO_NONE protocol POSIX mutex .
static int
do_unlock_normal(struct thread *td, struct umutex *m, uint32_t flags, bool rb)
{
	struct umtx_key key;
	uint32_t owner, old, id, newlock;
	int error, count;
	id = td->td_tid;
	error = fueword32(&m->m_owner, &owner);
	if (error == -1)
		return (EFAULT);
	if ((owner & ~UMUTEX_CONTESTED) != id)
		return (EPERM);
	newlock = umtx_unlock_val(flags, rb);
	if ((owner & UMUTEX_CONTESTED) == 0) {
		error = casueword32(&m->m_owner, owner, &old, newlock);
		if (error == -1)
			return (EFAULT);
		if (old == owner)
			return (0);
		owner = old;
	}
	if ((error = umtx_key_get(m, TYPE_NORMAL_UMUTEX, GET_SHARE(flags),
	    &key)) != 0)
		return (error);
	umtxq_lock(&key);
	umtxq_busy(&key);
	count = umtxq_count(&key);
	umtxq_unlock(&key);
	if (count > 1)
		newlock |= UMUTEX_CONTESTED;
	error = casueword32(&m->m_owner, owner, &old, newlock);
	umtxq_lock(&key);
	umtxq_signal(&key, 1);
	umtxq_unbusy(&key);
	umtxq_unlock(&key);
	umtx_key_release(&key);
	if (error == -1)
		return (EFAULT);
	if (old != owner)
		return (EINVAL);
	return (0);
}
static int do_unlock_normal ( struct thread * td , struct umutex * m , uint32_t flags , bool rb ) { struct umtx_key key ; uint32_t owner , old , id , newlock ; int error , count ; id = td -> td_tid ; error = fueword32 ( & m -> m_owner , & owner ) ; if ( error == -1 ) return ( EFAULT ) ; if ( ( owner & ~ UMUTEX_CONTESTED ) != id ) return ( EPERM ) ; newlock = umtx_unlock_val ( flags , rb ) ; if ( ( owner & UMUTEX_CONTESTED ) == 0 ) { error = casueword32 ( & m -> m_owner , owner , & old , newlock ) ; if ( error == -1 ) return ( EFAULT ) ; if ( old == owner ) return ( 0 ) ; owner = old ; } if ( ( error = umtx_key_get ( m , TYPE_NORMAL_UMUTEX , GET_SHARE ( flags ) , & key ) ) != 0 ) return ( error ) ; umtxq_lock ( & key ) ; umtxq_busy ( & key ) ; count = umtxq_count ( & key ) ; umtxq_unlock ( & key ) ; if ( count > 1 ) newlock |= UMUTEX_CONTESTED ; error = casueword32 ( & m -> m_owner , owner , & old , newlock ) ; umtxq_lock ( & key ) ; umtxq_signal ( & key , 1 ) ; umtxq_unbusy ( & key ) ; umtxq_unlock ( & key ) ; umtx_key_release ( & key ) ; if ( error == -1 ) return ( EFAULT ) ; if ( old != owner ) return ( EINVAL ) ; return ( 0 ) ; }
Unlock PTHREAD_PRIO_NONE protocol POSIX mutex.
Unlock PTHREAD_PRIO_NONE protocol POSIX mutex .
/*
	 * Make sure we own this mtx.
	 */ /* We should only ever be in here for contested locks */ /*
	 * When unlocking the umtx, it must be marked as unowned if
	 * there is zero or one thread only waiting for it.
	 * Otherwise, it must be marked as contested.
	 */