(* Parallel extension to MathLink interface. $Id: para.m,v 1.1 1996/10/04 06:09:25 tjchol01 Exp tjchol01 $ $Log: para.m,v $ \Revision 1.1 1996/10/04 06:09:25 tjchol01 Initial revision *) Begin["System`"] RunLinks::usage = "Evaluate from links with pending data until they return results." GetLinkResults::usage = "Return result from a link evaluated with RunLinks." Remove[PRun] PRun::usage = "Run links and return results." PRun[x_] := GetLinkResults[ RunLinks [x] ] LinksRunning::usage = "A list of links with pending results." LinksAvailable::usage = "A list of installed unused links." LinkResults::usage = "A list of results from finished links." ExternalCall::NoLinksLeft = "All links are in use. Install more." NLinks := Length[LinksAvailable] Begin["`Private`"] If[ Length[LinksAvailable] + Length[LinksRunning] == 0, LinksAvailable = {}; LinksRunning = {}; LinkResults = {} ] ExternalCall[ link_LinkObject, packet_CallPacket ] := Module[{mylink}, If[ Length[LinksAvailable] > 0, mylink = First[LinksAvailable]; Block[{ThisLink = mylink}, If[ LinkWrite[mylink, packet] === $Failed, LinksRunning = DeleteCases[LinksRunning, mylink]; LinksAvailable = DeleteCases[LinksAvailable, mylink]; $Failed, AppendTo[LinksRunning, mylink]; LinksAvailable = Rest[LinksAvailable]; LinkResults = DeleteCases[LinkResults, {mylink, _}]; mylink (* link id returned *) ] ], Message[ExternalCall::NoLinksLeft]; Abort[] ] ] ExternalAnswer[ link_LinkObject, Hold[EvaluatePacket[expr_]] ] := If[ LinkWrite[ link, ReturnPacket[ CheckAbort[expr, $Aborted]]] === $Failed, LinksRunning = DeleteCases[LinksRunning, mylink]; LinksAvailable = DeleteCases[LinksAvailable, mylink]; $Failed ] ExternalAnswer[ link_LinkObject, Hold[ReturnPacket[result_]] ] := ExternalFinish[link, result] ExternalAnswer[ link_LinkObject, Hold[result_] ] := ExternalFinish[link, result] ExternalAnswer[ link_LinkObject, result_ ] := ExternalFinish[link, result] ExternalFinish[ link_LinkObject, result_ ] := ( LinksRunning = DeleteCases[LinksRunning, link]; AppendTo[LinksAvailable, link]; AppendTo[LinkResults, {link, result}]; result ) RunLinks[link_] := Module[{links = If[ListQ[link], link, {link}]}, While[ Length[Intersection[LinksRunning, links]] > 0, If[ LinkReadyQ[#] || !ListQ[link], ExternalAnswer[#, LinkReadHeld[#] ]; ]& /@ links ]; link ] GetLinkResults[link_] := Block[{x}, With[{sele = (If[ Length[#] > 0, First[#], {}]& [ Cases[ LinkResults, {#, x_} -> x] ])&}, If[ListQ[link], sele /@ link, sele @ link] ]] End[] End[];