diff options
author | jake <jake@FreeBSD.org> | 2003-04-02 08:02:27 +0000 |
---|---|---|
committer | jake <jake@FreeBSD.org> | 2003-04-02 08:02:27 +0000 |
commit | 02364d4f5d7a3cf2e1a838a47309ccf55842b608 (patch) | |
tree | 66041b2d50e003cbdefc4f9db88ca96c5465e56c /sys/kern | |
parent | 6470e002eb8ea4132df07e807cbe873b93299a2a (diff) | |
download | FreeBSD-src-02364d4f5d7a3cf2e1a838a47309ccf55842b608.zip FreeBSD-src-02364d4f5d7a3cf2e1a838a47309ccf55842b608.tar.gz |
- Make casuptr return the old value of the location we're trying to update,
and change the umtx code to expect this.
Reviewed by: jeff
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_umtx.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index a8dfe76..8c01669 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -46,6 +46,7 @@ _umtx_lock(struct thread *td, struct _umtx_lock_args *uap) struct umtx *umtx; struct thread *blocked; intptr_t owner; + intptr_t old; int error; error = 0; @@ -66,7 +67,7 @@ _umtx_lock(struct thread *td, struct _umtx_lock_args *uap) UMTX_UNOWNED, (intptr_t)td); /* The acquire succeeded. */ - if (owner == (intptr_t)td) { + if (owner == UMTX_UNOWNED) { error = 0; goto out; } @@ -86,14 +87,15 @@ _umtx_lock(struct thread *td, struct _umtx_lock_args *uap) * either some one else has acquired the lock or it has been * released. */ - owner = casuptr((intptr_t *)&umtx->u_owner, owner, owner | UMTX_CONTESTED); + old = casuptr((intptr_t *)&umtx->u_owner, owner, + owner | UMTX_CONTESTED); - /* The contested bit was set. */ - if (owner & UMTX_CONTESTED) + /* We set the contested bit. */ + if (old == owner) break; /* The address was invalid. */ - if (owner == -1) { + if (old == -1) { error = EFAULT; goto out; } @@ -182,6 +184,7 @@ _umtx_unlock(struct thread *td, struct _umtx_unlock_args *uap) struct umtx *umtx; intptr_t owner; intptr_t blocked; + intptr_t old; int error; error = 0; @@ -217,7 +220,7 @@ _umtx_unlock(struct thread *td, struct _umtx_unlock_args *uap) * If this failed someone modified the memory without going * through this api. */ - else if (owner != UMTX_UNOWNED) + else if (owner != (intptr_t)td) error = EINVAL; else error = 0; @@ -231,7 +234,7 @@ _umtx_unlock(struct thread *td, struct _umtx_unlock_args *uap) * CONTESTED bit was set. */ blocked = fuword(&umtx->u_blocked); - if (blocked == -1){ + if (blocked == -1) { error = EFAULT; goto out; } @@ -278,17 +281,17 @@ _umtx_unlock(struct thread *td, struct _umtx_unlock_args *uap) * Now directly assign this mutex to the first thread that was * blocked on it. */ - owner = casuptr((intptr_t *)&umtx->u_owner, owner, blocked); + old = casuptr((intptr_t *)&umtx->u_owner, owner, blocked); /* * This will only happen if someone modifies the lock without going * through this api. */ - if (owner != blocked) { + if (old != owner) { error = EINVAL; goto out; } - if (owner == -1) { + if (old == -1) { error = EFAULT; goto out; } |