-- 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