2012-02-14 133 views
1

我在網上找到的__sync_val_compare_and_swap實現:GCC內聯彙編的SPARC架構

#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架構編譯,我以下錯誤:

error: impossible constraint in `asm' 

什麼問題?

回答

3

在Solaris上,最好不要爲此編寫自己的代碼(無論是在SPARC還是x86上);相反,使用atomic_cas(3C)功能爲宗旨:

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做。

編輯:如果你非得內聯這種事情,在SPARC(V8 +,又名的UltraSPARC)指令使用的是「比較和交換」,又名CAS。它總是原子的(sparc不知道鎖前綴)。它只包含32位和64位(CASX)變體,以便8/16位庫函數執行掩蓋非目標字/字節的32位CAS。我不會幫助重新實現 - 這不是一個好主意,請使用庫接口。

編輯2:一些幫助重新實現你得到reading the sourcecode(如果你不能鏈接到Solaris libc)。

+0

test_cas.c :(.text + 0x70):undefined指向'atomic_cas_8' – 2012-02-20 14:20:37

1

您無法編譯sparc的x86 asm。這是我得到的使用叮鐺聲:

[~] main% ~/ellcc/bin/sparc-linux-ecc asm.c 
asm.c:13:20: error: invalid output constraint '=a' in asm 
      : "=a"(prev) 

「a」不是sparc寄存器,它是特定於x86。

即使你要修復約束,當sparc彙編程序看到x86特定的cmpxchgb操作碼時,也會出現彙編時錯誤。

+0

當我可以找到sparc的__sync_val_compare_and_swap實現,如果我不知道彙編程序,或者我必須開始學習asm?:( – 2012-02-14 12:47:46

5

cmpxchgb是一個i386指令,它不會在Sparc下工作。