Test.multiple seems to be fine but Test.uniq does a double free:
let (allocate0 : unit -> _), free0, (allocate1 : int -> _), free1 =
match kind with
| Test.Uniq ->
let v = [| Test.Uniq.prj (allocate ()) |] in
( (fun () -> Test.Uniq.prj (allocate ()))
, (fun v -> free (Test.Uniq.inj v))
, always v
, fun a -> a |> Array.iter @@ fun v -> free (Test.Uniq.inj v) )
| Test.Multiple ->
let v = unsafe_array_get (Test.Multiple.prj (allocate 1)) 0 in
( always v
, (fun v -> free (Test.Multiple.inj [| v |]))
, (fun n -> Test.Multiple.prj (allocate n))
, fun v -> free (Test.Multiple.inj v) )
in
allocate1 and free1 get called multiple times in the benchmark loop, unlike allocate0 and free0 which get called just once.
Even if the argument ends up unused that can still result in a deadlock, crash or exception being thrown by the 'free1' implementation.
Would probably be useful to have some unit tests for this.
Test.multiple seems to be fine but Test.uniq does a double free:
allocate1
andfree1
get called multiple times in the benchmark loop, unlike allocate0 and free0 which get called just once.Even if the argument ends up unused that can still result in a deadlock, crash or exception being thrown by the 'free1' implementation.
Would probably be useful to have some unit tests for this.
I've modified list.ml slightly to show this: