-- File: PupPktMgr.mesa, Last Edit: HGM March 14, 1981 11:43 AM DIRECTORY Process USING [ InitializeCondition, InitializeMonitor, DisableTimeout, SetTimeout, MsecToTicks], Storage USING [FreeString], System USING [Pulses, MicrosecondsToPulses], CommUtilDefs USING [LockCode, EnableAborts, UnlockCode], PupPktOps, PupStream USING [CloseReason, PupOpenMode], PupPktDefs USING [PupPktStream], PupDefs USING [ Pair, defaultPupsToAllocate, DataWordsPerPupBuffer, PupAddress, PupBuffer, PupSocketDestroy, PupSocketKick, PupSocketID, Tocks, veryLongWait, veryShortWait], BufferDefs USING [QueueInitialize, QueueCleanup], PupTypes USING [fillInSocketID]; PupPktMgr: MONITOR IMPORTS Process, Storage, System, CommUtilDefs, PupPktOps, PupDefs, BufferDefs EXPORTS PupPktOps, PupStream, PupPktDefs = BEGIN OPEN PupPktOps, PupPktDefs, PupDefs; -- Manager data free: Instance ← START PupPktOps.PupPktHot; GetInstance: ENTRY PROCEDURE RETURNS [him: Instance] = BEGIN IF free = NIL THEN him ← START (NEW PupPktOps.PupPktHot) ELSE BEGIN him ← free; free ← free.next; END; InitializeEverything[him]; IF lockRequeueProcedure THEN CommUtilDefs.LockCode[him.me.get]; -- PupPktHot END; FreeInstance: ENTRY PROCEDURE [him: Instance] = BEGIN IF lockRequeueProcedure THEN CommUtilDefs.UnlockCode[him.me.get]; -- PupPktHot him.next ← free; free ← him; END; lockRequeueProcedure: BOOLEAN ← FALSE; myPing: BOOLEAN ← TRUE; myMaxAllocate, myPathMaxAllocate: CARDINAL ← defaultPupsToAllocate; myMaxBufferSize: CARDINAL ← 0; NoBufferToSend: PUBLIC ERROR = CODE; StreamAlreadyOpen: PUBLIC ERROR = CODE; maxRetransmitPulses: PUBLIC System.Pulses ← System.MicrosecondsToPulses[ 5000000]; minRetransmitPulses: PUBLIC System.Pulses ← System.MicrosecondsToPulses[100000]; initialRetransmitPulses: PUBLIC System.Pulses ← System.MicrosecondsToPulses[ 5000000]; ctlRetransmitPulses: PUBLIC System.Pulses ← System.MicrosecondsToPulses[ 2000000]; pingPulses: PUBLIC System.Pulses ← System.MicrosecondsToPulses[60000000]; SetLockRequeueProcedureFlag: PUBLIC PROCEDURE [lockit: BOOLEAN] = BEGIN lockRequeueProcedure ← lockit; END; PupPktStreamCreate: PUBLIC PROCEDURE [remote: PupAddress, ticks: Tocks] RETURNS [PupPktStream] = BEGIN RETURN[ PupPktStreamMake[PupTypes.fillInSocketID, remote, ticks, sendRfc, [0, 0]]]; END; PupPktStreamMake: PUBLIC PROCEDURE [ local: PupSocketID, remote: PupAddress, ticks: Tocks, mode: PupStream.PupOpenMode, id: Pair] RETURNS [PupPktStream] = BEGIN him: Instance ← GetInstance[]; SELECT ticks FROM veryShortWait => him.dontWait ← TRUE; veryLongWait => Process.DisableTimeout[@him.inputReady]; ENDCASE => Process.SetTimeout[@him.inputReady, ticks]; MakeLocal[ him, local, remote, mode, id ! UNWIND => PupPktStreamDestroy[@him.me]]; RETURN[@him.me]; END; PupPktStreamDestroy: PUBLIC PROCEDURE [ps: PupPktStream] = BEGIN krock: Instance = LOOPHOLE[1234]; offset: INTEGER = @krock.me - LOOPHOLE[krock, POINTER]; him: Instance ← LOOPHOLE[ps - offset]; DestroyLocal[him]; FreeInstance[him]; END; SetMaxAllocation: PUBLIC PROCEDURE [n: CARDINAL] = BEGIN myMaxAllocate ← n; myPathMaxAllocate ← MIN[defaultPupsToAllocate, n]; END; SetMaxBufferSize: PUBLIC PROCEDURE [n: CARDINAL] = BEGIN myMaxBufferSize ← 2*MIN[n, DataWordsPerPupBuffer[]]; END; SetPinging: PUBLIC PROCEDURE [ping: BOOLEAN] = BEGIN myPing ← ping; END; InitializeEverything: PROCEDURE [him: Instance] = BEGIN him.state ← idle; him.c ← NIL; him.dontWait ← FALSE; him.dataBytesPerPup ← 2*DataWordsPerPupBuffer[]; him.outIntPending ← FALSE; him.outEnd ← 0; him.probeCounter ← 0; him.ping ← myPing; him.myMaxAllocate ← myMaxAllocate; him.pathMaxAllocate ← myPathMaxAllocate; him.hisMaxAllocate ← 0; him.throttle ← 0; him.unackedPups ← 0; him.allocatedPups ← 0; him.clumpsSinceBump ← 0; him.sentBuffer ← NIL; him.pleaseDie ← FALSE; him.sameNet ← FALSE; him.sendAck ← FALSE; him.aDataOut ← FALSE; him.retransmitPulses ← initialRetransmitPulses; him.whyClosed ← localClose; him.text ← NIL; him.next ← NIL; BufferDefs.QueueInitialize[@him.inputQueue]; BufferDefs.QueueInitialize[@him.sentQueue]; BEGIN OPEN Process; InitializeCondition[@him.stateChange, MsecToTicks[1000]]; InitializeCondition[@him.retransmitterReady, MsecToTicks[100]]; InitializeCondition[@him.inputReady, MsecToTicks[5000]]; InitializeCondition[@him.waitingForInterrupt, MsecToTicks[5000]]; DisableTimeout[@him.waitingForInterrupt]; CommUtilDefs.EnableAborts[@him.waitingForInterrupt]; InitializeMonitor[@him.lock]; END; IF myMaxBufferSize # 0 THEN him.dataBytesPerPup ← myMaxBufferSize; END; DestroyLocal: PROCEDURE [him: Instance] = BEGIN OPEN him; DestroyLocalLocked[him]; JOIN retransmitterFork; PupSocketKick[socket]; JOIN slurpFork; -- IF sentBuffer#NIL THEN ReturnFreePupBuffer[sentBuffer]; BufferDefs.QueueCleanup[@inputQueue]; BufferDefs.QueueCleanup[@sentQueue]; PupSocketDestroy[socket]; IF text # NIL THEN Storage.FreeString[text]; END; free.next ← NIL; END.