-- RPCBulk.mesa -- Andrew Birrell 26-Feb-82 10:06:00 DIRECTORY NameInfoSpecialDefs, Process, MesaRPC, RPCLupine, Runtime, SpyClient, System; RPCBulk: MONITOR IMPORTS NameInfoSpecialDefs, Process, MesaRPC, RPCLupine, Runtime, SpyClient, System = BEGIN -- ******** Test program ******** -- Finished: SIGNAL = CODE; signalFinished: BOOLEAN ← TRUE; tries: CARDINAL ← 1000; quit: BOOLEAN ← FALSE; gvExport: BOOLEAN ← TRUE; gvInstance: STRING = "RPCRuntime.pa"; nongvInstance: STRING = "Tokay"; callerName: MesaRPC.Principal ← "Test.pa"; callerKey: MesaRPC.EncryptionKey ← MesaRPC.MakeKey["Test"L]; exporterName: MesaRPC.Principal ← "RPCRuntime.pa"; exporterKey: MesaRPC.EncryptionKey ← MesaRPC.MakeKey["zzy"L]; userTest: BOOLEAN ← TRUE; spyWanted: BOOLEAN ← FALSE; import: RPCLupine.ImportHandle ← NIL; -- Test version of stub code -- StartTransfer: PROC[conv: MesaRPC.Conversation] = BEGIN pktSpace: ARRAY[1..RPCLupine.pktOverhead+1] OF WORD; pkt: RPCLupine.StubPkt = RPCLupine.GetStubPkt[@pktSpace]; [] ← RPCLupine.StartCall[pkt, import, conv]; BEGIN length: RPCLupine.DataLength; last: BOOLEAN; pkt[0] ← 1; [length, last] ← RPCLupine.Call[pkt, 1, 1, NIL]; IF NOT last THEN ERROR; END; END; SendPage: PROC[conv: MesaRPC.Conversation, page: CARDINAL] = BEGIN pktSpace: ARRAY[1..RPCLupine.pktOverhead+RPCLupine.maxDataLength] OF WORD; pkt: RPCLupine.StubPkt = RPCLupine.GetStubPkt[@pktSpace]; [] ← RPCLupine.StartCall[pkt, import, conv]; BEGIN length: RPCLupine.DataLength; last: BOOLEAN; pkt[0] ← 0; pkt[1] ← page; [length, last] ← RPCLupine.Call[pkt, RPCLupine.maxDataLength, RPCLupine.maxDataLength, NIL]; IF NOT last THEN ERROR; END; END; TestDispatcher: RPCLupine.Dispatcher = BEGIN -- Dummy dispatcher: consumes args and sends dummy result -- IF NOT lastPkt THEN ERROR; SELECT pkt[0] FROM 0 => AcceptPage[localConversation, pkt[1] ]; 1 => AcceptTransfer[localConversation]; ENDCASE => ERROR; RETURN[0]; END; -- Test version of client code -- -- Sender -- conversation: MesaRPC.Conversation; senderPage: CARDINAL ← 0; NextPage: ENTRY PROC RETURNS[p: CARDINAL] = INLINE { p ← senderPage; senderPage ← senderPage+1 }; Sender: PROC[limit: CARDINAL] = BEGIN DO p: CARDINAL = NextPage[]; IF p > limit THEN EXIT; SendPage[conversation, p]; ENDLOOP; END; -- Receiver -- pageCond: CONDITION ← [timeout:0]; receiverPage: CARDINAL ← 0; AcceptTransfer: ENTRY PROC[conv: MesaRPC.Conversation] = BEGIN receiverPage ← 0; END; AcceptPage: ENTRY PROC[conv: MesaRPC.Conversation, page: CARDINAL] = BEGIN UNTIL receiverPage = page DO WAIT pageCond ENDLOOP; receiverPage ← page + 1; BROADCAST pageCond; END; DoIt: PROC = BEGIN -- Export and import -- instance: STRING ← IF gvExport THEN gvInstance ELSE nongvInstance; import ← RPCLupine.ImportInterface[["RPC-bulk-test"L, instance], [0,0] ! MesaRPC.ImportFailed => IF why = unbound OR why = communications THEN BEGIN [] ← RPCLupine.ExportInterface[exporterName, exporterKey, ["RPC-bulk-test"L, instance], TestDispatcher, [0,0]]; import ← RPCLupine.ImportInterface[["RPC-bulk-test"L, instance],[0,0]]; CONTINUE END ]; BEGIN spyAvailable: BOOLEAN = Runtime.IsBound[SpyClient.StartCounting]; UNTIL quit DO UNTIL userTest DO Process.Pause[Process.SecondsToTicks[5]] ENDLOOP; conversation ← MesaRPC.StartConversation[callerName, callerKey, exporterName, authOnly]; senderPage ← 0; StartTransfer[conversation]; NameInfoSpecialDefs.CleanUp[]; IF spyWanted AND spyAvailable THEN SpyClient.StartCounting[]; BEGIN start: System.Pulses = System.GetClockPulses[]; end: System.Pulses; elapsed: System.Microseconds; first: PROCESS = FORK Sender[tries]; second: PROCESS = FORK Sender[tries]; third: PROCESS = FORK Sender[tries]; fourth: PROCESS = FORK Sender[tries]; --fifth: PROCESS = FORK Sender[tries]; --sixth: PROCESS = FORK Sender[tries]; --seventh: PROCESS = FORK Sender[tries]; JOIN first; JOIN second; JOIN third; JOIN fourth; --JOIN fifth; JOIN sixth; JOIN seventh; end ← System.GetClockPulses[]; IF spyWanted AND spyAvailable THEN SpyClient.StopCounting[]; elapsed ← System.PulsesToMicroseconds[[end-start]]; MesaRPC.EndConversation[conversation]; IF signalFinished THEN SIGNAL Finished[]; END; ENDLOOP; END; END; DoIt[]; END.