mcas_volatile.ml Helping Protocol
read_internal — threads help each other complete
let rec read_internal addr self =
  let content = Atomic.get addr in
  match content with
  | Value value ->
      (content, value)          (* clean read — return immediately *)

  | Word wd ->
      let parent = wd.parent in
      let not_self = match self with
        | Some d -> not (same_desc d parent)
        | None   -> true
      in
      (* Help foreign in-progress MCAS before reading *)
      if not_self && Atomic.get parent.status = Active
      then (ignore (mcas_desc parent); read_internal addr self)
      else
        (content, logical_value wd)  (* return logical value *)

let logical_value wd =
  if is_successful wd.parent
  then wd.new_value   (* MCAS committed — expose new value *)
  else wd.old_value   (* MCAS failed  — expose old value  *)