Ensure atomicity in the Atomic module is respected by flambda (#10035)

Prevent inlining of some of the functions, otherwise Flambda can move unrelated allocations inside the critical sections, making them non-atomic.
master
Guillaume Munch-Maccagnoni 2020-11-24 11:48:33 +01:00 committed by GitHub
parent 328ebc1ea3
commit 2109946e0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 6 deletions

View File

@ -264,6 +264,9 @@ OCaml 4.12.0
OCaml. OCaml.
(Gabriel Scherer, review by Xavier Leroy) (Gabriel Scherer, review by Xavier Leroy)
- #10035: Make sure that flambda respects atomicity in the Atomic module.
(Guillaume Munch-Maccagnoni, review by Gabriel Scherer)
- #9571: Make at_exit and Printexc.register_printer thread-safe. - #9571: Make at_exit and Printexc.register_printer thread-safe.
(Guillaume Munch-Maccagnoni, review by Gabriel Scherer and Xavier Leroy) (Guillaume Munch-Maccagnoni, review by Gabriel Scherer and Xavier Leroy)

View File

@ -28,21 +28,32 @@ let make v = {v}
let get r = r.v let get r = r.v
let set r v = r.v <- v let set r v = r.v <- v
let exchange r v = (* The following functions are set to never be inlined: Flambda is
allowed to move surrounding code inside the critical section,
including allocations. *)
let[@inline never] exchange r v =
(* BEGIN ATOMIC *)
let cur = r.v in let cur = r.v in
r.v <- v; r.v <- v;
(* END ATOMIC *)
cur cur
let compare_and_set r seen v = let[@inline never] compare_and_set r seen v =
(* BEGIN ATOMIC *)
let cur = r.v in let cur = r.v in
if cur == seen then if cur == seen then (
(r.v <- v; true) r.v <- v;
else (* END ATOMIC *)
true
) else
false false
let fetch_and_add r n = let[@inline never] fetch_and_add r n =
(* BEGIN ATOMIC *)
let cur = r.v in let cur = r.v in
r.v <- (cur + n); r.v <- (cur + n);
(* END ATOMIC *)
cur cur
let incr r = ignore (fetch_and_add r 1) let incr r = ignore (fetch_and_add r 1)