Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_umtx.c
Show First 20 Lines • Show All 3,117 Lines • ▼ Show 20 Lines | do_sem_wake(struct thread *td, struct _usem *sem) | ||||
if (error == -1) | if (error == -1) | ||||
return (EFAULT); | return (EFAULT); | ||||
if ((error = umtx_key_get(sem, TYPE_SEM, GET_SHARE(flags), &key)) != 0) | if ((error = umtx_key_get(sem, TYPE_SEM, GET_SHARE(flags), &key)) != 0) | ||||
return (error); | return (error); | ||||
umtxq_lock(&key); | umtxq_lock(&key); | ||||
umtxq_busy(&key); | umtxq_busy(&key); | ||||
cnt = umtxq_count(&key); | cnt = umtxq_count(&key); | ||||
if (cnt > 0) { | if (cnt > 0) { | ||||
umtxq_signal(&key, 1); | |||||
/* | /* | ||||
* Check if count is greater than 0, this means the memory is | * Check if count is greater than 0, this means the memory is | ||||
* still being referenced by user code, so we can safely | * still being referenced by user code, so we can safely | ||||
* update _has_waiters flag. | * update _has_waiters flag. | ||||
*/ | */ | ||||
if (cnt == 1) { | if (cnt == 1) { | ||||
umtxq_unlock(&key); | umtxq_unlock(&key); | ||||
error = suword32(&sem->_has_waiters, 0); | error = suword32(&sem->_has_waiters, 0); | ||||
umtxq_lock(&key); | umtxq_lock(&key); | ||||
if (error == -1) | if (error == -1) | ||||
error = EFAULT; | error = EFAULT; | ||||
} | } | ||||
umtxq_signal(&key, 1); | |||||
} | } | ||||
umtxq_unbusy(&key); | umtxq_unbusy(&key); | ||||
umtxq_unlock(&key); | umtxq_unlock(&key); | ||||
umtx_key_release(&key); | umtx_key_release(&key); | ||||
return (error); | return (error); | ||||
} | } | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | do_sem2_wake(struct thread *td, struct _usem2 *sem) | ||||
if (rv == -1) | if (rv == -1) | ||||
return (EFAULT); | return (EFAULT); | ||||
if ((error = umtx_key_get(sem, TYPE_SEM, GET_SHARE(flags), &key)) != 0) | if ((error = umtx_key_get(sem, TYPE_SEM, GET_SHARE(flags), &key)) != 0) | ||||
return (error); | return (error); | ||||
umtxq_lock(&key); | umtxq_lock(&key); | ||||
umtxq_busy(&key); | umtxq_busy(&key); | ||||
cnt = umtxq_count(&key); | cnt = umtxq_count(&key); | ||||
if (cnt > 0) { | if (cnt > 0) { | ||||
umtxq_signal(&key, 1); | |||||
/* | /* | ||||
* If this was the last sleeping thread, clear the waiters | * If this was the last sleeping thread, clear the waiters | ||||
* flag in _count. | * flag in _count. | ||||
*/ | */ | ||||
if (cnt == 1) { | if (cnt == 1) { | ||||
umtxq_unlock(&key); | umtxq_unlock(&key); | ||||
rv = fueword32(&sem->_count, &count); | rv = fueword32(&sem->_count, &count); | ||||
while (rv != -1 && count & USEM_HAS_WAITERS) | while (rv != -1 && count & USEM_HAS_WAITERS) | ||||
rv = casueword32(&sem->_count, count, &count, | rv = casueword32(&sem->_count, count, &count, | ||||
count & ~USEM_HAS_WAITERS); | count & ~USEM_HAS_WAITERS); | ||||
if (rv == -1) | if (rv == -1) | ||||
error = EFAULT; | error = EFAULT; | ||||
umtxq_lock(&key); | umtxq_lock(&key); | ||||
} | } | ||||
umtxq_signal(&key, 1); | |||||
} | } | ||||
umtxq_unbusy(&key); | umtxq_unbusy(&key); | ||||
umtxq_unlock(&key); | umtxq_unlock(&key); | ||||
umtx_key_release(&key); | umtx_key_release(&key); | ||||
return (error); | return (error); | ||||
} | } | ||||
inline int | inline int | ||||
▲ Show 20 Lines • Show All 1,233 Lines • Show Last 20 Lines |