mirror of
https://github.com/opnsense/src.git
synced 2026-02-20 00:11:07 -05:00
Remove dead code from umtx support:
- Retire long time unused (basically always unused) sys__umtx_lock() and sys__umtx_unlock() syscalls - struct umtx and their supporting definitions - UMUTEX_ERROR_CHECK flag - Retire UMTX_OP_LOCK/UMTX_OP_UNLOCK from _umtx_op() syscall __FreeBSD_version is not bumped yet because it is expected that further breakages to the umtx interface will follow up in the next days. However there will be a final bump when necessary. Sponsored by: EMC / Isilon storage division Reviewed by: jhb
This commit is contained in:
parent
38035ed6dc
commit
ce42e79310
7 changed files with 13 additions and 557 deletions
|
|
@ -775,8 +775,8 @@
|
|||
431 AUE_NULL NOPROTO { void thr_exit(long *state); }
|
||||
432 AUE_NULL NOPROTO { int thr_self(long *id); }
|
||||
433 AUE_NULL NOPROTO { int thr_kill(long id, int sig); }
|
||||
434 AUE_NULL STD { int freebsd32_umtx_lock(struct umtx *umtx); }
|
||||
435 AUE_NULL STD { int freebsd32_umtx_unlock(struct umtx *umtx); }
|
||||
434 AUE_NULL UNIMPL nosys
|
||||
435 AUE_NULL UNIMPL nosys
|
||||
436 AUE_NULL NOPROTO { int jail_attach(int jid); }
|
||||
437 AUE_EXTATTR_LIST_FD NOPROTO { ssize_t extattr_list_fd(int fd, \
|
||||
int attrnamespace, void *data, \
|
||||
|
|
|
|||
|
|
@ -837,367 +837,6 @@ umtx_key_release(struct umtx_key *key)
|
|||
vm_object_deallocate(key->info.shared.object);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock a umtx object.
|
||||
*/
|
||||
static int
|
||||
do_lock_umtx(struct thread *td, struct umtx *umtx, u_long id,
|
||||
const struct timespec *timeout)
|
||||
{
|
||||
struct abs_timeout timo;
|
||||
struct umtx_q *uq;
|
||||
u_long owner;
|
||||
u_long old;
|
||||
int error = 0;
|
||||
|
||||
uq = td->td_umtxq;
|
||||
if (timeout != NULL)
|
||||
abs_timeout_init(&timo, CLOCK_REALTIME, 0, timeout);
|
||||
|
||||
/*
|
||||
* Care must be exercised when dealing with umtx structure. It
|
||||
* can fault on any access.
|
||||
*/
|
||||
for (;;) {
|
||||
/*
|
||||
* Try the uncontested case. This should be done in userland.
|
||||
*/
|
||||
owner = casuword(&umtx->u_owner, UMTX_UNOWNED, id);
|
||||
|
||||
/* The acquire succeeded. */
|
||||
if (owner == UMTX_UNOWNED)
|
||||
return (0);
|
||||
|
||||
/* The address was invalid. */
|
||||
if (owner == -1)
|
||||
return (EFAULT);
|
||||
|
||||
/* If no one owns it but it is contested try to acquire it. */
|
||||
if (owner == UMTX_CONTESTED) {
|
||||
owner = casuword(&umtx->u_owner,
|
||||
UMTX_CONTESTED, id | UMTX_CONTESTED);
|
||||
|
||||
if (owner == UMTX_CONTESTED)
|
||||
return (0);
|
||||
|
||||
/* The address was invalid. */
|
||||
if (owner == -1)
|
||||
return (EFAULT);
|
||||
|
||||
error = umtxq_check_susp(td);
|
||||
if (error != 0)
|
||||
break;
|
||||
|
||||
/* If this failed the lock has changed, restart. */
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we caught a signal, we have retried and now
|
||||
* exit immediately.
|
||||
*/
|
||||
if (error != 0)
|
||||
break;
|
||||
|
||||
if ((error = umtx_key_get(umtx, TYPE_SIMPLE_LOCK,
|
||||
AUTO_SHARE, &uq->uq_key)) != 0)
|
||||
return (error);
|
||||
|
||||
umtxq_lock(&uq->uq_key);
|
||||
umtxq_busy(&uq->uq_key);
|
||||
umtxq_insert(uq);
|
||||
umtxq_unbusy(&uq->uq_key);
|
||||
umtxq_unlock(&uq->uq_key);
|
||||
|
||||
/*
|
||||
* Set the contested bit so that a release in user space
|
||||
* knows to use the system call for unlock. If this fails
|
||||
* either some one else has acquired the lock or it has been
|
||||
* released.
|
||||
*/
|
||||
old = casuword(&umtx->u_owner, owner, owner | UMTX_CONTESTED);
|
||||
|
||||
/* The address was invalid. */
|
||||
if (old == -1) {
|
||||
umtxq_lock(&uq->uq_key);
|
||||
umtxq_remove(uq);
|
||||
umtxq_unlock(&uq->uq_key);
|
||||
umtx_key_release(&uq->uq_key);
|
||||
return (EFAULT);
|
||||
}
|
||||
|
||||
/*
|
||||
* We set the contested bit, sleep. Otherwise the lock changed
|
||||
* and we need to retry or we lost a race to the thread
|
||||
* unlocking the umtx.
|
||||
*/
|
||||
umtxq_lock(&uq->uq_key);
|
||||
if (old == owner)
|
||||
error = umtxq_sleep(uq, "umtx", timeout == NULL ? NULL :
|
||||
&timo);
|
||||
umtxq_remove(uq);
|
||||
umtxq_unlock(&uq->uq_key);
|
||||
umtx_key_release(&uq->uq_key);
|
||||
|
||||
if (error == 0)
|
||||
error = umtxq_check_susp(td);
|
||||
}
|
||||
|
||||
if (timeout == NULL) {
|
||||
/* Mutex locking is restarted if it is interrupted. */
|
||||
if (error == EINTR)
|
||||
error = ERESTART;
|
||||
} else {
|
||||
/* Timed-locking is not restarted. */
|
||||
if (error == ERESTART)
|
||||
error = EINTR;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlock a umtx object.
|
||||
*/
|
||||
static int
|
||||
do_unlock_umtx(struct thread *td, struct umtx *umtx, u_long id)
|
||||
{
|
||||
struct umtx_key key;
|
||||
u_long owner;
|
||||
u_long old;
|
||||
int error;
|
||||
int count;
|
||||
|
||||
/*
|
||||
* Make sure we own this mtx.
|
||||
*/
|
||||
owner = fuword(__DEVOLATILE(u_long *, &umtx->u_owner));
|
||||
if (owner == -1)
|
||||
return (EFAULT);
|
||||
|
||||
if ((owner & ~UMTX_CONTESTED) != id)
|
||||
return (EPERM);
|
||||
|
||||
/* This should be done in userland */
|
||||
if ((owner & UMTX_CONTESTED) == 0) {
|
||||
old = casuword(&umtx->u_owner, owner, UMTX_UNOWNED);
|
||||
if (old == -1)
|
||||
return (EFAULT);
|
||||
if (old == owner)
|
||||
return (0);
|
||||
owner = old;
|
||||
}
|
||||
|
||||
/* We should only ever be in here for contested locks */
|
||||
if ((error = umtx_key_get(umtx, TYPE_SIMPLE_LOCK, AUTO_SHARE,
|
||||
&key)) != 0)
|
||||
return (error);
|
||||
|
||||
umtxq_lock(&key);
|
||||
umtxq_busy(&key);
|
||||
count = umtxq_count(&key);
|
||||
umtxq_unlock(&key);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
old = casuword(&umtx->u_owner, owner,
|
||||
count <= 1 ? UMTX_UNOWNED : UMTX_CONTESTED);
|
||||
umtxq_lock(&key);
|
||||
umtxq_signal(&key,1);
|
||||
umtxq_unbusy(&key);
|
||||
umtxq_unlock(&key);
|
||||
umtx_key_release(&key);
|
||||
if (old == -1)
|
||||
return (EFAULT);
|
||||
if (old != owner)
|
||||
return (EINVAL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef COMPAT_FREEBSD32
|
||||
|
||||
/*
|
||||
* Lock a umtx object.
|
||||
*/
|
||||
static int
|
||||
do_lock_umtx32(struct thread *td, uint32_t *m, uint32_t id,
|
||||
const struct timespec *timeout)
|
||||
{
|
||||
struct abs_timeout timo;
|
||||
struct umtx_q *uq;
|
||||
uint32_t owner;
|
||||
uint32_t old;
|
||||
int error = 0;
|
||||
|
||||
uq = td->td_umtxq;
|
||||
|
||||
if (timeout != NULL)
|
||||
abs_timeout_init(&timo, CLOCK_REALTIME, 0, timeout);
|
||||
|
||||
/*
|
||||
* Care must be exercised when dealing with umtx structure. It
|
||||
* can fault on any access.
|
||||
*/
|
||||
for (;;) {
|
||||
/*
|
||||
* Try the uncontested case. This should be done in userland.
|
||||
*/
|
||||
owner = casuword32(m, UMUTEX_UNOWNED, id);
|
||||
|
||||
/* The acquire succeeded. */
|
||||
if (owner == UMUTEX_UNOWNED)
|
||||
return (0);
|
||||
|
||||
/* The address was invalid. */
|
||||
if (owner == -1)
|
||||
return (EFAULT);
|
||||
|
||||
/* If no one owns it but it is contested try to acquire it. */
|
||||
if (owner == UMUTEX_CONTESTED) {
|
||||
owner = casuword32(m,
|
||||
UMUTEX_CONTESTED, id | UMUTEX_CONTESTED);
|
||||
if (owner == UMUTEX_CONTESTED)
|
||||
return (0);
|
||||
|
||||
/* The address was invalid. */
|
||||
if (owner == -1)
|
||||
return (EFAULT);
|
||||
|
||||
error = umtxq_check_susp(td);
|
||||
if (error != 0)
|
||||
break;
|
||||
|
||||
/* If this failed the lock has changed, restart. */
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we caught a signal, we have retried and now
|
||||
* exit immediately.
|
||||
*/
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if ((error = umtx_key_get(m, TYPE_SIMPLE_LOCK,
|
||||
AUTO_SHARE, &uq->uq_key)) != 0)
|
||||
return (error);
|
||||
|
||||
umtxq_lock(&uq->uq_key);
|
||||
umtxq_busy(&uq->uq_key);
|
||||
umtxq_insert(uq);
|
||||
umtxq_unbusy(&uq->uq_key);
|
||||
umtxq_unlock(&uq->uq_key);
|
||||
|
||||
/*
|
||||
* Set the contested bit so that a release in user space
|
||||
* knows to use the system call for unlock. If this fails
|
||||
* either some one else has acquired the lock or it has been
|
||||
* released.
|
||||
*/
|
||||
old = casuword32(m, owner, owner | UMUTEX_CONTESTED);
|
||||
|
||||
/* The address was invalid. */
|
||||
if (old == -1) {
|
||||
umtxq_lock(&uq->uq_key);
|
||||
umtxq_remove(uq);
|
||||
umtxq_unlock(&uq->uq_key);
|
||||
umtx_key_release(&uq->uq_key);
|
||||
return (EFAULT);
|
||||
}
|
||||
|
||||
/*
|
||||
* We set the contested bit, sleep. Otherwise the lock changed
|
||||
* and we need to retry or we lost a race to the thread
|
||||
* unlocking the umtx.
|
||||
*/
|
||||
umtxq_lock(&uq->uq_key);
|
||||
if (old == owner)
|
||||
error = umtxq_sleep(uq, "umtx", timeout == NULL ?
|
||||
NULL : &timo);
|
||||
umtxq_remove(uq);
|
||||
umtxq_unlock(&uq->uq_key);
|
||||
umtx_key_release(&uq->uq_key);
|
||||
|
||||
if (error == 0)
|
||||
error = umtxq_check_susp(td);
|
||||
}
|
||||
|
||||
if (timeout == NULL) {
|
||||
/* Mutex locking is restarted if it is interrupted. */
|
||||
if (error == EINTR)
|
||||
error = ERESTART;
|
||||
} else {
|
||||
/* Timed-locking is not restarted. */
|
||||
if (error == ERESTART)
|
||||
error = EINTR;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlock a umtx object.
|
||||
*/
|
||||
static int
|
||||
do_unlock_umtx32(struct thread *td, uint32_t *m, uint32_t id)
|
||||
{
|
||||
struct umtx_key key;
|
||||
uint32_t owner;
|
||||
uint32_t old;
|
||||
int error;
|
||||
int count;
|
||||
|
||||
/*
|
||||
* Make sure we own this mtx.
|
||||
*/
|
||||
owner = fuword32(m);
|
||||
if (owner == -1)
|
||||
return (EFAULT);
|
||||
|
||||
if ((owner & ~UMUTEX_CONTESTED) != id)
|
||||
return (EPERM);
|
||||
|
||||
/* This should be done in userland */
|
||||
if ((owner & UMUTEX_CONTESTED) == 0) {
|
||||
old = casuword32(m, owner, UMUTEX_UNOWNED);
|
||||
if (old == -1)
|
||||
return (EFAULT);
|
||||
if (old == owner)
|
||||
return (0);
|
||||
owner = old;
|
||||
}
|
||||
|
||||
/* We should only ever be in here for contested locks */
|
||||
if ((error = umtx_key_get(m, TYPE_SIMPLE_LOCK, AUTO_SHARE,
|
||||
&key)) != 0)
|
||||
return (error);
|
||||
|
||||
umtxq_lock(&key);
|
||||
umtxq_busy(&key);
|
||||
count = umtxq_count(&key);
|
||||
umtxq_unlock(&key);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
old = casuword32(m, owner,
|
||||
count <= 1 ? UMUTEX_UNOWNED : UMUTEX_CONTESTED);
|
||||
umtxq_lock(&key);
|
||||
umtxq_signal(&key,1);
|
||||
umtxq_unbusy(&key);
|
||||
umtxq_unlock(&key);
|
||||
umtx_key_release(&key);
|
||||
if (old == -1)
|
||||
return (EFAULT);
|
||||
if (old != owner)
|
||||
return (EINVAL);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Fetch and compare value, sleep on the address if value is not changed.
|
||||
*/
|
||||
|
|
@ -1321,10 +960,6 @@ do_lock_normal(struct thread *td, struct umutex *m, uint32_t flags,
|
|||
}
|
||||
}
|
||||
|
||||
if ((flags & UMUTEX_ERROR_CHECK) != 0 &&
|
||||
(owner & ~UMUTEX_CONTESTED) == id)
|
||||
return (EDEADLK);
|
||||
|
||||
if (mode == _UMUTEX_TRY)
|
||||
return (EBUSY);
|
||||
|
||||
|
|
@ -2026,12 +1661,6 @@ do_lock_pi(struct thread *td, struct umutex *m, uint32_t flags,
|
|||
continue;
|
||||
}
|
||||
|
||||
if ((flags & UMUTEX_ERROR_CHECK) != 0 &&
|
||||
(owner & ~UMUTEX_CONTESTED) == id) {
|
||||
error = EDEADLK;
|
||||
break;
|
||||
}
|
||||
|
||||
if (try != 0) {
|
||||
error = EBUSY;
|
||||
break;
|
||||
|
|
@ -2257,12 +1886,6 @@ do_lock_pp(struct thread *td, struct umutex *m, uint32_t flags,
|
|||
break;
|
||||
}
|
||||
|
||||
if ((flags & UMUTEX_ERROR_CHECK) != 0 &&
|
||||
(owner & ~UMUTEX_CONTESTED) == id) {
|
||||
error = EDEADLK;
|
||||
break;
|
||||
}
|
||||
|
||||
if (try != 0) {
|
||||
error = EBUSY;
|
||||
break;
|
||||
|
|
@ -3171,20 +2794,6 @@ do_sem_wake(struct thread *td, struct _usem *sem)
|
|||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
sys__umtx_lock(struct thread *td, struct _umtx_lock_args *uap)
|
||||
/* struct umtx *umtx */
|
||||
{
|
||||
return do_lock_umtx(td, uap->umtx, td->td_tid, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sys__umtx_unlock(struct thread *td, struct _umtx_unlock_args *uap)
|
||||
/* struct umtx *umtx */
|
||||
{
|
||||
return do_unlock_umtx(td, uap->umtx, td->td_tid);
|
||||
}
|
||||
|
||||
inline int
|
||||
umtx_copyin_timeout(const void *addr, struct timespec *tsp)
|
||||
{
|
||||
|
|
@ -3220,27 +2829,10 @@ umtx_copyin_umtx_time(const void *addr, size_t size, struct _umtx_time *tp)
|
|||
}
|
||||
|
||||
static int
|
||||
__umtx_op_lock_umtx(struct thread *td, struct _umtx_op_args *uap)
|
||||
__umtx_op_unimpl(struct thread *td, struct _umtx_op_args *uap)
|
||||
{
|
||||
struct timespec *ts, timeout;
|
||||
int error;
|
||||
|
||||
/* Allow a null timespec (wait forever). */
|
||||
if (uap->uaddr2 == NULL)
|
||||
ts = NULL;
|
||||
else {
|
||||
error = umtx_copyin_timeout(uap->uaddr2, &timeout);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
ts = &timeout;
|
||||
}
|
||||
return (do_lock_umtx(td, uap->obj, uap->val, ts));
|
||||
}
|
||||
|
||||
static int
|
||||
__umtx_op_unlock_umtx(struct thread *td, struct _umtx_op_args *uap)
|
||||
{
|
||||
return (do_unlock_umtx(td, uap->obj, uap->val));
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -3506,8 +3098,8 @@ __umtx_op_wake2_umutex(struct thread *td, struct _umtx_op_args *uap)
|
|||
typedef int (*_umtx_op_func)(struct thread *td, struct _umtx_op_args *uap);
|
||||
|
||||
static _umtx_op_func op_table[] = {
|
||||
__umtx_op_lock_umtx, /* UMTX_OP_LOCK */
|
||||
__umtx_op_unlock_umtx, /* UMTX_OP_UNLOCK */
|
||||
__umtx_op_unimpl, /* UMTX_OP_RESERVED0 */
|
||||
__umtx_op_unimpl, /* UMTX_OP_RESERVED1 */
|
||||
__umtx_op_wait, /* UMTX_OP_WAIT */
|
||||
__umtx_op_wake, /* UMTX_OP_WAKE */
|
||||
__umtx_op_trylock_umutex, /* UMTX_OP_MUTEX_TRYLOCK */
|
||||
|
|
@ -3540,19 +3132,6 @@ sys__umtx_op(struct thread *td, struct _umtx_op_args *uap)
|
|||
}
|
||||
|
||||
#ifdef COMPAT_FREEBSD32
|
||||
int
|
||||
freebsd32_umtx_lock(struct thread *td, struct freebsd32_umtx_lock_args *uap)
|
||||
/* struct umtx *umtx */
|
||||
{
|
||||
return (do_lock_umtx32(td, (uint32_t *)uap->umtx, td->td_tid, NULL));
|
||||
}
|
||||
|
||||
int
|
||||
freebsd32_umtx_unlock(struct thread *td, struct freebsd32_umtx_unlock_args *uap)
|
||||
/* struct umtx *umtx */
|
||||
{
|
||||
return (do_unlock_umtx32(td, (uint32_t *)uap->umtx, td->td_tid));
|
||||
}
|
||||
|
||||
struct timespec32 {
|
||||
int32_t tv_sec;
|
||||
|
|
@ -3609,30 +3188,6 @@ umtx_copyin_umtx_time32(const void *addr, size_t size, struct _umtx_time *tp)
|
|||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
__umtx_op_lock_umtx_compat32(struct thread *td, struct _umtx_op_args *uap)
|
||||
{
|
||||
struct timespec *ts, timeout;
|
||||
int error;
|
||||
|
||||
/* Allow a null timespec (wait forever). */
|
||||
if (uap->uaddr2 == NULL)
|
||||
ts = NULL;
|
||||
else {
|
||||
error = umtx_copyin_timeout32(uap->uaddr2, &timeout);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
ts = &timeout;
|
||||
}
|
||||
return (do_lock_umtx32(td, uap->obj, uap->val, ts));
|
||||
}
|
||||
|
||||
static int
|
||||
__umtx_op_unlock_umtx_compat32(struct thread *td, struct _umtx_op_args *uap)
|
||||
{
|
||||
return (do_unlock_umtx32(td, uap->obj, (uint32_t)uap->val));
|
||||
}
|
||||
|
||||
static int
|
||||
__umtx_op_wait_compat32(struct thread *td, struct _umtx_op_args *uap)
|
||||
{
|
||||
|
|
@ -3809,8 +3364,8 @@ __umtx_op_nwake_private32(struct thread *td, struct _umtx_op_args *uap)
|
|||
}
|
||||
|
||||
static _umtx_op_func op_table_compat32[] = {
|
||||
__umtx_op_lock_umtx_compat32, /* UMTX_OP_LOCK */
|
||||
__umtx_op_unlock_umtx_compat32, /* UMTX_OP_UNLOCK */
|
||||
__umtx_op_unimpl, /* UMTX_OP_RESERVED0 */
|
||||
__umtx_op_unimpl, /* UMTX_OP_RESERVED1 */
|
||||
__umtx_op_wait_compat32, /* UMTX_OP_WAIT */
|
||||
__umtx_op_wake, /* UMTX_OP_WAKE */
|
||||
__umtx_op_trylock_umutex, /* UMTX_OP_MUTEX_LOCK */
|
||||
|
|
|
|||
|
|
@ -773,8 +773,8 @@
|
|||
431 AUE_NULL STD { void thr_exit(long *state); }
|
||||
432 AUE_NULL STD { int thr_self(long *id); }
|
||||
433 AUE_NULL STD { int thr_kill(long id, int sig); }
|
||||
434 AUE_NULL STD { int _umtx_lock(struct umtx *umtx); }
|
||||
435 AUE_NULL STD { int _umtx_unlock(struct umtx *umtx); }
|
||||
434 AUE_NULL UNIMPL nosys
|
||||
435 AUE_NULL UNIMPL nosys
|
||||
436 AUE_NULL STD { int jail_attach(int jid); }
|
||||
437 AUE_EXTATTR_LIST_FD STD { ssize_t extattr_list_fd(int fd, \
|
||||
int attrnamespace, void *data, \
|
||||
|
|
|
|||
|
|
@ -33,10 +33,6 @@
|
|||
#include <sys/_types.h>
|
||||
#include <sys/_timespec.h>
|
||||
|
||||
struct umtx {
|
||||
volatile unsigned long u_owner; /* Owner of the mutex. */
|
||||
};
|
||||
|
||||
struct umutex {
|
||||
volatile __lwpid_t m_owner; /* Owner of the mutex */
|
||||
__uint32_t m_flags; /* Flags of the mutex */
|
||||
|
|
|
|||
|
|
@ -31,17 +31,12 @@
|
|||
#define _SYS_UMTX_H_
|
||||
|
||||
#include <sys/_umtx.h>
|
||||
#include <sys/limits.h>
|
||||
|
||||
#define UMTX_UNOWNED 0x0
|
||||
#define UMTX_CONTESTED LONG_MIN
|
||||
|
||||
#define USYNC_PROCESS_SHARED 0x0001 /* Process shared sync objs */
|
||||
|
||||
#define UMUTEX_UNOWNED 0x0
|
||||
#define UMUTEX_CONTESTED 0x80000000U
|
||||
|
||||
#define UMUTEX_ERROR_CHECK 0x0002 /* Error-checking mutex */
|
||||
#define UMUTEX_PRIO_INHERIT 0x0004 /* Priority inherited mutex */
|
||||
#define UMUTEX_PRIO_PROTECT 0x0008 /* Priority protect mutex */
|
||||
|
||||
|
|
@ -58,8 +53,8 @@
|
|||
#define SEM_NAMED 0x0002
|
||||
|
||||
/* op code for _umtx_op */
|
||||
#define UMTX_OP_LOCK 0
|
||||
#define UMTX_OP_UNLOCK 1
|
||||
#define UMTX_OP_RESERVED0 0
|
||||
#define UMTX_OP_RESERVED1 1
|
||||
#define UMTX_OP_WAIT 2
|
||||
#define UMTX_OP_WAKE 3
|
||||
#define UMTX_OP_MUTEX_TRYLOCK 4
|
||||
|
|
@ -96,82 +91,6 @@
|
|||
|
||||
int _umtx_op(void *obj, int op, u_long val, void *uaddr, void *uaddr2);
|
||||
|
||||
/*
|
||||
* Old (deprecated) userland mutex system calls.
|
||||
*/
|
||||
int _umtx_lock(struct umtx *mtx);
|
||||
int _umtx_unlock(struct umtx *mtx);
|
||||
|
||||
/*
|
||||
* Standard api. Try uncontested acquire/release and asks the
|
||||
* kernel to resolve failures.
|
||||
*/
|
||||
static __inline void
|
||||
umtx_init(struct umtx *umtx)
|
||||
{
|
||||
umtx->u_owner = UMTX_UNOWNED;
|
||||
}
|
||||
|
||||
static __inline u_long
|
||||
umtx_owner(struct umtx *umtx)
|
||||
{
|
||||
return (umtx->u_owner & ~LONG_MIN);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
umtx_lock(struct umtx *umtx, u_long id)
|
||||
{
|
||||
if (atomic_cmpset_acq_long(&umtx->u_owner, UMTX_UNOWNED, id) == 0)
|
||||
if (_umtx_lock(umtx) == -1)
|
||||
return (errno);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
umtx_trylock(struct umtx *umtx, u_long id)
|
||||
{
|
||||
if (atomic_cmpset_acq_long(&umtx->u_owner, UMTX_UNOWNED, id) == 0)
|
||||
return (EBUSY);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
umtx_timedlock(struct umtx *umtx, u_long id, const struct timespec *timeout)
|
||||
{
|
||||
if (atomic_cmpset_acq_long(&umtx->u_owner, UMTX_UNOWNED, id) == 0)
|
||||
if (_umtx_op(umtx, UMTX_OP_LOCK, id, 0,
|
||||
__DECONST(void *, timeout)) == -1)
|
||||
return (errno);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
umtx_unlock(struct umtx *umtx, u_long id)
|
||||
{
|
||||
if (atomic_cmpset_rel_long(&umtx->u_owner, id, UMTX_UNOWNED) == 0)
|
||||
if (_umtx_unlock(umtx) == -1)
|
||||
return (errno);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
umtx_wait(u_long *p, long val, const struct timespec *timeout)
|
||||
{
|
||||
if (_umtx_op(p, UMTX_OP_WAIT, val, 0,
|
||||
__DECONST(void *, timeout)) == -1)
|
||||
return (errno);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Wake threads waiting on a user address. */
|
||||
static __inline int
|
||||
umtx_wake(u_long *p, int nr_wakeup)
|
||||
{
|
||||
if (_umtx_op(p, UMTX_OP_WAKE, nr_wakeup, 0, 0) == -1)
|
||||
return (errno);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
* Pollfd -- a pointer to an array of struct pollfd. Prints .fd and .events.
|
||||
* Fd_set -- a pointer to an array of fd_set. Prints the fds that are set.
|
||||
* Sigaction -- a pointer to a struct sigaction. Prints all elements.
|
||||
* Umtx -- a pointer to a struct umtx. Prints the value of owner.
|
||||
* Sigset -- a pointer to a sigset_t. Prints the signals that are set.
|
||||
* Sigprocmask -- the first argument to sigprocmask(). Prints the name.
|
||||
* Kevent -- a pointer to an array of struct kevents. Prints all elements.
|
||||
|
|
@ -38,7 +37,7 @@
|
|||
enum Argtype { None = 1, Hex, Octal, Int, Name, Ptr, Stat, Ioctl, Quad,
|
||||
Signal, Sockaddr, StringArray, Timespec, Timeval, Itimerval, Pollfd,
|
||||
Fd_set, Sigaction, Fcntl, Mprot, Mmapflags, Whence, Readlinkres,
|
||||
Umtx, Sigset, Sigprocmask, Kevent, Sockdomain, Socktype, Open,
|
||||
Sigset, Sigprocmask, Kevent, Sockdomain, Socktype, Open,
|
||||
Fcntlflag, Rusage, BinString, Shutdown, Resource, Rlimit, Timeval2,
|
||||
Pathconf, Rforkflags, ExitStatus, Waitoptions, Idtype, Procctl };
|
||||
|
||||
|
|
|
|||
|
|
@ -215,10 +215,6 @@ static struct syscall syscalls[] = {
|
|||
.args = { { Timespec, 0 } } },
|
||||
{ .name = "kevent", .ret_type = 0, .nargs = 6,
|
||||
.args = { { Int, 0 }, { Kevent, 1 }, { Int, 2 }, { Kevent | OUT, 3 }, { Int, 4 }, { Timespec, 5 } } },
|
||||
{ .name = "_umtx_lock", .ret_type = 0, .nargs = 1,
|
||||
.args = { { Umtx, 0 } } },
|
||||
{ .name = "_umtx_unlock", .ret_type = 0, .nargs = 1,
|
||||
.args = { { Umtx, 0 } } },
|
||||
{ .name = "sigprocmask", .ret_type = 0, .nargs = 3,
|
||||
.args = { { Sigprocmask, 0 }, { Sigset, 1 }, { Sigset | OUT, 2 } } },
|
||||
{ .name = "unmount", .ret_type = 1, .nargs = 2,
|
||||
|
|
@ -723,15 +719,6 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case Umtx: {
|
||||
struct umtx umtx;
|
||||
if (get_struct(pid, (void *)args[sc->offset], &umtx,
|
||||
sizeof(umtx)) != -1)
|
||||
asprintf(&tmp, "{ 0x%lx }", (long)umtx.u_owner);
|
||||
else
|
||||
asprintf(&tmp, "0x%lx", args[sc->offset]);
|
||||
break;
|
||||
}
|
||||
case Timespec: {
|
||||
struct timespec ts;
|
||||
if (get_struct(pid, (void *)args[sc->offset], &ts,
|
||||
|
|
|
|||
Loading…
Reference in a new issue