Cedar Nucleus: Interface with Germ.
GermSwapImpl.mesa
Andrew Birrell May 26, 1983 9:28 am
Last Edited by: Levin, June 14, 1983 4:48 pm
DIRECTORY
BootFile USING [MDSIndex],
GermSwap USING [gCross, lCross, LP, mdsiGerm, nGCross, nLCross, pMon, pRequest, ReadMDS, Request, Switches],
PrincOps USING [Port, SD, sBootSwitches, TrapLink],
PrincOpsUtils USING [COPY, Free, LongCOPY, MyGlobalFrame, MyLocalFrame, WriteMDS];
GermSwapImpl: PROGRAM
IMPORTS GermSwap, PrincOpsUtils
EXPORTS GermSwap
SHARES GermSwap =
BEGIN
Initialisation
Initialize: PUBLIC PROCEDURE [mdsiOther: BootFile.MDSIndex] =
BEGIN
Strategy: GermSwap.gCross and lCross are allocated in each MDS, initialised identically.
OPEN port: LOOPHOLE[Port, PrincOps.Port];
InitializeMDS[];
Set up frame for Procedure and make it pending on Port
port.dest ← [frame[PrincOpsUtils.MyLocalFrame[]]]; -- temporarily connect Port to self
Procedure[];
Now set up local and global frames with copy in other MDS
GermSwap.lCross.accesslink ← GermSwap.gCross;
GermSwap.lCross.pc ← port.frame.pc;
GermSwap.lCross.returnlink ← PrincOps.TrapLink;
PrincOpsUtils.Free[port.frame];
port.frame ← GermSwap.lCross;
now mustn't set global variables
PrincOpsUtils.COPY[
from: PrincOpsUtils.MyGlobalFrame[],
nwords: GermSwap.nGCross,
to: GermSwap.gCross];
PrincOpsUtils.LongCOPY[
from: GermSwap.lCross,
nwords: GermSwap.nLCross+GermSwap.nGCross,
to: GermSwap.LP[GermSwap.lCross, mdsiOther]];
connect CrossMDSCall to Port
GermSwap.pMon.CrossMDSCall ←
LOOPHOLE[GermSwap.gCross+(@port-LOOPHOLE[PrincOpsUtils.MyGlobalFrame[], POINTER TO PrincOps.Port])];
GermSwap.pMon.pcCross ← GermSwap.lCross.pc
END;
switches: PUBLIC GermSwap.Switches;
bootedFrom: PUBLIC GermSwap.Request;
InitializeMDS: PUBLIC PROCEDURE =
BEGIN
switches ← LOOPHOLE[GermSwap.LP[@PrincOps.SD[PrincOps.sBootSwitches], GermSwap.mdsiGerm], LONG POINTER TO GermSwap.Switches]^;
bootedFrom ← LOOPHOLE[GermSwap.LP[GermSwap.pRequest, GermSwap.mdsiGerm], LONG POINTER TO GermSwap.Request]^;
END;
Cross-MDS co-routine
Port: PORT RETURNS [mdsiOther: BootFile.MDSIndex, Dest: PROCEDURE];
Procedure: PROCEDURE =
BEGIN -- address of this frame must be same in both MDS's; global frames must be "similar"
mdsiOther: BootFile.MDSIndex;
Dest: PROCEDURE;
mdsiBack: BootFile.MDSIndex;
DO
[mdsiOther, Dest] ← Port[];
[Dest, mdsiBack] ← Save2AndWriteMDS[Dest, GermSwap.ReadMDS[], mdsiOther];
Dest[];
PrincOpsUtils.WriteMDS[mdsiBack];
ENDLOOP
END;
Save2AndWriteMDS: PROCEDURE [s1, s2: UNSPECIFIED, mdsi: BootFile.MDSIndex]
RETURNS [t1, t2: UNSPECIFIED] =
LOOPHOLE[PrincOpsUtils.WriteMDS]; -- t1=s1 AND t2=s2!
END.