-- LockTestImpl.mesa -- Last edited by -- MBrown on January 11, 1983 11:17 pm DIRECTORY AlpineEnvironment, AlpineInternal, Lock, LockControl, LockWatchdog, Process, TransactionMap; LockTestImpl: MONITOR IMPORTS Lock, LockControl, LockWatchdog, Process EXPORTS AlpineInternal, TransactionMap = BEGIN LockID: TYPE = Lock.LockID; LockMode: TYPE = Lock.LockMode; TransObject: PUBLIC TYPE = RECORD [ -- AlpineInternal.TransObject id: NAT, locks: AlpineInternal.LockTransHeaderHandle ← NIL ]; Handle: TYPE = REF TransObject; GetLockHeader: PUBLIC PROC [self: Handle] RETURNS [lockHeader: AlpineInternal.LockTransHeaderHandle] = { -- TransactionMap.GetLockHeader RETURN[self.locks]; }; AbortUnilaterally: PUBLIC PROC [self: Handle, why: AlpineEnvironment.LockFailure] = { -- TransactionMap.AbortUnilaterally LockControl.AbortWaitingRequests[self, why]; }; ConsTrans: PROC [id: NAT] RETURNS [Handle] = { h: Handle ← NEW[TransObject ← [id: id]]; h.locks ← LockControl.ConsTransHeader[h]; RETURN[h]; }; seq: LONG CARDINAL ← 1; GenerateLockID: PROC [] RETURNS [LockID] = { ID4: TYPE = RECORD [a, b, c, d: LONG CARDINAL]; id: ID4 ← [0, 0, 0, seq]; seq ← seq + 1; RETURN [LOOPHOLE[id]]; }; LockSetProcessResult: TYPE = {ok, aborting, conflict, deadlock, timeout}; LockSetProcess: PROC [ trans: AlpineInternal.TransHandle, lock: LockID, mode: LockMode, wait: BOOL ← TRUE] RETURNS [result: LockSetProcessResult] = { result ← ok; [] ← Lock.Set[trans, lock, mode, wait ! Lock.Failed => { SELECT why FROM aborting => result ← aborting; conflict => result ← conflict; deadlock => result ← deadlock; timeout => result ← timeout; ENDCASE; CONTINUE }]; }; LockTestHere: SIGNAL = CODE; Test: PROC [] = { LockControl.Initialize[lockZoneInitialSize: 0, hashArraySize: 32]; LockWatchdog.Initialize[ deadlockCheckingPeriod: Process.SecondsToTicks[5], timeoutCheckingPeriod: Process.SecondsToTicks[5], abortWaitingTransInterval: 60 ]; { p0, p1, p2, p3, p4, p5, p6: PROCESS RETURNS [LockSetProcessResult]; r0, r1, r2, r3, r4, r5, r6: LockSetProcessResult; t1: Handle = ConsTrans[1]; t2: Handle = ConsTrans[2]; t3: Handle = ConsTrans[3]; t4: Handle = ConsTrans[4]; t5: Handle = ConsTrans[5]; t6: Handle = ConsTrans[6]; l1: LockID = GenerateLockID[]; l2: LockID = GenerateLockID[]; l3: LockID = GenerateLockID[]; l4: LockID = GenerateLockID[]; l5: LockID = GenerateLockID[]; [] ← Lock.Set[t1, l1, write]; [] ← Lock.Set[t2, l2, write]; [] ← Lock.Set[t3, l3, write]; [] ← Lock.Set[t4, l4, write]; [] ← Lock.Set[t5, l5, write]; p6 ← FORK LockSetProcess[t6, l1, read]; Process.Pause[2]; p5 ← FORK LockSetProcess[t1, l2, read]; Process.Pause[2]; p4 ← FORK LockSetProcess[t2, l3, read]; Process.Pause[2]; p3 ← FORK LockSetProcess[t2, l4, read]; Process.Pause[2]; p2 ← FORK LockSetProcess[t4, l3, read]; Process.Pause[2]; p1 ← FORK LockSetProcess[t4, l1, read]; Process.Pause[2]; p0 ← FORK LockSetProcess[t3, l5, read]; Process.Pause[2]; SIGNAL LockTestHere; r0 ← JOIN p0; r1 ← JOIN p1; r2 ← JOIN p2; r3 ← JOIN p3; r4 ← JOIN p4; r5 ← JOIN p5; r6 ← JOIN p6; }; }; END.--LockTestImpl