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