summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2023-03-09 17:19:43 -0500
committerBen Gamari <ben@smart-cactus.org>2023-04-24 06:00:40 -0400
commit4eb1aeb06fc86da216bd176f6d3a1383c9364b03 (patch)
treed7fcb3fa5d93681a21f600839f04b345228c533f
parent47d0ad2eba86788bbb7a0e527b33e8064184cf80 (diff)
downloadhaskell-4eb1aeb06fc86da216bd176f6d3a1383c9364b03.tar.gz
rts: Fix various data races
-rw-r--r--rts/Interpreter.c4
-rw-r--r--rts/PrimOps.cmm17
-rw-r--r--rts/include/Cmm.h6
3 files changed, 15 insertions, 12 deletions
diff --git a/rts/Interpreter.c b/rts/Interpreter.c
index f8885cdbce..b263f749a3 100644
--- a/rts/Interpreter.c
+++ b/rts/Interpreter.c
@@ -307,7 +307,7 @@ interpretBCO (Capability* cap)
LOAD_THREAD_STATE();
- cap->r.rHpLim = (P_)1; // HpLim is the context-switch flag; when it
+ RELAXED_STORE(&cap->r.rHpLim, (P_)1); // HpLim is the context-switch flag; when it
// goes to zero we must return to the scheduler.
IF_DEBUG(interpreter,
@@ -1989,7 +1989,7 @@ run_BCO:
// context switching: sometimes the scheduler can invoke
// the interpreter with context_switch == 1, particularly
// if the -C0 flag has been given on the cmd line.
- if (cap->r.rHpLim == NULL) {
+ if (RELAXED_LOAD(&cap->r.rHpLim) == NULL) {
Sp_subW(1); SpW(0) = (W_)&stg_enter_info;
RETURN_TO_SCHEDULER(ThreadInterpret, ThreadYielding);
}
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm
index 60d0dc2ccc..51bb8981f7 100644
--- a/rts/PrimOps.cmm
+++ b/rts/PrimOps.cmm
@@ -1170,12 +1170,11 @@ stg_threadLabelzh ( gcptr tso )
stg_threadStatuszh ( gcptr tso )
{
- W_ why_blocked;
- W_ what_next;
- W_ ret, cap, locked;
+ W_ why_blocked, what_next, flags, cap;
+ W_ ret, cap_no, locked;
- what_next = TO_W_(StgTSO_what_next(tso));
- why_blocked = TO_W_(StgTSO_why_blocked(tso));
+ what_next = TO_W_(RELAXED_LOAD_FIELD(StgTSO_what_next, tso));
+ why_blocked = TO_W_(RELAXED_LOAD_FIELD(StgTSO_why_blocked, tso));
// Note: these two reads are not atomic, so they might end up
// being inconsistent. It doesn't matter, since we
// only return one or the other. If we wanted to return the
@@ -1191,15 +1190,17 @@ stg_threadStatuszh ( gcptr tso )
}
}
- cap = TO_W_(Capability_no(StgTSO_cap(tso)));
+ cap = RELAXED_LOAD_FIELD(StgTSO_cap, tso);
+ cap_no = TO_W_(Capability_no(cap));
- if ((TO_W_(StgTSO_flags(tso)) & TSO_LOCKED) != 0) {
+ flags = TO_W_(RELAXED_LOAD_FIELD(StgTSO_flags, tso));
+ if ((flags & TSO_LOCKED) != 0) {
locked = 1;
} else {
locked = 0;
}
- return (ret,cap,locked);
+ return (ret,cap_no,locked);
}
/* -----------------------------------------------------------------------------
diff --git a/rts/include/Cmm.h b/rts/include/Cmm.h
index 688a5cf458..a1ea4efe92 100644
--- a/rts/include/Cmm.h
+++ b/rts/include/Cmm.h
@@ -444,9 +444,11 @@
HP_CHK_P(bytes); \
TICK_ALLOC_HEAP_NOCTR(bytes);
+#define RELAXED_LOAD_FIELD(fld, ptr) REP_##fld![(ptr) + SIZEOF_StgHeader + OFFSET_##fld]
+
#define CHECK_GC() \
(bdescr_link(CurrentNursery) == NULL || \
- generation_n_new_large_words(W_[g0]) >= TO_W_(CLong[large_alloc_lim]))
+ RELAXED_LOAD_FIELD(generation_n_new_large_words, g0) >= TO_W_(CLong[large_alloc_lim]))
// allocate() allocates from the nursery, so we check to see
// whether the nursery is nearly empty in any function that uses
@@ -695,7 +697,7 @@
-------------------------------------------------------------------------- */
#if defined(TICKY_TICKY)
-#define TICK_BUMP_BY(ctr,n) %relaxed W_[ctr] = %relaxed W_[ctr] + n
+#define TICK_BUMP_BY(ctr,n) %relaxed W_[ctr] = W_![ctr] + n
#else
#define TICK_BUMP_BY(ctr,n) /* nothing */
#endif