[Git][ghc/ghc][wip/tsan/prep] 2 commits: rts: Introduce more principled fence operations
Ben Gamari (@bgamari)
gitlab at gitlab.haskell.org
Mon Jul 24 18:30:25 UTC 2023
Ben Gamari pushed to branch wip/tsan/prep at Glasgow Haskell Compiler / GHC
Commits:
b431aa81 by Ben Gamari at 2023-07-24T14:23:58-04:00
rts: Introduce more principled fence operations
- - - - -
8a64b390 by Ben Gamari at 2023-07-24T14:23:59-04:00
rts: Introduce SET_INFO_RELAXED
- - - - -
5 changed files:
- rts/include/Cmm.h
- rts/include/Rts.h
- rts/include/Stg.h
- rts/include/rts/storage/ClosureMacros.h
- rts/include/stg/SMP.h
Changes:
=====================================
rts/include/Cmm.h
=====================================
@@ -596,6 +596,7 @@
/* Getting/setting the info pointer of a closure */
#define SET_INFO(p,info) StgHeader_info(p) = info
#define SET_INFO_RELEASE(p,info) %release StgHeader_info(p) = info
+#define SET_INFO_RELAXED(p,info) %relaxed StgHeader_info(p) = info
#define GET_INFO(p) StgHeader_info(p)
#define GET_INFO_ACQUIRE(p) %acquire GET_INFO(p)
@@ -687,10 +688,18 @@
#define RELEASE_FENCE prim %fence_release();
#define ACQUIRE_FENCE prim %fence_acquire();
+// TODO
+#if 1
+#define ACQUIRE_FENCE_ON(x) if (1) { W_ tmp; (tmp) = prim %load_acquire64(x); }
+#else
+#define ACQUIRE_FENCE_ON(x) ACQUIRE_FENCE
+#endif
+
#else
#define RELEASE_FENCE /* nothing */
#define ACQUIRE_FENCE /* nothing */
+#define ACQUIRE_FENCE_ON(x) /* nothing */
#endif /* THREADED_RTS */
/* -----------------------------------------------------------------------------
=====================================
rts/include/Rts.h
=====================================
@@ -236,7 +236,6 @@ void _warnFail(const char *filename, unsigned int linenum);
/* Parallel information */
#include "rts/OSThreads.h"
-#include "rts/TSANUtils.h"
#include "rts/SpinLock.h"
#include "rts/Messages.h"
=====================================
rts/include/Stg.h
=====================================
@@ -393,6 +393,7 @@ external prototype return neither of these types to workaround #11395.
#include "stg/MachRegsForHost.h"
#include "stg/Regs.h"
#include "stg/Ticky.h"
+#include "rts/TSANUtils.h"
#if IN_STG_CODE
/*
=====================================
rts/include/rts/storage/ClosureMacros.h
=====================================
@@ -47,6 +47,11 @@
EXTERN_INLINE void SET_INFO(StgClosure *c, const StgInfoTable *info);
EXTERN_INLINE void SET_INFO(StgClosure *c, const StgInfoTable *info) {
+ c->header.info = info;
+}
+
+EXTERN_INLINE void SET_INFO_RELAXED(StgClosure *c, const StgInfoTable *info);
+EXTERN_INLINE void SET_INFO_RELAXED(StgClosure *c, const StgInfoTable *info) {
RELAXED_STORE(&c->header.info, info);
}
@@ -70,6 +75,7 @@ EXTERN_INLINE StgThunkInfoTable *itbl_to_thunk_itbl (const StgInfoTable *i);
EXTERN_INLINE StgConInfoTable *itbl_to_con_itbl (const StgInfoTable *i);
#if defined(TABLES_NEXT_TO_CODE)
+NO_WARN(-Warray-bounds,
EXTERN_INLINE StgInfoTable *INFO_PTR_TO_STRUCT(const StgInfoTable *info) {return (StgInfoTable *)info - 1;}
EXTERN_INLINE StgRetInfoTable *RET_INFO_PTR_TO_STRUCT(const StgInfoTable *info) {return (StgRetInfoTable *)info - 1;}
EXTERN_INLINE StgFunInfoTable *FUN_INFO_PTR_TO_STRUCT(const StgInfoTable *info) {return (StgFunInfoTable *)info - 1;}
@@ -79,6 +85,7 @@ EXTERN_INLINE StgFunInfoTable *itbl_to_fun_itbl(const StgInfoTable *i) {return (
EXTERN_INLINE StgRetInfoTable *itbl_to_ret_itbl(const StgInfoTable *i) {return (StgRetInfoTable *)(i + 1) - 1;}
EXTERN_INLINE StgThunkInfoTable *itbl_to_thunk_itbl(const StgInfoTable *i) {return (StgThunkInfoTable *)(i + 1) - 1;}
EXTERN_INLINE StgConInfoTable *itbl_to_con_itbl(const StgInfoTable *i) {return (StgConInfoTable *)(i + 1) - 1;}
+)
#else
EXTERN_INLINE StgInfoTable *INFO_PTR_TO_STRUCT(const StgInfoTable *info) {return (StgInfoTable *)info;}
EXTERN_INLINE StgRetInfoTable *RET_INFO_PTR_TO_STRUCT(const StgInfoTable *info) {return (StgRetInfoTable *)info;}
=====================================
rts/include/stg/SMP.h
=====================================
@@ -490,10 +490,25 @@ busy_wait_nop(void)
// These are typically necessary only in very specific cases (e.g. WSDeque)
// where the ordered operations aren't expressive enough to capture the desired
// ordering.
+//
+// Additionally, it is preferable to use the *_FENCE_ON() forms, which turn into
+// memory accesses when compiling for ThreadSanitizer (as ThreadSanitizer is
+// otherwise unable to reason about fences). See Note [ThreadSanitizer] in
+// TSANUtils.h.
+
#define ACQUIRE_FENCE() __atomic_thread_fence(__ATOMIC_ACQUIRE)
#define RELEASE_FENCE() __atomic_thread_fence(__ATOMIC_RELEASE)
#define SEQ_CST_FENCE() __atomic_thread_fence(__ATOMIC_SEQ_CST)
+#if defined(TSAN_ENABLED)
+#define ACQUIRE_FENCE() NO_WARN(-Wtsan, __atomic_thread_fence(__ATOMIC_ACQUIRE);)
+#define RELEASE_FENCE() NO_WARN(-Wtsan, __atomic_thread_fence(__ATOMIC_RELEASE);)
+#define SEQ_CST_FENCE() NO_WARN(-Wtsan, __atomic_thread_fence(__ATOMIC_SEQ_CST);)
+#define ACQUIRE_FENCE_ON(x) (void)ACQUIRE_LOAD(x)
+#else
+#define ACQUIRE_FENCE_ON(x) __atomic_thread_fence(__ATOMIC_ACQUIRE)
+#endif
+
/* ---------------------------------------------------------------------- */
#else /* !THREADED_RTS */
@@ -521,6 +536,8 @@ busy_wait_nop(void)
#define ACQUIRE_FENCE()
#define RELEASE_FENCE()
#define SEQ_CST_FENCE()
+#define ACQUIRE_FENCE_ON(x)
+#define RELEASE_FENCE_ON(x)
#if !IN_STG_CODE || IN_STGCRUN
INLINE_HEADER StgWord
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/af672b6669059a8df0e04cbd2b2959d0390830fb...8a64b390f2bd5da967e4935e9db399db387e8a8d
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/af672b6669059a8df0e04cbd2b2959d0390830fb...8a64b390f2bd5da967e4935e9db399db387e8a8d
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20230724/5d6bcc8e/attachment-0001.html>
More information about the ghc-commits
mailing list