diff options
Diffstat (limited to 'includes')
-rw-r--r-- | includes/stg/MiscClosures.h | 1 | ||||
-rw-r--r-- | includes/stg/SMP.h | 32 |
2 files changed, 29 insertions, 4 deletions
diff --git a/includes/stg/MiscClosures.h b/includes/stg/MiscClosures.h index ee973e46a9..876f39a02c 100644 --- a/includes/stg/MiscClosures.h +++ b/includes/stg/MiscClosures.h @@ -369,6 +369,7 @@ RTS_FUN_DECL(stg_newByteArrayzh); RTS_FUN_DECL(stg_newPinnedByteArrayzh); RTS_FUN_DECL(stg_newAlignedPinnedByteArrayzh); RTS_FUN_DECL(stg_casIntArrayzh); +RTS_FUN_DECL(stg_fetchAddIntArrayzh); RTS_FUN_DECL(stg_newArrayzh); RTS_FUN_DECL(stg_newArrayArrayzh); diff --git a/includes/stg/SMP.h b/includes/stg/SMP.h index bfd6bbcfab..bdcaf55d3e 100644 --- a/includes/stg/SMP.h +++ b/includes/stg/SMP.h @@ -61,6 +61,16 @@ EXTERN_INLINE StgWord cas(StgVolatilePtr p, StgWord o, StgWord n); EXTERN_INLINE StgWord atomic_inc(StgVolatilePtr p); /* + * Atomic addition by the provided quantity + * + * atomic_inc_by(p, n) { + * return ((*p) += n); + * } + */ +EXTERN_INLINE StgWord atomic_inc_by(StgVolatilePtr p, StgWord n); + + +/* * Atomic decrement * * atomic_dec(p) { @@ -236,28 +246,35 @@ cas(StgVolatilePtr p, StgWord o, StgWord n) #endif } +// RRN: Added to enable general fetch-and-add in Haskell code (fetchAddIntArray#). EXTERN_INLINE StgWord -atomic_inc(StgVolatilePtr p) +atomic_inc_by(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 } EXTERN_INLINE StgWord +atomic_inc(StgVolatilePtr p) +{ + return atomic_inc_by(p, 1); +} + +EXTERN_INLINE StgWord atomic_dec(StgVolatilePtr p) { #if defined(i386_HOST_ARCH) || defined(x86_64_HOST_ARCH) @@ -397,6 +414,13 @@ atomic_inc(StgVolatilePtr p) } INLINE_HEADER StgWord +atomic_inc_by(StgVolatilePtr p, StgWord incr) +{ + return ((*p) += incr); +} + + +INLINE_HEADER StgWord atomic_dec(StgVolatilePtr p) { return --(*p); |