Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 3 Mar 2005 15:25:58 -0600
From:      Alan Cox <alc@cs.rice.edu>
To:        John Baldwin <jhb@FreeBSD.org>
Cc:        Alan Cox <alc@cs.rice.edu>
Subject:   Re: PERFORCE change 72450 for review
Message-ID:  <20050303212558.GA16936@cs.rice.edu>
In-Reply-To: <200503032104.j23L4Pjw010114@repoman.freebsd.org>
References:  <200503032104.j23L4Pjw010114@repoman.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Mar 03, 2005 at 09:04:25PM +0000, John Baldwin wrote:
> http://perforce.freebsd.org/chv.cgi?CH=72450
> 
> Change 72450 by jhb@jhb_slimer on 2005/03/03 21:03:35
> 
> 	Clobber memory for cas{x,}a() inlines.
> 	
> 	Suggested by:  alc
> 
> Affected files ...
> 
> .. //depot/projects/smpng/sys/sparc64/include/cpufunc.h#20 edit
> 
> Differences ...
> 
> ==== //depot/projects/smpng/sys/sparc64/include/cpufunc.h#20 (text+ko) ====
> 
> @@ -63,14 +63,14 @@
>  #define	casa(rs1, rs2, rd, asi) ({					\
>  	u_int __rd = (uint32_t)(rd);					\
>  	__asm __volatile("casa [%1] %2, %3, %0"				\
> -	    : "+r" (__rd) : "r" (rs1), "n" (asi), "r" (rs2));		\
> +	    : "+r" (__rd) : "r" (rs1), "n" (asi), "r" (rs2) : "memory");\
>  	__rd;								\
>  })
>  
>  #define	casxa(rs1, rs2, rd, asi) ({					\
>  	u_long __rd = (uint64_t)(rd);					\
>  	__asm __volatile("casxa [%1] %2, %3, %0"			\
> -	    : "+r" (__rd) : "r" (rs1), "n" (asi), "r" (rs2));		\
> +	    : "+r" (__rd) : "r" (rs1), "n" (asi), "r" (rs2) : "memory");\
>  	__rd;								\
>  })
>  

The other, arguably "more correct", option is to declare the memory
location referenced by rs1 as an input and output operand, like so
from i386:  (I say "more correct" because the true operand here is the
memory location referenced by rs1 not rs1 the register.)

static __inline pt_entry_t
pte_load_store(pt_entry_t *ptep, pt_entry_t pte)
{
	pt_entry_t r;

	__asm __volatile(
	    "xchgl %0,%1"
	    : "=m" (*ptep),
	      "=r" (r)
	    : "1" (pte),
	      "m" (*ptep));
	return (r);
}

(Note: this example does not use "+m" as an output constraint because
Tor convinced me a few months ago that the gcc docs prohibit that: "+"
is only to be used with registers.)  

Returning to the sparc, I'm not sure what the right constraint is for
cas{x,}a's rs1.  I don't believe that "m" is appropriate because this
particular instruction doesn't allow the destination to be a register
plus an constant offset.  Perhaps, "V"?

That said, we should add a "memory" clobber to the sparc64 atomic ops
that include a memory barrier, particularly, the acquires.

Regards,
Alan



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050303212558.GA16936>