diff options
author | John Högberg <john@erlang.org> | 2023-03-20 11:40:05 +0100 |
---|---|---|
committer | John Högberg <john@erlang.org> | 2023-04-11 13:47:16 +0200 |
commit | 50d1239ff9a02e621a40d78ab6c5a559197f50c4 (patch) | |
tree | 5fce8b6312f75175c1f6b382012042c34d9f662f | |
parent | 5400ccf243a31d664153a4b9ceb9de3edfce1e0e (diff) | |
download | erlang-50d1239ff9a02e621a40d78ab6c5a559197f50c4.tar.gz |
erts: Fix overlapping blocking code barriers in the same tick
-rw-r--r-- | erts/emulator/beam/code_ix.c | 23 |
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 |