summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2023-03-15 20:50:38 -0400
committerBen Gamari <ben@smart-cactus.org>2023-05-09 08:41:53 -0400
commit81cfefd2cfb9d97a19d8e543130f94248e667330 (patch)
treef2b2bc724572fbcaca8c5370c38214f7a5aeb649 /rts
parentb970e64fb2dd6d65e6e14a7e57bbc0e2eef663a7 (diff)
downloadhaskell-81cfefd2cfb9d97a19d8e543130f94248e667330.tar.gz
compiler: Implement atomicSwapIORef with xchg
As requested by @treeowl in CLC#139.
Diffstat (limited to 'rts')
-rw-r--r--rts/PrimOps.cmm11
-rw-r--r--rts/RtsSymbols.c1
-rw-r--r--rts/include/Cmm.h2
-rw-r--r--rts/include/stg/MiscClosures.h1
4 files changed, 15 insertions, 0 deletions
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm
index 60d0dc2ccc..9e86a8e0a2 100644
--- a/rts/PrimOps.cmm
+++ b/rts/PrimOps.cmm
@@ -689,6 +689,17 @@ stg_newMutVarzh ( gcptr init )
return (mv);
}
+stg_atomicSwapMutVarzh ( gcptr mv, gcptr new )
+ /* MutVar# s a -> a -> State# s -> (# State#, a #) */
+{
+ W_ old;
+ (old) = prim %xchgW(mv + SIZEOF_StgHeader + OFFSET_StgMutVar_var, new);
+ if (GET_INFO(mv) == stg_MUT_VAR_CLEAN_info) {
+ ccall dirty_MUT_VAR(BaseReg "ptr", mv "ptr", old "ptr");
+ }
+ return (old);
+}
+
// RRN: To support the "ticketed" approach, we return the NEW rather
// than old value if the CAS is successful. This is received in an
// opaque form in the Haskell code, preventing the compiler from
diff --git a/rts/RtsSymbols.c b/rts/RtsSymbols.c
index dee6c57f5e..ebf73a2b69 100644
--- a/rts/RtsSymbols.c
+++ b/rts/RtsSymbols.c
@@ -633,6 +633,7 @@ extern char **environ;
SymI_HasDataProto(stg_writeIOPortzh) \
SymI_HasDataProto(stg_newIOPortzh) \
SymI_HasDataProto(stg_noDuplicatezh) \
+ SymI_HasDataProto(stg_atomicSwapMutVarzh) \
SymI_HasDataProto(stg_atomicModifyMutVar2zh) \
SymI_HasDataProto(stg_atomicModifyMutVarzuzh) \
SymI_HasDataProto(stg_casMutVarzh) \
diff --git a/rts/include/Cmm.h b/rts/include/Cmm.h
index 15df6d0df1..a1cf44c31b 100644
--- a/rts/include/Cmm.h
+++ b/rts/include/Cmm.h
@@ -193,8 +193,10 @@
#if SIZEOF_W == 4
#define cmpxchgW cmpxchg32
+#define xchgW xchg32
#elif SIZEOF_W == 8
#define cmpxchgW cmpxchg64
+#define xchgW xchg64
#endif
/* -----------------------------------------------------------------------------
diff --git a/rts/include/stg/MiscClosures.h b/rts/include/stg/MiscClosures.h
index 8e50336e4a..da556870f1 100644
--- a/rts/include/stg/MiscClosures.h
+++ b/rts/include/stg/MiscClosures.h
@@ -481,6 +481,7 @@ RTS_FUN_DECL(stg_copySmallMutableArrayzh);
RTS_FUN_DECL(stg_casSmallArrayzh);
RTS_FUN_DECL(stg_newMutVarzh);
+RTS_FUN_DECL(stg_atomicSwapMutVarzh);
RTS_FUN_DECL(stg_atomicModifyMutVar2zh);
RTS_FUN_DECL(stg_atomicModifyMutVarzuzh);
RTS_FUN_DECL(stg_casMutVarzh);