1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-04 09:09:56 +00:00

o Add keyword volatile for user mutex owner field.

o Fix type consistent problem by using type long for old
  umtx and wait channel.
o Rename casuptr to casuword.
This commit is contained in:
David Xu 2006-10-17 02:24:47 +00:00
parent b7e440b595
commit 5f641fc0fb
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=163449
11 changed files with 68 additions and 78 deletions

View File

@ -342,10 +342,10 @@ ENTRY(casuword32)
ret
/*
* casuptr. Compare and set user pointer. Returns -1 or the current value.
* casuword. Compare and set user word. Returns -1 or the current value.
* dst = %rdi, old = %rsi, new = %rdx
*/
ENTRY(casuptr)
ENTRY(casuword)
movq PCPU(CURPCB),%rcx
movq $fusufault,PCB_ONFAULT(%rcx)

View File

@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$");
*/
ENTRY_NP(casuword32)
ENTRY(casuptr)
ENTRY(casuword)
#ifdef MULTIPROCESSOR
/* XXX Probably not appropriate for non-Hydra SMPs */
stmfd sp!, {r0, r14}
@ -72,7 +72,7 @@ ENTRY(casuptr)
beq .Lfusupcbfault
#endif
stmfd sp!, {r4, r5}
adr r4, .Lcasuptrfault
adr r4, .Lcasuwordfault
str r4, [r3, #PCB_ONFAULT]
ldrt r5, [r0]
cmp r5, r1
@ -85,10 +85,10 @@ ENTRY(casuptr)
RET
/*
* Handle faults from casuptr. Clean up and return -1.
* Handle faults from casuword. Clean up and return -1.
*/
.Lcasuptrfault:
.Lcasuwordfault:
mov r0, #0x00000000
str r0, [r3, #PCB_ONFAULT]
mvn r0, #0x00000000

View File

@ -1140,11 +1140,11 @@ fastmove_tail_fault:
#endif /* I586_CPU && defined(DEV_NPX) */
/*
* casuptr. Compare and set user pointer. Returns -1 or the current value.
* casuword. Compare and set user word. Returns -1 or the current value.
*/
ALTENTRY(casuword32)
ENTRY(casuptr)
ENTRY(casuword)
movl PCPU(CURPCB),%ecx
movl $fusufault,PCB_ONFAULT(%ecx)
movl 4(%esp),%edx /* dst */

View File

@ -192,10 +192,10 @@ ENTRY(fusufault, 0)
END(fusufault)
/*
* casuptr(intptr_t *p, intptr_t old, intptr_t new)
* casuword(u_long *p, u_long old, u_long new)
* Perform a compare-exchange in user space.
*/
ENTRY(casuptr, 3)
ENTRY(casuword, 3)
{ .mlx
add r15=PC_CURTHREAD,r13
movl r14=VM_MAX_ADDRESS
@ -239,10 +239,10 @@ ENTRY(casuptr, 3)
br.ret.sptk rp
;;
}
END(casuptr)
END(casuword)
/*
* casuword32(int32_t *p, int32_t old, int32_t new)
* casuword32(uint32_t *p, uint32_t old, uint32_t new)
* Perform a 32-bit compare-exchange in user space.
*/
ENTRY(casuword32, 3)

View File

@ -522,11 +522,11 @@ umtx_key_release(struct umtx_key *key)
* Lock a umtx object.
*/
static int
_do_lock_umtx(struct thread *td, struct umtx *umtx, uintptr_t id, int timo)
_do_lock_umtx(struct thread *td, struct umtx *umtx, u_long id, int timo)
{
struct umtx_q *uq;
intptr_t owner;
intptr_t old;
u_long owner;
u_long old;
int error = 0;
uq = td->td_umtxq;
@ -539,7 +539,7 @@ _do_lock_umtx(struct thread *td, struct umtx *umtx, uintptr_t id, int timo)
/*
* Try the uncontested case. This should be done in userland.
*/
owner = casuptr((intptr_t *)&umtx->u_owner, UMTX_UNOWNED, id);
owner = casuword(&umtx->u_owner, UMTX_UNOWNED, id);
/* The acquire succeeded. */
if (owner == UMTX_UNOWNED)
@ -551,7 +551,7 @@ _do_lock_umtx(struct thread *td, struct umtx *umtx, uintptr_t id, int timo)
/* If no one owns it but it is contested try to acquire it. */
if (owner == UMTX_CONTESTED) {
owner = casuptr((intptr_t *)&umtx->u_owner,
owner = casuword(&umtx->u_owner,
UMTX_CONTESTED, id | UMTX_CONTESTED);
if (owner == UMTX_CONTESTED)
@ -588,8 +588,7 @@ _do_lock_umtx(struct thread *td, struct umtx *umtx, uintptr_t id, int timo)
* either some one else has acquired the lock or it has been
* released.
*/
old = casuptr((intptr_t *)&umtx->u_owner, owner,
owner | UMTX_CONTESTED);
old = casuword(&umtx->u_owner, owner, owner | UMTX_CONTESTED);
/* The address was invalid. */
if (old == -1) {
@ -620,7 +619,7 @@ _do_lock_umtx(struct thread *td, struct umtx *umtx, uintptr_t id, int timo)
* Lock a umtx object.
*/
static int
do_lock_umtx(struct thread *td, struct umtx *umtx, uintptr_t id,
do_lock_umtx(struct thread *td, struct umtx *umtx, u_long id,
struct timespec *timeout)
{
struct timespec ts, ts2, ts3;
@ -660,21 +659,18 @@ do_lock_umtx(struct thread *td, struct umtx *umtx, uintptr_t id,
* Unlock a umtx object.
*/
static int
do_unlock_umtx(struct thread *td, struct umtx *umtx, uintptr_t id)
do_unlock_umtx(struct thread *td, struct umtx *umtx, u_long id)
{
struct umtx_key key;
intptr_t owner;
intptr_t old;
u_long owner;
u_long old;
int error;
int count;
/*
* Make sure we own this mtx.
*
* XXX Need a {fu,su}ptr this is not correct on arch where
* sizeof(intptr_t) != sizeof(long).
*/
owner = fuword(&umtx->u_owner);
owner = fuword(__DEVOLATILE(u_long *, &umtx->u_owner));
if (owner == -1)
return (EFAULT);
@ -683,8 +679,7 @@ do_unlock_umtx(struct thread *td, struct umtx *umtx, uintptr_t id)
/* This should be done in userland */
if ((owner & UMTX_CONTESTED) == 0) {
old = casuptr((intptr_t *)&umtx->u_owner, owner,
UMTX_UNOWNED);
old = casuword(&umtx->u_owner, owner, UMTX_UNOWNED);
if (old == -1)
return (EFAULT);
if (old == owner)
@ -707,8 +702,8 @@ do_unlock_umtx(struct thread *td, struct umtx *umtx, uintptr_t id)
* there is zero or one thread only waiting for it.
* Otherwise, it must be marked as contested.
*/
old = casuptr((intptr_t *)&umtx->u_owner, owner,
count <= 1 ? UMTX_UNOWNED : UMTX_CONTESTED);
old = casuword(&umtx->u_owner, owner,
count <= 1 ? UMTX_UNOWNED : UMTX_CONTESTED);
umtxq_lock(&key);
umtxq_signal(&key,1);
umtxq_unbusy(&key);
@ -873,9 +868,6 @@ do_unlock_umtx32(struct thread *td, uint32_t *m, uint32_t id)
/*
* Make sure we own this mtx.
*
* XXX Need a {fu,su}ptr this is not correct on arch where
* sizeof(intptr_t) != sizeof(long).
*/
owner = fuword32(m);
if (owner == -1)
@ -928,13 +920,13 @@ do_unlock_umtx32(struct thread *td, uint32_t *m, uint32_t id)
* Fetch and compare value, sleep on the address if value is not changed.
*/
static int
do_wait(struct thread *td, void *addr, uintptr_t id,
do_wait(struct thread *td, void *addr, u_long id,
struct timespec *timeout, int compat32)
{
struct umtx_q *uq;
struct timespec ts, ts2, ts3;
struct timeval tv;
uintptr_t tmp;
u_long tmp;
int error = 0;
uq = td->td_umtxq;
@ -1132,7 +1124,7 @@ do_unlock_normal(struct thread *td, struct umutex *m, uint32_t flags)
/*
* Make sure we own this mtx.
*/
owner = fuword32(&m->m_owner);
owner = fuword32(__DEVOLATILE(uint32_t *, &m->m_owner));
if (owner == -1)
return (EFAULT);
@ -1729,7 +1721,7 @@ do_unlock_pi(struct thread *td, struct umutex *m, uint32_t flags)
/*
* Make sure we own this mtx.
*/
owner = fuword32(&m->m_owner);
owner = fuword32(__DEVOLATILE(uint32_t *, &m->m_owner));
if (owner == -1)
return (EFAULT);
@ -1945,7 +1937,7 @@ do_unlock_pp(struct thread *td, struct umutex *m, uint32_t flags)
/*
* Make sure we own this mtx.
*/
owner = fuword32(&m->m_owner);
owner = fuword32(__DEVOLATILE(uint32_t *, &m->m_owner));
if (owner == -1)
return (EFAULT);
@ -1977,7 +1969,8 @@ do_unlock_pp(struct thread *td, struct umutex *m, uint32_t flags)
* to lock the mutex, it is necessary because thread priority
* has to be adjusted for such mutex.
*/
error = suword32(&m->m_owner, UMUTEX_CONTESTED);
error = suword32(__DEVOLATILE(uint32_t *, &m->m_owner),
UMUTEX_CONTESTED);
umtxq_lock(&key);
if (error == 0)
@ -2040,7 +2033,8 @@ do_set_ceiling(struct thread *td, struct umutex *m, uint32_t ceiling,
if (owner == UMUTEX_CONTESTED) {
suword32(&m->m_ceilings[0], ceiling);
suword32(&m->m_owner, UMUTEX_CONTESTED);
suword32(__DEVOLATILE(uint32_t *, &m->m_owner),
UMUTEX_CONTESTED);
error = 0;
break;
}

View File

@ -796,7 +796,7 @@
u_int length); }
453 AUE_AUDITCTL STD { int auditctl(char *path); }
454 AUE_NULL STD { int _umtx_op(void *obj, int op, \
uintptr_t val, void *uaddr1, void *uaddr2); }
u_long val, void *uaddr1, void *uaddr2); }
455 AUE_NULL STD { int thr_new(struct thr_param *param, \
int param_size); }
456 AUE_NULL STD { int sigqueue(pid_t pid, int signum, void *value); }

View File

@ -322,23 +322,23 @@ fuword32(const void *addr)
return ((int32_t)fuword(addr));
}
int32_t
casuword32(int32_t *base, int32_t oldval, int32_t newval)
uint32_t
casuword32(volatile uint32_t *base, uint32_t oldval, uint32_t newval)
{
return (casuptr(base, oldval, newval));
return (casuword(base, oldval, newval));
}
intptr_t
casuptr(intptr_t *addr, intptr_t old, intptr_t new)
u_long
casuword(volatile u_long *addr, u_long old, u_long new)
{
struct thread *td;
pmap_t pm;
faultbuf env;
intptr_t *p, val;
u_long *p, val;
td = PCPU_GET(curthread);
pm = &td->td_proc->p_vmspace->vm_pmap;
p = (intptr_t *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
p = (u_long *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);

View File

@ -322,23 +322,23 @@ fuword32(const void *addr)
return ((int32_t)fuword(addr));
}
int32_t
casuword32(int32_t *base, int32_t oldval, int32_t newval)
uint32_t
casuword32(volatile uint32_t *base, uint32_t oldval, uint32_t newval)
{
return (casuptr(base, oldval, newval));
return (casuword(base, oldval, newval));
}
intptr_t
casuptr(intptr_t *addr, intptr_t old, intptr_t new)
u_long
casuword(volatile u_long *addr, u_long old, u_long new)
{
struct thread *td;
pmap_t pm;
faultbuf env;
intptr_t *p, val;
u_long *p, val;
td = PCPU_GET(curthread);
pm = &td->td_proc->p_vmspace->vm_pmap;
p = (intptr_t *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
p = (u_long *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);

View File

@ -402,8 +402,8 @@ fs_nofault_begin:
.set susword, suword16
.set suword, suword64
.globl casuword32, casuptr, fuptr, suptr
.set casuptr, casuword64
.globl casuword32, casuword, fuptr, suptr
.set casuword, casuword64
.set fuptr, fuword64
.set suptr, suword64

View File

@ -203,8 +203,8 @@ int suword(void *base, long word);
int suword16(void *base, int word);
int suword32(void *base, int32_t word);
int suword64(void *base, int64_t word);
int32_t casuword32(int32_t *base, int32_t oldval, int32_t newval);
intptr_t casuptr(intptr_t *p, intptr_t oldval, intptr_t newval);
uint32_t casuword32(volatile uint32_t *base, uint32_t oldval, uint32_t newval);
u_long casuword(volatile u_long *p, u_long oldval, u_long newval);
void realitexpire(void *);

View File

@ -41,7 +41,7 @@
#define UMTX_CONTESTED LONG_MIN
struct umtx {
uintptr_t u_owner; /* Owner of the mutex. */
volatile u_long u_owner; /* Owner of the mutex. */
};
#define USYNC_PROCESS_SHARED 0x0001 /* Process shared sync objs */
@ -53,7 +53,7 @@ struct umtx {
#define UMUTEX_PRIO_INHERIT 0x0004 /* Priority inherited mutex */
#define UMUTEX_PRIO_PROTECT 0x0008 /* Priority protect mutex */
struct umutex {
__lwpid_t m_owner; /* Owner of the mutex */
volatile __lwpid_t m_owner; /* Owner of the mutex */
uint32_t m_flags; /* Flags of the mutex */
uint32_t m_ceilings[2]; /* Priority protect ceiling */
uint32_t m_spare[4]; /* Spare space */
@ -72,11 +72,7 @@ struct umutex {
#ifndef _KERNEL
/*
* System call for userland mutex operations.
* Bug: assume sizeof(uintptr_t) == sizeof(long)
*/
int _umtx_op(void *obj, int op, uintptr_t val, void *uaddr, void *uaddr2);
int _umtx_op(void *obj, int op, u_long val, void *uaddr, void *uaddr2);
/*
* Old (deprecated) userland mutex system calls.
@ -94,33 +90,33 @@ umtx_init(struct umtx *umtx)
umtx->u_owner = UMTX_UNOWNED;
}
static __inline uintptr_t
static __inline u_long
umtx_owner(struct umtx *umtx)
{
return (umtx->u_owner & ~LONG_MIN);
}
static __inline int
umtx_lock(struct umtx *umtx, uintptr_t id)
umtx_lock(struct umtx *umtx, u_long id)
{
if (atomic_cmpset_acq_ptr(&umtx->u_owner, UMTX_UNOWNED, id) == 0)
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, uintptr_t id)
umtx_trylock(struct umtx *umtx, u_long id)
{
if (atomic_cmpset_acq_ptr(&umtx->u_owner, UMTX_UNOWNED, id) == 0)
if (atomic_cmpset_acq_long(&umtx->u_owner, UMTX_UNOWNED, id) == 0)
return (EBUSY);
return (0);
}
static __inline int
umtx_timedlock(struct umtx *umtx, uintptr_t id, const struct timespec *timeout)
umtx_timedlock(struct umtx *umtx, u_long id, const struct timespec *timeout)
{
if (atomic_cmpset_acq_ptr(&umtx->u_owner, UMTX_UNOWNED, id) == 0)
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);
@ -128,16 +124,16 @@ umtx_timedlock(struct umtx *umtx, uintptr_t id, const struct timespec *timeout)
}
static __inline int
umtx_unlock(struct umtx *umtx, uintptr_t id)
umtx_unlock(struct umtx *umtx, u_long id)
{
if (atomic_cmpset_rel_ptr(&umtx->u_owner, id, UMTX_UNOWNED) == 0)
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(long *p, long val, const struct timespec *timeout)
umtx_wait(u_long *p, long val, const struct timespec *timeout)
{
if (_umtx_op(p, UMTX_OP_WAIT, val, 0,
__DECONST(void *, timeout)) == -1)
@ -147,7 +143,7 @@ umtx_wait(long *p, long val, const struct timespec *timeout)
/* Wake threads waiting on a user address. */
static __inline int
umtx_wake(long *p, int nr_wakeup)
umtx_wake(u_long *p, int nr_wakeup)
{
if (_umtx_op(p, UMTX_OP_WAKE, nr_wakeup, 0, 0) == -1)
return (errno);