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:
parent
b7e440b595
commit
5f641fc0fb
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=163449
@ -342,10 +342,10 @@ ENTRY(casuword32)
|
|||||||
ret
|
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
|
* dst = %rdi, old = %rsi, new = %rdx
|
||||||
*/
|
*/
|
||||||
ENTRY(casuptr)
|
ENTRY(casuword)
|
||||||
movq PCPU(CURPCB),%rcx
|
movq PCPU(CURPCB),%rcx
|
||||||
movq $fusufault,PCB_ONFAULT(%rcx)
|
movq $fusufault,PCB_ONFAULT(%rcx)
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
ENTRY_NP(casuword32)
|
ENTRY_NP(casuword32)
|
||||||
ENTRY(casuptr)
|
ENTRY(casuword)
|
||||||
#ifdef MULTIPROCESSOR
|
#ifdef MULTIPROCESSOR
|
||||||
/* XXX Probably not appropriate for non-Hydra SMPs */
|
/* XXX Probably not appropriate for non-Hydra SMPs */
|
||||||
stmfd sp!, {r0, r14}
|
stmfd sp!, {r0, r14}
|
||||||
@ -72,7 +72,7 @@ ENTRY(casuptr)
|
|||||||
beq .Lfusupcbfault
|
beq .Lfusupcbfault
|
||||||
#endif
|
#endif
|
||||||
stmfd sp!, {r4, r5}
|
stmfd sp!, {r4, r5}
|
||||||
adr r4, .Lcasuptrfault
|
adr r4, .Lcasuwordfault
|
||||||
str r4, [r3, #PCB_ONFAULT]
|
str r4, [r3, #PCB_ONFAULT]
|
||||||
ldrt r5, [r0]
|
ldrt r5, [r0]
|
||||||
cmp r5, r1
|
cmp r5, r1
|
||||||
@ -85,10 +85,10 @@ ENTRY(casuptr)
|
|||||||
RET
|
RET
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle faults from casuptr. Clean up and return -1.
|
* Handle faults from casuword. Clean up and return -1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.Lcasuptrfault:
|
.Lcasuwordfault:
|
||||||
mov r0, #0x00000000
|
mov r0, #0x00000000
|
||||||
str r0, [r3, #PCB_ONFAULT]
|
str r0, [r3, #PCB_ONFAULT]
|
||||||
mvn r0, #0x00000000
|
mvn r0, #0x00000000
|
||||||
|
@ -1140,11 +1140,11 @@ fastmove_tail_fault:
|
|||||||
#endif /* I586_CPU && defined(DEV_NPX) */
|
#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)
|
ALTENTRY(casuword32)
|
||||||
ENTRY(casuptr)
|
ENTRY(casuword)
|
||||||
movl PCPU(CURPCB),%ecx
|
movl PCPU(CURPCB),%ecx
|
||||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||||
movl 4(%esp),%edx /* dst */
|
movl 4(%esp),%edx /* dst */
|
||||||
|
@ -192,10 +192,10 @@ ENTRY(fusufault, 0)
|
|||||||
END(fusufault)
|
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.
|
* Perform a compare-exchange in user space.
|
||||||
*/
|
*/
|
||||||
ENTRY(casuptr, 3)
|
ENTRY(casuword, 3)
|
||||||
{ .mlx
|
{ .mlx
|
||||||
add r15=PC_CURTHREAD,r13
|
add r15=PC_CURTHREAD,r13
|
||||||
movl r14=VM_MAX_ADDRESS
|
movl r14=VM_MAX_ADDRESS
|
||||||
@ -239,10 +239,10 @@ ENTRY(casuptr, 3)
|
|||||||
br.ret.sptk rp
|
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.
|
* Perform a 32-bit compare-exchange in user space.
|
||||||
*/
|
*/
|
||||||
ENTRY(casuword32, 3)
|
ENTRY(casuword32, 3)
|
||||||
|
@ -522,11 +522,11 @@ umtx_key_release(struct umtx_key *key)
|
|||||||
* Lock a umtx object.
|
* Lock a umtx object.
|
||||||
*/
|
*/
|
||||||
static int
|
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;
|
struct umtx_q *uq;
|
||||||
intptr_t owner;
|
u_long owner;
|
||||||
intptr_t old;
|
u_long old;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
uq = td->td_umtxq;
|
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.
|
* 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. */
|
/* The acquire succeeded. */
|
||||||
if (owner == UMTX_UNOWNED)
|
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 no one owns it but it is contested try to acquire it. */
|
||||||
if (owner == UMTX_CONTESTED) {
|
if (owner == UMTX_CONTESTED) {
|
||||||
owner = casuptr((intptr_t *)&umtx->u_owner,
|
owner = casuword(&umtx->u_owner,
|
||||||
UMTX_CONTESTED, id | UMTX_CONTESTED);
|
UMTX_CONTESTED, id | UMTX_CONTESTED);
|
||||||
|
|
||||||
if (owner == 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
|
* either some one else has acquired the lock or it has been
|
||||||
* released.
|
* released.
|
||||||
*/
|
*/
|
||||||
old = casuptr((intptr_t *)&umtx->u_owner, owner,
|
old = casuword(&umtx->u_owner, owner, owner | UMTX_CONTESTED);
|
||||||
owner | UMTX_CONTESTED);
|
|
||||||
|
|
||||||
/* The address was invalid. */
|
/* The address was invalid. */
|
||||||
if (old == -1) {
|
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.
|
* Lock a umtx object.
|
||||||
*/
|
*/
|
||||||
static int
|
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 *timeout)
|
||||||
{
|
{
|
||||||
struct timespec ts, ts2, ts3;
|
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.
|
* Unlock a umtx object.
|
||||||
*/
|
*/
|
||||||
static int
|
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;
|
struct umtx_key key;
|
||||||
intptr_t owner;
|
u_long owner;
|
||||||
intptr_t old;
|
u_long old;
|
||||||
int error;
|
int error;
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure we own this mtx.
|
* 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)
|
if (owner == -1)
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
|
|
||||||
@ -683,8 +679,7 @@ do_unlock_umtx(struct thread *td, struct umtx *umtx, uintptr_t id)
|
|||||||
|
|
||||||
/* This should be done in userland */
|
/* This should be done in userland */
|
||||||
if ((owner & UMTX_CONTESTED) == 0) {
|
if ((owner & UMTX_CONTESTED) == 0) {
|
||||||
old = casuptr((intptr_t *)&umtx->u_owner, owner,
|
old = casuword(&umtx->u_owner, owner, UMTX_UNOWNED);
|
||||||
UMTX_UNOWNED);
|
|
||||||
if (old == -1)
|
if (old == -1)
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
if (old == owner)
|
if (old == owner)
|
||||||
@ -707,7 +702,7 @@ do_unlock_umtx(struct thread *td, struct umtx *umtx, uintptr_t id)
|
|||||||
* there is zero or one thread only waiting for it.
|
* there is zero or one thread only waiting for it.
|
||||||
* Otherwise, it must be marked as contested.
|
* Otherwise, it must be marked as contested.
|
||||||
*/
|
*/
|
||||||
old = casuptr((intptr_t *)&umtx->u_owner, owner,
|
old = casuword(&umtx->u_owner, owner,
|
||||||
count <= 1 ? UMTX_UNOWNED : UMTX_CONTESTED);
|
count <= 1 ? UMTX_UNOWNED : UMTX_CONTESTED);
|
||||||
umtxq_lock(&key);
|
umtxq_lock(&key);
|
||||||
umtxq_signal(&key,1);
|
umtxq_signal(&key,1);
|
||||||
@ -873,9 +868,6 @@ do_unlock_umtx32(struct thread *td, uint32_t *m, uint32_t id)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure we own this mtx.
|
* 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);
|
owner = fuword32(m);
|
||||||
if (owner == -1)
|
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.
|
* Fetch and compare value, sleep on the address if value is not changed.
|
||||||
*/
|
*/
|
||||||
static int
|
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 timespec *timeout, int compat32)
|
||||||
{
|
{
|
||||||
struct umtx_q *uq;
|
struct umtx_q *uq;
|
||||||
struct timespec ts, ts2, ts3;
|
struct timespec ts, ts2, ts3;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
uintptr_t tmp;
|
u_long tmp;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
uq = td->td_umtxq;
|
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.
|
* Make sure we own this mtx.
|
||||||
*/
|
*/
|
||||||
owner = fuword32(&m->m_owner);
|
owner = fuword32(__DEVOLATILE(uint32_t *, &m->m_owner));
|
||||||
if (owner == -1)
|
if (owner == -1)
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
|
|
||||||
@ -1729,7 +1721,7 @@ do_unlock_pi(struct thread *td, struct umutex *m, uint32_t flags)
|
|||||||
/*
|
/*
|
||||||
* Make sure we own this mtx.
|
* Make sure we own this mtx.
|
||||||
*/
|
*/
|
||||||
owner = fuword32(&m->m_owner);
|
owner = fuword32(__DEVOLATILE(uint32_t *, &m->m_owner));
|
||||||
if (owner == -1)
|
if (owner == -1)
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
|
|
||||||
@ -1945,7 +1937,7 @@ do_unlock_pp(struct thread *td, struct umutex *m, uint32_t flags)
|
|||||||
/*
|
/*
|
||||||
* Make sure we own this mtx.
|
* Make sure we own this mtx.
|
||||||
*/
|
*/
|
||||||
owner = fuword32(&m->m_owner);
|
owner = fuword32(__DEVOLATILE(uint32_t *, &m->m_owner));
|
||||||
if (owner == -1)
|
if (owner == -1)
|
||||||
return (EFAULT);
|
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
|
* to lock the mutex, it is necessary because thread priority
|
||||||
* has to be adjusted for such mutex.
|
* 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);
|
umtxq_lock(&key);
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
@ -2040,7 +2033,8 @@ do_set_ceiling(struct thread *td, struct umutex *m, uint32_t ceiling,
|
|||||||
|
|
||||||
if (owner == UMUTEX_CONTESTED) {
|
if (owner == UMUTEX_CONTESTED) {
|
||||||
suword32(&m->m_ceilings[0], ceiling);
|
suword32(&m->m_ceilings[0], ceiling);
|
||||||
suword32(&m->m_owner, UMUTEX_CONTESTED);
|
suword32(__DEVOLATILE(uint32_t *, &m->m_owner),
|
||||||
|
UMUTEX_CONTESTED);
|
||||||
error = 0;
|
error = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -796,7 +796,7 @@
|
|||||||
u_int length); }
|
u_int length); }
|
||||||
453 AUE_AUDITCTL STD { int auditctl(char *path); }
|
453 AUE_AUDITCTL STD { int auditctl(char *path); }
|
||||||
454 AUE_NULL STD { int _umtx_op(void *obj, int op, \
|
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, \
|
455 AUE_NULL STD { int thr_new(struct thr_param *param, \
|
||||||
int param_size); }
|
int param_size); }
|
||||||
456 AUE_NULL STD { int sigqueue(pid_t pid, int signum, void *value); }
|
456 AUE_NULL STD { int sigqueue(pid_t pid, int signum, void *value); }
|
||||||
|
@ -322,23 +322,23 @@ fuword32(const void *addr)
|
|||||||
return ((int32_t)fuword(addr));
|
return ((int32_t)fuword(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
uint32_t
|
||||||
casuword32(int32_t *base, int32_t oldval, int32_t newval)
|
casuword32(volatile uint32_t *base, uint32_t oldval, uint32_t newval)
|
||||||
{
|
{
|
||||||
return (casuptr(base, oldval, newval));
|
return (casuword(base, oldval, newval));
|
||||||
}
|
}
|
||||||
|
|
||||||
intptr_t
|
u_long
|
||||||
casuptr(intptr_t *addr, intptr_t old, intptr_t new)
|
casuword(volatile u_long *addr, u_long old, u_long new)
|
||||||
{
|
{
|
||||||
struct thread *td;
|
struct thread *td;
|
||||||
pmap_t pm;
|
pmap_t pm;
|
||||||
faultbuf env;
|
faultbuf env;
|
||||||
intptr_t *p, val;
|
u_long *p, val;
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = PCPU_GET(curthread);
|
||||||
pm = &td->td_proc->p_vmspace->vm_pmap;
|
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]);
|
set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
|
||||||
|
|
||||||
|
@ -322,23 +322,23 @@ fuword32(const void *addr)
|
|||||||
return ((int32_t)fuword(addr));
|
return ((int32_t)fuword(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
uint32_t
|
||||||
casuword32(int32_t *base, int32_t oldval, int32_t newval)
|
casuword32(volatile uint32_t *base, uint32_t oldval, uint32_t newval)
|
||||||
{
|
{
|
||||||
return (casuptr(base, oldval, newval));
|
return (casuword(base, oldval, newval));
|
||||||
}
|
}
|
||||||
|
|
||||||
intptr_t
|
u_long
|
||||||
casuptr(intptr_t *addr, intptr_t old, intptr_t new)
|
casuword(volatile u_long *addr, u_long old, u_long new)
|
||||||
{
|
{
|
||||||
struct thread *td;
|
struct thread *td;
|
||||||
pmap_t pm;
|
pmap_t pm;
|
||||||
faultbuf env;
|
faultbuf env;
|
||||||
intptr_t *p, val;
|
u_long *p, val;
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = PCPU_GET(curthread);
|
||||||
pm = &td->td_proc->p_vmspace->vm_pmap;
|
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]);
|
set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
|
||||||
|
|
||||||
|
@ -402,8 +402,8 @@ fs_nofault_begin:
|
|||||||
.set susword, suword16
|
.set susword, suword16
|
||||||
.set suword, suword64
|
.set suword, suword64
|
||||||
|
|
||||||
.globl casuword32, casuptr, fuptr, suptr
|
.globl casuword32, casuword, fuptr, suptr
|
||||||
.set casuptr, casuword64
|
.set casuword, casuword64
|
||||||
.set fuptr, fuword64
|
.set fuptr, fuword64
|
||||||
.set suptr, suword64
|
.set suptr, suword64
|
||||||
|
|
||||||
|
@ -203,8 +203,8 @@ int suword(void *base, long word);
|
|||||||
int suword16(void *base, int word);
|
int suword16(void *base, int word);
|
||||||
int suword32(void *base, int32_t word);
|
int suword32(void *base, int32_t word);
|
||||||
int suword64(void *base, int64_t word);
|
int suword64(void *base, int64_t word);
|
||||||
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);
|
||||||
intptr_t casuptr(intptr_t *p, intptr_t oldval, intptr_t newval);
|
u_long casuword(volatile u_long *p, u_long oldval, u_long newval);
|
||||||
|
|
||||||
void realitexpire(void *);
|
void realitexpire(void *);
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
#define UMTX_CONTESTED LONG_MIN
|
#define UMTX_CONTESTED LONG_MIN
|
||||||
|
|
||||||
struct umtx {
|
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 */
|
#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_INHERIT 0x0004 /* Priority inherited mutex */
|
||||||
#define UMUTEX_PRIO_PROTECT 0x0008 /* Priority protect mutex */
|
#define UMUTEX_PRIO_PROTECT 0x0008 /* Priority protect mutex */
|
||||||
struct umutex {
|
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_flags; /* Flags of the mutex */
|
||||||
uint32_t m_ceilings[2]; /* Priority protect ceiling */
|
uint32_t m_ceilings[2]; /* Priority protect ceiling */
|
||||||
uint32_t m_spare[4]; /* Spare space */
|
uint32_t m_spare[4]; /* Spare space */
|
||||||
@ -72,11 +72,7 @@ struct umutex {
|
|||||||
|
|
||||||
#ifndef _KERNEL
|
#ifndef _KERNEL
|
||||||
|
|
||||||
/*
|
int _umtx_op(void *obj, int op, u_long val, void *uaddr, void *uaddr2);
|
||||||
* 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);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Old (deprecated) userland mutex system calls.
|
* Old (deprecated) userland mutex system calls.
|
||||||
@ -94,33 +90,33 @@ umtx_init(struct umtx *umtx)
|
|||||||
umtx->u_owner = UMTX_UNOWNED;
|
umtx->u_owner = UMTX_UNOWNED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline uintptr_t
|
static __inline u_long
|
||||||
umtx_owner(struct umtx *umtx)
|
umtx_owner(struct umtx *umtx)
|
||||||
{
|
{
|
||||||
return (umtx->u_owner & ~LONG_MIN);
|
return (umtx->u_owner & ~LONG_MIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline int
|
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)
|
if (_umtx_lock(umtx) == -1)
|
||||||
return (errno);
|
return (errno);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline int
|
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 (EBUSY);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline int
|
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,
|
if (_umtx_op(umtx, UMTX_OP_LOCK, id, 0,
|
||||||
__DECONST(void *, timeout)) == -1)
|
__DECONST(void *, timeout)) == -1)
|
||||||
return (errno);
|
return (errno);
|
||||||
@ -128,16 +124,16 @@ umtx_timedlock(struct umtx *umtx, uintptr_t id, const struct timespec *timeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static __inline int
|
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)
|
if (_umtx_unlock(umtx) == -1)
|
||||||
return (errno);
|
return (errno);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline int
|
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,
|
if (_umtx_op(p, UMTX_OP_WAIT, val, 0,
|
||||||
__DECONST(void *, timeout)) == -1)
|
__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. */
|
/* Wake threads waiting on a user address. */
|
||||||
static __inline int
|
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)
|
if (_umtx_op(p, UMTX_OP_WAKE, nr_wakeup, 0, 0) == -1)
|
||||||
return (errno);
|
return (errno);
|
||||||
|
Loading…
Reference in New Issue
Block a user