X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=includes%2FSMP.h;h=b7538424b9aa6d9050a55347ec81ccb3b1193661;hb=f4e682c8f54a70cacbc412c1bd24cf619e1023e7;hp=c851054cd90d3f2adc685a7d02756a32f83f8fca;hpb=a67183b75f1527edd88b071b879c2d07e8ac7653;p=ghc-hetmet.git diff --git a/includes/SMP.h b/includes/SMP.h index c851054..b753842 100644 --- a/includes/SMP.h +++ b/includes/SMP.h @@ -18,7 +18,7 @@ #if defined(THREADED_RTS) -#if defined(TICKY_TICKY) +#if defined(TICKY_TICKY) #error Build options incompatible with THREADED_RTS. #endif @@ -52,6 +52,24 @@ EXTERN_INLINE StgWord xchg(StgPtr p, StgWord w); */ EXTERN_INLINE StgWord cas(StgVolatilePtr p, StgWord o, StgWord n); +/* + * Atomic increment + * + * atomic_inc(p) { + * return ++(*p); + * } + */ +EXTERN_INLINE StgWord atomic_inc(StgVolatilePtr p); + +/* + * Atomic decrement + * + * atomic_dec(p) { + * return --(*p); + * } + */ +EXTERN_INLINE StgWord atomic_dec(StgVolatilePtr p); + #endif // !IN_STG_CODE /* @@ -164,6 +182,48 @@ cas(StgVolatilePtr p, StgWord o, StgWord n) #endif } +EXTERN_INLINE StgWord +atomic_inc(StgVolatilePtr p) +{ +#if defined(i386_HOST_ARCH) || defined(x86_64_HOST_ARCH) + StgWord r; + r = 1; + __asm__ __volatile__ ( + "lock\nxadd %0,%1": + "+r" (r), "+m" (*p): + ); + return r+1; +#else + StgWord old, new; + do { + old = *p; + new = old + 1; + } while (cas(p, old, new) != old); + return new; +#endif +} + +EXTERN_INLINE StgWord +atomic_dec(StgVolatilePtr p) +{ +#if defined(i386_HOST_ARCH) || defined(x86_64_HOST_ARCH) + StgWord r; + r = (StgWord)-1; + __asm__ __volatile__ ( + "lock\nxadd %0,%1": + "+r" (r), "+m" (*p): + ); + return r-1; +#else + StgWord old, new; + do { + old = *p; + new = old - 1; + } while (cas(p, old, new) != old); + return new; +#endif +} + #endif // !IN_STG_CODE /* @@ -179,7 +239,7 @@ write_barrier(void) { #elif powerpc_HOST_ARCH __asm__ __volatile__ ("lwsync" : : : "memory"); #elif sparc_HOST_ARCH - /* Sparc in TSO mode does not require write/write barriers. */ + /* Sparc in TSO mode does not require store/store barriers. */ __asm__ __volatile__ ("" : : : "memory"); #elif !defined(WITHSMP) return; @@ -195,10 +255,9 @@ store_load_barrier(void) { #elif x86_64_HOST_ARCH __asm__ __volatile__ ("lock; addq $0,0(%%rsp)" : : : "memory"); #elif powerpc_HOST_ARCH - __asm__ __volatile__ ("msync" : : : "memory"); + __asm__ __volatile__ ("sync" : : : "memory"); #elif sparc_HOST_ARCH - /* Sparc in TSO mode does not require write/write barriers. */ - __asm__ __volatile__ ("membar" : : : "memory"); + __asm__ __volatile__ ("membar #StoreLoad" : : : "memory"); #elif !defined(WITHSMP) return; #else @@ -215,7 +274,7 @@ load_load_barrier(void) { #elif powerpc_HOST_ARCH __asm__ __volatile__ ("lwsync" : : : "memory"); #elif sparc_HOST_ARCH - /* Sparc in TSO mode does not require write/write barriers. */ + /* Sparc in TSO mode does not require load/load barriers. */ __asm__ __volatile__ ("" : : : "memory"); #elif !defined(WITHSMP) return; @@ -250,6 +309,18 @@ cas(StgVolatilePtr p, StgWord o, StgWord n) return result; } +INLINE_HEADER StgWord +atomic_inc(StgVolatilePtr p) +{ + return ++(*p); +} + +INLINE_HEADER StgWord +atomic_dec(StgVolatilePtr p) +{ + return --(*p); +} + #endif /* !THREADED_RTS */ #endif /* SMP_H */