diff options
author | Patrick Palka <patrick@parcs.ath.cx> | 2013-09-04 12:10:27 -0400 |
---|---|---|
committer | Patrick Palka <patrick@parcs.ath.cx> | 2013-09-04 12:10:27 -0400 |
commit | d127a697192851ea6bf308525a8a8895da71b639 (patch) | |
tree | 895f8976273df8e96b7c52382529ca0dfee61a5a /includes/stg/SMP.h | |
parent | a2e338f3ae5a101d333fb260ed58ec238106e88e (diff) | |
parent | 32ade417f7e82b6fbcb6f1c93871ba3141a8f5c8 (diff) | |
download | haskell-d127a697192851ea6bf308525a8a8895da71b639.tar.gz |
Merge remote-tracking branch 'origin/master' into ghc-parmake-gsoc
Diffstat (limited to 'includes/stg/SMP.h')
-rw-r--r-- | includes/stg/SMP.h | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/includes/stg/SMP.h b/includes/stg/SMP.h index 99c25fe355..07ea522328 100644 --- a/includes/stg/SMP.h +++ b/includes/stg/SMP.h @@ -52,13 +52,14 @@ EXTERN_INLINE StgWord xchg(StgPtr p, StgWord w); EXTERN_INLINE StgWord cas(StgVolatilePtr p, StgWord o, StgWord n); /* - * Atomic increment + * Atomic addition by the provided quantity * - * atomic_inc(p) { - * return ++(*p); + * atomic_inc(p, n) { + * return ((*p) += n); * } */ -EXTERN_INLINE StgWord atomic_inc(StgVolatilePtr p); +EXTERN_INLINE StgWord atomic_inc(StgVolatilePtr p, StgWord n); + /* * Atomic decrement @@ -236,22 +237,24 @@ cas(StgVolatilePtr p, StgWord o, StgWord n) #endif } +// RRN: Generalized to arbitrary increments to enable fetch-and-add in +// Haskell code (fetchAddIntArray#). EXTERN_INLINE StgWord -atomic_inc(StgVolatilePtr p) +atomic_inc(StgVolatilePtr p, StgWord incr) { #if defined(i386_HOST_ARCH) || defined(x86_64_HOST_ARCH) StgWord r; - r = 1; + r = incr; __asm__ __volatile__ ( "lock\nxadd %0,%1": "+r" (r), "+m" (*p): ); - return r+1; + return r + incr; #else StgWord old, new; do { old = *p; - new = old + 1; + new = old + incr; } while (cas(p, old, new) != old); return new; #endif @@ -393,12 +396,14 @@ cas(StgVolatilePtr p, StgWord o, StgWord n) return result; } -INLINE_HEADER StgWord -atomic_inc(StgVolatilePtr p) +EXTERN_INLINE StgWord atomic_inc(StgVolatilePtr p, StgWord incr); +EXTERN_INLINE StgWord +atomic_inc(StgVolatilePtr p, StgWord incr) { - return ++(*p); + return ((*p) += incr); } + INLINE_HEADER StgWord atomic_dec(StgVolatilePtr p) { |