- Define a new md function 'casuptr'. This atomically compares and sets

a pointer that is in user space.  It will be used as the basic primitive
   for a kernel supported user space lock implementation.
 - Implement this function in x86's support.s
 - Provide stubs that return -1 in all other architectures.  Implementations
   will follow along shortly.

Reviewed by:	jake
This commit is contained in:
Jeff Roberson 2003-04-01 00:18:55 +00:00
parent fb8aaa76c7
commit b8db34d280
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=112898
11 changed files with 146 additions and 0 deletions

View File

@ -2324,3 +2324,9 @@ cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz)
pcpu->pc_idlepcb.apcb_ptbr = thread0.td_pcb->pcb_hw.apcb_ptbr;
pcpu->pc_current_asngen = 1;
}
intptr_t
casuptr(intptr_t *p, intptr_t old, intptr_t new)
{
return (-1);
}

View File

@ -1172,6 +1172,37 @@ fastmove_tail_fault:
ret
#endif /* I586_CPU && defined(DEV_NPX) */
/*
* casuptr. Compare and set user pointer. Returns -1 or the current value.
*/
ENTRY(casuptr)
movl PCPU(CURPCB),%ecx
movl $fusufault,PCB_ONFAULT(%ecx)
movl 4(%esp),%edx /* dst */
movl 8(%esp),%eax /* old */
movl 12(%esp),%ecx /* new */
cmpl $VM_MAXUSER_ADDRESS-4,%edx /* verify address is valid */
ja fusufault
#if defined(SMP)
lock cmpxchgl %ecx, (%edx) /* Compare and set. */
#else /* !SMP */
cmpxchgl %ecx, (%edx)
#endif /* !SMP */
/*
* We store the current value regardless of the success of the
* cmpxchg. Calling code checks for new == return to determine
* success.
*/
movl (%edx), %eax
movl PCPU(CURPCB),%ecx
movl $fusufault,PCB_ONFAULT(%ecx)
movl $0,PCB_ONFAULT(%ecx)
ret
/*
* fu{byte,sword,word} - MP SAFE
*

View File

@ -1172,6 +1172,37 @@ fastmove_tail_fault:
ret
#endif /* I586_CPU && defined(DEV_NPX) */
/*
* casuptr. Compare and set user pointer. Returns -1 or the current value.
*/
ENTRY(casuptr)
movl PCPU(CURPCB),%ecx
movl $fusufault,PCB_ONFAULT(%ecx)
movl 4(%esp),%edx /* dst */
movl 8(%esp),%eax /* old */
movl 12(%esp),%ecx /* new */
cmpl $VM_MAXUSER_ADDRESS-4,%edx /* verify address is valid */
ja fusufault
#if defined(SMP)
lock cmpxchgl %ecx, (%edx) /* Compare and set. */
#else /* !SMP */
cmpxchgl %ecx, (%edx)
#endif /* !SMP */
/*
* We store the current value regardless of the success of the
* cmpxchg. Calling code checks for new == return to determine
* success.
*/
movl (%edx), %eax
movl PCPU(CURPCB),%ecx
movl $fusufault,PCB_ONFAULT(%ecx)
movl $0,PCB_ONFAULT(%ecx)
ret
/*
* fu{byte,sword,word} - MP SAFE
*

View File

@ -1172,6 +1172,37 @@ fastmove_tail_fault:
ret
#endif /* I586_CPU && defined(DEV_NPX) */
/*
* casuptr. Compare and set user pointer. Returns -1 or the current value.
*/
ENTRY(casuptr)
movl PCPU(CURPCB),%ecx
movl $fusufault,PCB_ONFAULT(%ecx)
movl 4(%esp),%edx /* dst */
movl 8(%esp),%eax /* old */
movl 12(%esp),%ecx /* new */
cmpl $VM_MAXUSER_ADDRESS-4,%edx /* verify address is valid */
ja fusufault
#if defined(SMP)
lock cmpxchgl %ecx, (%edx) /* Compare and set. */
#else /* !SMP */
cmpxchgl %ecx, (%edx)
#endif /* !SMP */
/*
* We store the current value regardless of the success of the
* cmpxchg. Calling code checks for new == return to determine
* success.
*/
movl (%edx), %eax
movl PCPU(CURPCB),%ecx
movl $fusufault,PCB_ONFAULT(%ecx)
movl $0,PCB_ONFAULT(%ecx)
ret
/*
* fu{byte,sword,word} - MP SAFE
*

View File

@ -1444,3 +1444,10 @@ ia64_rse_previous_frame(u_int64_t *bsp, int size)
return bsp - size - rnats;
}
intptr_t
casuptr(intptr_t *p, intptr_t old, intptr_t new)
{
return (-1);
}

View File

@ -2803,3 +2803,11 @@ outb(u_int port, u_char data)
}
#endif /* DDB */
intptr_t
casuptr(intptr_t *p, intptr_t old, intptr_t new)
{
return (-1);
}

View File

@ -2803,3 +2803,11 @@ outb(u_int port, u_char data)
}
#endif /* DDB */
intptr_t
casuptr(intptr_t *p, intptr_t old, intptr_t new)
{
return (-1);
}

View File

@ -752,3 +752,11 @@ kcopy(const void *src, void *dst, size_t len)
td->td_pcb->pcb_onfault = oldfault;
return (0);
}
intptr_t
casuptr(intptr_t *p, intptr_t old, intptr_t new)
{
return (-1);
}

View File

@ -752,3 +752,11 @@ kcopy(const void *src, void *dst, size_t len)
td->td_pcb->pcb_onfault = oldfault;
return (0);
}
intptr_t
casuptr(intptr_t *p, intptr_t old, intptr_t new)
{
return (-1);
}

View File

@ -703,3 +703,10 @@ set_fpregs(struct thread *td, struct fpreg *fpregs)
tf->tf_gsr = fpregs->fr_gsr;
return (0);
}
intptr_t
casuptr(intptr_t *p, intptr_t old, intptr_t new)
{
return (-1);
}

View File

@ -197,6 +197,7 @@ 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);
void realitexpire(void *);