diff options
author | Ben Gamari <ben@smart-cactus.org> | 2023-03-09 17:19:43 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2023-04-24 06:00:40 -0400 |
commit | 4eb1aeb06fc86da216bd176f6d3a1383c9364b03 (patch) | |
tree | d7fcb3fa5d93681a21f600839f04b345228c533f | |
parent | 47d0ad2eba86788bbb7a0e527b33e8064184cf80 (diff) | |
download | haskell-4eb1aeb06fc86da216bd176f6d3a1383c9364b03.tar.gz |
rts: Fix various data races
-rw-r--r-- | rts/Interpreter.c | 4 | ||||
-rw-r--r-- | rts/PrimOps.cmm | 17 | ||||
-rw-r--r-- | rts/include/Cmm.h | 6 |
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 |