summaryrefslogtreecommitdiff
path: root/erts
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-03-20 12:37:24 +0100
commit74eee7564d64091dcf42f9361be5381f9fbec0ab (patch)
tree2505f2fb89c038c53b1bf78b600042af9a9e7e76 /erts
parentfc86dc0055ac3d26f8af4899175319737a622c91 (diff)
downloaderlang-74eee7564d64091dcf42f9361be5381f9fbec0ab.tar.gz
erts: Fix overlapping blocking code barriers in the same tick
Diffstat (limited to 'erts')
-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 2dd3412d1b..e2e275442e 100644
--- a/erts/emulator/beam/code_ix.c
+++ b/erts/emulator/beam/code_ix.c
@@ -444,7 +444,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) {
@@ -455,11 +465,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