Thread (2 messages) 2 messages, 2 authors, 2002-02-01

Re: [libc-alpha] Re: PATCH: Fix ll/sc for mips

From: Hiroyuki Machida <hidden>
Date: 2002-02-01 12:13:05

From: "H . J . Lu" <redacted>
Subject: Re: [libc-alpha] Re: PATCH: Fix ll/sc for mips
Date: Thu, 31 Jan 2002 23:00:50 -0800
On Fri, Feb 01, 2002 at 01:59:03PM +0900, Hiroyuki Machida wrote:
quoted
From: Kaz Kylheku <redacted>
Subject: Re: [libc-alpha] Re: PATCH: Fix ll/sc for mips
Date: Thu, 31 Jan 2002 20:02:25 -0800 (PST)
quoted
On Fri, 1 Feb 2002, Hiroyuki Machida wrote:
quoted
Please note that "sc" may fail even if nobody write the
variable. (See P.211 "8.4.2 Load-Linked/Sotre-Conditional" of "See 
MIPS RUN" for more detail.) 
So, after your patch applied, compare_and_swap() may fail, even if
*p is equal to oldval.
I can't think of anything that will break because of this, as long
as the compare_and_swap eventually succeeds on some subsequent trial.
If the atomic operation has to abort for some reason other than *p being
unequal to oldval, that should be cool.
I mean that this patch breaks the spec of compare_and_swap().
In most case, this patch may works as Kaz said. If this patch have
no side-effect to any application, it's ok to apply the patch. But
we can't know how to use compare_and_swap() in all aplications in a
whole world. So we have to follow the spec.  
Please note that the old compare_and_swap is broken. If you use
compare_and_swap to check if *p == oldval, my patch doesn't help
you. But if you use it to swap old/new, my patch works fine. But I
don't think you can use it check if *p == oldval since *p can change
at any time. It is the same as simply using "*p == oldval". I don't
see my patch should break any sane applications.


H.J.
I know the orinal compare_and_swap() is bad, and I believe  the
spec of compare_and_swap() as below;

compare_and_swap(p, oldval, newval)
{
	retval = 0;
	begin_atomic
	if (*p==oldval) {
	   *p = newval;
	   retval = 1;
	}
	end_atomic
	return retval;
}

So, compare_and_swap() should be ...

 __compare_and_swap (a0 long int oldval, long int newval)

a0: *p
a1: oldval
a2: newval
v0: return value

     .set	noreorder
retry:
     ll		v0, (a0)
     bne	v0, a1
      move	v0, zero
     move	v0, a2
     sc		v0, (a0)
     beqz	v0, retry
      nop
    j		ra



But, with your patch ...

     .set	noreorder

     ll		t0, (a0)
     bne	t0, a1
      move	v0, zero
     move	v0, a
     sc		v0, (a0)
    j		ra


In this way, compare_and_swap() was changed as

compare_and_swap(p, oldval, newval)
{
	retval = 0;
	begin_atomic
	if (*p==oldval) {

	   if "sc" was failed goto out;
	   
	   *p = newval;
	   retval = 1;
	}
out:
	end_atomic
	return retval;
}

---
Hiroyuki Machida
Sony Corp.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help