build_descriptor — sort + validate + allocate
let build_descriptor ops =
let ops = sort_ops ops in (* sort by id to prevent deadlock *)
validate_distinct ops; (* reject duplicate targets *)
let desc = {
status = Atomic.make Active;
words = [||];
retired = Atomic.make false
} in
let words =
Array.of_list (
List.map (fun (CAS (r, expected, desired)) -> {
address = r.cell;
old_value = Obj.repr expected;
new_value = Obj.repr desired;
parent = desc; (* back-link to parent *)
}) ops)
in
desc.words <- words;
desc
let mcas ops =
let desc = build_descriptor ops in
mcas_desc desc (* returns true on commit, false on abort *)