Implement casuword32, compare and set user integer, thank Marcel Moolenarr
who wrote the IA64 version of casuword32.
This commit is contained in:
parent
eb4bbba83a
commit
66e1c26dba
@ -313,6 +313,34 @@ copyin_fault:
|
||||
movq $EFAULT,%rax
|
||||
ret
|
||||
|
||||
/*
|
||||
* casuword32. Compare and set user integer. Returns -1 or the current value.
|
||||
* dst = %rdi, old = %rsi, new = %rdx
|
||||
*/
|
||||
ENTRY(casuword32)
|
||||
movq PCPU(CURPCB),%rcx
|
||||
movq $fusufault,PCB_ONFAULT(%rcx)
|
||||
|
||||
movq $VM_MAXUSER_ADDRESS-4,%rax
|
||||
cmpq %rax,%rdi /* verify address is valid */
|
||||
ja fusufault
|
||||
|
||||
movl %esi,%eax /* old */
|
||||
#ifdef SMP
|
||||
lock
|
||||
#endif
|
||||
cmpxchgl %edx,(%rdi) /* new = %edx */
|
||||
|
||||
/*
|
||||
* The old value is in %eax. If the store succeeded it will be the
|
||||
* value we expected (old) from before the store, otherwise it will
|
||||
* be the current value.
|
||||
*/
|
||||
|
||||
movq PCPU(CURPCB),%rcx
|
||||
movq $0,PCB_ONFAULT(%rcx)
|
||||
ret
|
||||
|
||||
/*
|
||||
* casuptr. Compare and set user pointer. Returns -1 or the current value.
|
||||
* dst = %rdi, old = %rsi, new = %rdx
|
||||
|
@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
|
||||
* Fetch an int from the user's address space.
|
||||
*/
|
||||
|
||||
ALTENTRY(casuword32)
|
||||
ENTRY(casuptr)
|
||||
#ifdef MULTIPROCESSOR
|
||||
/* XXX Probably not appropriate for non-Hydra SMPs */
|
||||
|
@ -1142,6 +1142,8 @@ fastmove_tail_fault:
|
||||
/*
|
||||
* casuptr. Compare and set user pointer. Returns -1 or the current value.
|
||||
*/
|
||||
|
||||
ALTENTRY(casuword32)
|
||||
ENTRY(casuptr)
|
||||
movl PCPU(CURPCB),%ecx
|
||||
movl $fusufault,PCB_ONFAULT(%ecx)
|
||||
|
@ -241,6 +241,56 @@ ENTRY(casuptr, 3)
|
||||
}
|
||||
END(casuptr)
|
||||
|
||||
/*
|
||||
* casuword32(int32_t *p, int32_t old, int32_t new)
|
||||
* Perform a 32-bit compare-exchange in user space.
|
||||
*/
|
||||
ENTRY(casuword32, 3)
|
||||
{ .mlx
|
||||
add r15=PC_CURTHREAD,r13
|
||||
movl r14=VM_MAX_ADDRESS
|
||||
;;
|
||||
}
|
||||
{ .mib
|
||||
ld8 r15=[r15] // r15 = curthread
|
||||
cmp.geu p6,p0=in0,r14
|
||||
(p6) br.dpnt.few 1f
|
||||
;;
|
||||
}
|
||||
{ .mlx
|
||||
add r15=TD_PCB,r15
|
||||
movl r14=fusufault
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8 r15=[r15] // r15 = PCB
|
||||
;;
|
||||
mov ar.ccv=in1
|
||||
add r15=PCB_ONFAULT,r15
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r15]=r14 // Set onfault
|
||||
;;
|
||||
cmpxchg4.rel ret0=[in0],in2,ar.ccv
|
||||
nop 0
|
||||
;;
|
||||
}
|
||||
{ .mfb
|
||||
st8.rel [r15]=r0 // Clear onfault
|
||||
nop 0
|
||||
br.ret.sptk rp
|
||||
;;
|
||||
}
|
||||
1:
|
||||
{ .mfb
|
||||
add ret0=-1,r0
|
||||
nop 0
|
||||
br.ret.sptk rp
|
||||
;;
|
||||
}
|
||||
END(casuword32)
|
||||
|
||||
/*
|
||||
* subyte(void *addr, int byte)
|
||||
* suword16(void *addr, int word)
|
||||
|
@ -322,6 +322,12 @@ fuword32(const void *addr)
|
||||
return ((int32_t)fuword(addr));
|
||||
}
|
||||
|
||||
int32_t
|
||||
casuword32(int32_t *base, int32_t oldval, int32_t newval)
|
||||
{
|
||||
return (casuptr(base, oldval, newval));
|
||||
}
|
||||
|
||||
intptr_t
|
||||
casuptr(intptr_t *addr, intptr_t old, intptr_t new)
|
||||
{
|
||||
|
@ -322,6 +322,12 @@ fuword32(const void *addr)
|
||||
return ((int32_t)fuword(addr));
|
||||
}
|
||||
|
||||
int32_t
|
||||
casuword32(int32_t *base, int32_t oldval, int32_t newval)
|
||||
{
|
||||
return (casuptr(base, oldval, newval));
|
||||
}
|
||||
|
||||
intptr_t
|
||||
casuptr(intptr_t *addr, intptr_t old, intptr_t new)
|
||||
{
|
||||
|
@ -402,7 +402,7 @@ fs_nofault_begin:
|
||||
.set susword, suword16
|
||||
.set suword, suword64
|
||||
|
||||
.globl casuptr, fuptr, suptr
|
||||
.globl casuword32, casuptr, fuptr, suptr
|
||||
.set casuptr, casuword64
|
||||
.set fuptr, fuword64
|
||||
.set suptr, suword64
|
||||
|
@ -203,7 +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);
|
||||
intptr_t casuptr(intptr_t *p, intptr_t old, intptr_t new);
|
||||
int32_t casuword32(int32_t *base, int32_t oldval, int32_t newval);
|
||||
intptr_t casuptr(intptr_t *p, intptr_t oldval, intptr_t newval);
|
||||
|
||||
void realitexpire(void *);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user