[Toss-devel-svn] SF.net SVN: toss:[1443] trunk/Toss
Status: Beta
Brought to you by:
lukaszkaiser
From: <luk...@us...> - 2011-05-16 17:40:29
|
Revision: 1443 http://toss.svn.sourceforge.net/toss/?rev=1443&view=rev Author: lukaszkaiser Date: 2011-05-16 17:40:23 +0000 (Mon, 16 May 2011) Log Message: ----------- Make parallel calls stable. Inefficient for now due to multi-threading cache misses. Modified Paths: -------------- trunk/Toss/Formula/Aux.ml trunk/Toss/Formula/Aux.mli trunk/Toss/Play/GameTree.ml trunk/Toss/Server/ReqHandler.ml Modified: trunk/Toss/Formula/Aux.ml =================================================================== --- trunk/Toss/Formula/Aux.ml 2011-05-15 22:48:50 UTC (rev 1442) +++ trunk/Toss/Formula/Aux.ml 2011-05-16 17:40:23 UTC (rev 1443) @@ -660,16 +660,21 @@ addr_arr.(0) with Not_found -> raise Host_not_found -let toss_call (client_port, client_addr_s) f x = - let client_addr = get_inet_addr client_addr_s in - let client_sock = Unix.ADDR_INET (client_addr, client_port) in - let (cl_in_ch, cl_out_ch) = Unix.open_connection client_sock in - output_string cl_out_ch "COMP\n"; - flush cl_out_ch; - Marshal.to_channel cl_out_ch (f, x) [Marshal.Closures]; - flush cl_out_ch; - fun () -> - let res = Marshal.from_channel cl_in_ch in - Unix.shutdown_connection cl_in_ch; - res +let toss_call (client_port, client_addr_s) f_in x = + try + let client_addr = get_inet_addr client_addr_s in + let client_sock = Unix.ADDR_INET (client_addr, client_port) in + let (cl_in_ch, cl_out_ch) = Unix.open_connection client_sock in + output_string cl_out_ch "COMP\n"; + flush cl_out_ch; + let f a = try `Res (f_in a) with exn -> `Exn exn in + Marshal.to_channel cl_out_ch (f, x) [Marshal.Closures]; + flush cl_out_ch; + (fun () -> + let res = Marshal.from_channel cl_in_ch in + Unix.shutdown_connection cl_in_ch; + match res with `Res r -> r | `Exn e -> raise e) + with Unix.Unix_error (e, f, s) -> + Printf.printf "Toss call failed: %s; %s %s\n%!" (Unix.error_message e) f s; + (fun () -> f_in x) Modified: trunk/Toss/Formula/Aux.mli =================================================================== --- trunk/Toss/Formula/Aux.mli 2011-05-15 22:48:50 UTC (rev 1442) +++ trunk/Toss/Formula/Aux.mli 2011-05-16 17:40:23 UTC (rev 1443) @@ -309,5 +309,8 @@ (** Determine the internet address or raise Host_not_found. *) val get_inet_addr : string -> Unix.inet_addr -(** Call a Toss Server on [port, server] to compute [f] on [x]. *) +(** Call a Toss Server on [port, server] to compute [f] on [x]. BEWARE: + (1) references are not sent, e.g. you must redo timeouts. + (2) on single-threaded servers handling calls (older Toss versions), + you have to collect the results, even on Exception in caller *) val toss_call : int * string -> ('a -> 'b) -> 'a -> (unit -> 'b) Modified: trunk/Toss/Play/GameTree.ml =================================================================== --- trunk/Toss/Play/GameTree.ml 2011-05-15 22:48:50 UTC (rev 1442) +++ trunk/Toss/Play/GameTree.ml 2011-05-16 17:40:23 UTC (rev 1443) @@ -14,8 +14,11 @@ if l = 0 then [||] else if l = 1 then [|f a.(0)|] else ( let (a1, a2) = (Array.sub a 0 (l/2+1), Array.sub a (l/2+1) (l-(l/2+1))) in let r1 = Aux.toss_call !parallel_toss (Array.map f) a1 in - let r2 = Array.map f a2 in - Array.append (r1 ()) (r2) + (* If the server handling COMP is single-threaded, they must wait for it! + In such case replace the last line with the two lines below. + try let r2 = Array.map f a2 in Array.append (r1 ()) (r2) with exn -> + ignore (r1 ()); raise exn *) + let r2 = Array.map f a2 in Array.append (r1 ()) r2 ) (* Abstract game tree, just stores state and move information. *) Modified: trunk/Toss/Server/ReqHandler.ml =================================================================== --- trunk/Toss/Server/ReqHandler.ml 2011-05-15 22:48:50 UTC (rev 1442) +++ trunk/Toss/Server/ReqHandler.ml 2011-05-16 17:40:23 UTC (rev 1443) @@ -658,7 +658,7 @@ | None -> if line_in = "COMP" then let res = Marshal.from_channel in_ch in - if !debug_level > 0 then Printf.printf "COMP\n%!"; + if !debug_level > 0 then Printf.printf "COMP, %!"; ("COMP", Some (Aux.Right res)) else (* We put endlines, encoded by '$', back into the message. @@ -684,10 +684,14 @@ (new_rstate, continue) in match read_in_line in_ch with | (line, Some (Aux.Right (f, x))) when line = "COMP" -> - let res = f x in - Marshal.to_channel out_ch res [Marshal.Closures]; - flush out_ch; - (rstate, true) + (match Unix.fork () with + | 0 (* child *) -> + let res = f x in + Marshal.to_channel out_ch res [Marshal.Closures]; + flush out_ch; + (rstate, false) + | _ (* parent *) -> (rstate, true) + ) | (line, Some (Aux.Left (cmd, head, msg, ck))) when line = "HTTP" -> (match handle_http_msg rstate cmd head msg ck with | Aux.Left ((state, resp)) -> report (state, resp) true This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |