linux-mips
[Top] [All Lists]

Re: PATCH: Fix ll/sc for mips

To: hjl@lucon.org
Subject: Re: PATCH: Fix ll/sc for mips
From: Hiroyuki Machida <machida@sm.sony.co.jp>
Date: Fri, 01 Feb 2002 12:35:23 +0900 (JST)
Cc: macro@ds2.pg.gda.pl, libc-alpha@sources.redhat.com, linux-mips@oss.sgi.com
In-reply-to: <20020131144100.A24634@lucon.org>
References: <20020131123547.A22759@lucon.org> <Pine.GSO.3.96.1020131230104.9069A-100000@delta.ds2.pg.gda.pl> <20020131144100.A24634@lucon.org>
Sender: owner-linux-mips@oss.sgi.com

From: "H . J . Lu" <hjl@lucon.org>
Subject: Re: PATCH: Fix ll/sc for mips
Date: Thu, 31 Jan 2002 14:41:00 -0800

> On Thu, Jan 31, 2002 at 11:17:21PM +0100, Maciej W. Rozycki wrote:
> > On Thu, 31 Jan 2002, H . J . Lu wrote:
> > 
> > >   (__compare_and_swap): Return 0 when failed to compare or swap.
> > [...]
> > >   * sysdeps/mips/atomicity.h (compare_and_swap): Return 0 when
> > >   failed to compare or swap.
> > 
> >  Looking at the i486 implementation these are not expected to fail. 
> > Unless I am missing something... 
> 
> Why can't it fail?
> 
> static inline char
> __attribute__ ((unused))
> compare_and_swap (volatile long int *p, long int oldval, long int newval)
> {
>   char ret;
>   long int readval;
> 
>   __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
>                         : "=q" (ret), "=m" (*p), "=a" (readval)
>                         : "r" (newval), "1" (*p), "a" (oldval));
>   return ret;
> }
> 
> It will fail if *p is not same as oldval.


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.


> > 
> > >   * sysdeps/unix/sysv/linux/mips/sys/tas.h (_test_and_set): Fill
> > >   the delay slot.
> > 
> >  What's the difference?  The code looks the same after changes.  Also you
> > forgot to indent instructions in delay slots, which worsens readability. 
> 
> Are we looking at the same file? Here is the patched version:
> 
> _EXTERN_INLINE int
> _test_and_set (int *p, int v) __THROW 
> {
>   int r, t;
> 
>   __asm__ __volatile__
>     (".set      push\n\t"
>      ".set      noreorder\n"
>      "1:\n\t"
>      "ll        %0,%3\n\t"
>      "beq       %0,%4,2f\n\t"
>      "move      %1,%4\n\t"
>      "sc        %1,%2\n\t"
>      "beqz      %1,1b\n\t"
>      "nop\n" 
>      "2:\n\t"
>      ".set      pop"    
>      : "=&r" (r), "=&r" (t), "=m" (*p)
>      : "m" (*p), "r" (v) 
>      : "memory");
> 
>   return r;
> }

Gas will fill delay slots. Same object codes will be produced, so I
think you don't have to do that by hand. 

---
Hiroyuki Machida
Sony Corp.

<Prev in Thread] Current Thread [Next in Thread>