diff --git a/Changes b/Changes index cbe18fcde..19caeea8b 100644 --- a/Changes +++ b/Changes @@ -264,6 +264,9 @@ OCaml 4.12.0 OCaml. (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. (Guillaume Munch-Maccagnoni, review by Gabriel Scherer and Xavier Leroy) diff --git a/stdlib/camlinternalAtomic.ml b/stdlib/camlinternalAtomic.ml index c73845330..b7e74a53f 100644 --- a/stdlib/camlinternalAtomic.ml +++ b/stdlib/camlinternalAtomic.ml @@ -28,21 +28,32 @@ let make v = {v} let get r = r.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 r.v <- v; + (* END ATOMIC *) cur -let compare_and_set r seen v = +let[@inline never] compare_and_set r seen v = + (* BEGIN ATOMIC *) let cur = r.v in - if cur == seen then - (r.v <- v; true) - else + if cur == seen then ( + r.v <- v; + (* END ATOMIC *) + true + ) else false -let fetch_and_add r n = +let[@inline never] fetch_and_add r n = + (* BEGIN ATOMIC *) let cur = r.v in r.v <- (cur + n); + (* END ATOMIC *) cur let incr r = ignore (fetch_and_add r 1)