问题描述
我在互联网上找到:
#define LOCK_PREFIX "lock ; "
struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((struct __xchg_dummy *)(x))
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
unsigned long new, int size)
{
unsigned long prev;
switch (size) {
case 1:
__asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
: "=a"(prev)
: "q"(new), "m"(*__xg(ptr)), "0"(old)
: "memory");
return prev;
case 2:
__asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
: "=a"(prev)
: "q"(new), "m"(*__xg(ptr)), "0"(old)
: "memory");
return prev;
case 4:
__asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
: "=a"(prev)
: "q"(new), "m"(*__xg(ptr)), "0"(old)
: "memory");
return prev;
}
return old;
}
#define cmpxchg(ptr,o,n)\
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
(unsigned long)(n),sizeof(*(ptr))))
当我编译并使用此功能(CMPXCHG)为i386架构 - 所有的好!但是,当我在SPARC架构编译,我以下错误:
When I compile and use this function (cmpxchg) for i386 architecture - all good! But, when i compile under Sparc architecture, i've the following error:
error: impossible constraint in `asm'
这是什么问题?
推荐答案
在Solaris上,最好不要写自己的code本(既不在SPARC也不在x86);相反,使用为目的的功能:
On Solaris, better don't write your own code for this (neither on SPARC nor on x86); rather, use the atomic_cas(3C)
functions for the purpose:
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
unsigned long new, int size)
{
switch (size) {
case 1: return atomic_cas_8(ptr, (unsigned char)old, (unsigned char)new);
case 2: return atomic_cas_16(ptr, (unsigned short)old, (unsigned short)new);
case 4: return atomic_cas_32(ptr, (unsigned int)old, (unsigned int)new);
#ifdef _LP64
case 8: return atomic_cas_64(ptr, old, new);
#endif
default: break;
}
return old;
}
这将用于Solaris做的。
That'll do for Solaris.
编辑:如果你绝对要内联这种事情,在SPARC(V8 +,又名的UltraSPARC)指令使用的是比较和交换,又名 CAS
。它总是原子(SPARC不知道锁prefixes)。它仅配备在32bit和64bit( CASX
)的变种,从而使8 / 16bit的库函数执行32位的 CAS
掩蔽出非目标字/字节。我不会重复实现,帮助 - 这是不是一个好主意,使用库接口
if you absolutely have to inline this kind of thing, the SPARC (v8+, aka UltraSPARC) instruction to use is "compare and swap", aka CAS
. It's always atomic (sparc doesn't know lock prefixes). It only comes in 32bit and 64bit (CASX
) variants, so that the 8/16bit library functions perform 32bit CAS
masking out the non-targeted word/bytes. I won't help with reimplementing that - it's not a good idea, use the library interfaces.
EDIT2:一些帮助,重新实现您的(如果你不能使用Solaris的libc链接)。
Some help with reimplementing you get by reading the sourcecode (if you cannot link with Solaris libc).
这篇关于GCC内联大会SPARC架构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!