(* Q2 *) type 'a future = { mutable isDone : bool ; mutable isCancelled : bool ; mutable result : 'a option ; mutable th : Thread.t ; mut : Mutex.t ; mutable exn : exn ; } let create_future () = { isDone = false; isCancelled = false; result = None ; th = Thread.self (); mut = Mutex.create(); exn = Not_found; } ;; let spawn g b = let f = create_future() in let h f () = Mutex.lock f.mut; let r = (g b) in f.isDone <- true; f.result <- Some(r); Mutex.unlock f.mut; r in Mutex.lock f.mut; let t = Thread.create (h f) () in f.th <- t; Mutex.unlock f.mut; f ;; let rec get f = if f.isDone then match f.result with None -> failwith "strange" | Some r -> r else ( Mutex.lock f.mut; Mutex.unlock f.mut; get f) ;; let isDone f = f.isDone;; (* Q3 *) let f x = x + 1;; let x1 = spawn f 5 and x2 = spawn f 4 and x3 = spawn f 6 ;; let result = ((get x1) + (get x2) + (get x3)) / 3;; (* Q4 *) let spawn2 g b = let f = create_future() in let h f () = Mutex.lock f.mut; try let r = (g b) in f.isDone <- true; f.result <- Some(r); Mutex.unlock f.mut; r with e -> (f.isDone <- true; f.isCancelled <- true; f.exn <- e; Mutex.unlock f.mut) in Mutex.lock f.mut; let t = Thread.create (h f) () in f.th <- t; Mutex.unlock f.mut; f ;; let rec get2 f = if f.isCancelled then raise f.exn else if f.isDone then match f.result with None -> failwith "strange" | Some r -> r else ( Mutex.lock f.mut; Mutex.unlock f.mut; get f) ;; let isCancelled f = f.isCancelled;; (* Q5 *) let futmap f a = let al = Array.length a in let b = Array.create al (spawn f a.(0)) in for i = 1 to al-1 do spawn f a.(i) done; b;; (* Q6 *) let sync af = let afl = Array.length af in for i=0 to afl-1 do get af.(i) done;; let tout f a = let af = futmap f a in af, spawn (fun af -> sync af) af;;