summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Högberg <john@erlang.org>2023-03-20 11:40:05 +0100
committerJohn Högberg <john@erlang.org>2023-04-11 13:47:16 +0200
commit50d1239ff9a02e621a40d78ab6c5a559197f50c4 (patch)
tree5fce8b6312f75175c1f6b382012042c34d9f662f
parent5400ccf243a31d664153a4b9ceb9de3edfce1e0e (diff)
downloaderlang-50d1239ff9a02e621a40d78ab6c5a559197f50c4.tar.gz
erts: Fix overlapping blocking code barriers in the same tick
-rw-r--r--erts/emulator/beam/code_ix.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/erts/emulator/beam/code_ix.c b/erts/emulator/beam/code_ix.c
index 607f3c82c6..8f393f92cf 100644
--- a/erts/emulator/beam/code_ix.c
+++ b/erts/emulator/beam/code_ix.c
@@ -347,7 +347,17 @@ static ErtsThrPrgrLaterOp global_code_barrier_lop;
static void decrement_blocking_code_barriers(void *ignored) {
(void)ignored;
- erts_atomic32_dec_nob(&outstanding_blocking_code_barriers);
+
+ if (erts_atomic32_dec_read_nob(&outstanding_blocking_code_barriers) > 0) {
+ /* We had more than one barrier in the same tick, and can't tell
+ * whether the later ones were issued before any of the managed threads
+ * were woken. Keep telling all managed threads to execute an
+ * instruction barrier on wake-up for one more tick. */
+ erts_atomic32_set_nob(&outstanding_blocking_code_barriers, 1);
+ erts_schedule_thr_prgr_later_op(decrement_blocking_code_barriers,
+ NULL,
+ &global_code_barrier_lop);
+ }
}
static void schedule_blocking_code_barriers(void *ignored) {
@@ -358,11 +368,12 @@ static void schedule_blocking_code_barriers(void *ignored) {
* counter.
*
* Note that we increment and decrement instead of setting and clearing
- * since we might execute several blocking barriers in the same tick. */
- erts_atomic32_inc_nob(&outstanding_blocking_code_barriers);
- erts_schedule_thr_prgr_later_op(decrement_blocking_code_barriers,
- NULL,
- &global_code_barrier_lop);
+ * since we might schedule several blocking barriers in the same tick. */
+ if (erts_atomic32_inc_read_nob(&outstanding_blocking_code_barriers) == 1) {
+ erts_schedule_thr_prgr_later_op(decrement_blocking_code_barriers,
+ NULL,
+ &global_code_barrier_lop);
+ }
}
#endif