FSLockTableImpl.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Russ Atkinson (RRA) October 17, 1985 6:31:44 pm PDT
DIRECTORY
Basics USING [BITXOR, HighHalf, LowHalf],
FSLock USING [ActiveFile, ActiveFileObject],
FSBackdoor USING [Version],
Rope USING [Concat, Equal, Match, ROPE],
RopeHash USING [FromRope];
FSLockTableImpl: CEDAR MONITOR
IMPORTS Basics, Rope, RopeHash
EXPORTS FSLock
= {
ROPE: TYPE = Rope.ROPE;
Exported to FSLock
LookupLock: PUBLIC ENTRY PROC [prefix, nameBody: ROPE, version: FSBackdoor.Version] RETURNS [a: FSLock.ActiveFile] = {
ENABLE UNWIND => NULL;
hash: CARDINAL;
IF NOT Rope.Match["[*", nameBody] THEN nameBody ← Rope.Concat[prefix, nameBody];
hash ← RopeHash.FromRope[rope: nameBody, case: FALSE, seed: version] MOD buckets;
stats.lookups ← stats.lookups + 1;
FOR a ← lockTbl[hash], a.next UNTIL a = NIL DO
IF version = a.version AND Rope.Equal[nameBody, a.nameBody, FALSE] THEN RETURN;
ENDLOOP;
stats.newActiveFiles ← stats.newActiveFiles + 1;
a ← NEW [FSLock.ActiveFileObject];
a.nameBody ← nameBody;
a.version ← version;
a.h ← NIL;
a.fileLock ← none;
a.recordLock ← FALSE;
a.fileLockCount ← 0;
a.attachedTo ← NIL;
a.next ← lockTbl[hash];
lockTbl[hash] ← a;
};
RemoveLock: PUBLIC ENTRY PROC [a: FSLock.ActiveFile] = {
ENABLE UNWIND => NULL;
hash: CARDINAL = RopeHash.FromRope[rope: a.nameBody, case: FALSE, seed: a.version] MOD buckets;
aPrev: FSLock.ActiveFile ← lockTbl[hash];
stats.removals ← stats.removals + 1;
IF aPrev = a
THEN lockTbl[hash] ← a.next
ELSE DO
IF aPrev.next = a THEN {aPrev.next ← a.next; EXIT};
aPrev ← aPrev.next;
ENDLOOP;
a.nameBody ← NIL;
};
RecordREF: PUBLIC ENTRY PROC [r: REF] = {
p: REF PRTEntry = NEW [PRTEntry];
hash: CARDINAL = RefHash[r];
p.ref ← r;
p.chain ← prt[hash];
prt[hash] ← p;
stats.prtRecorded ← stats.prtRecorded + 1;
};
RemoveREF: PUBLIC ENTRY PROC [r: REF] = {
hash: CARDINAL = RefHash[r];
p, q: REF PRTEntry;
q ← prt[hash];
IF q.ref = r
THEN prt[hash] ← q.chain
ELSE DO
p ← q;
q ← q.chain;
IF q.ref = r THEN {p.chain ← q.chain; EXIT};
ENDLOOP;
q.ref ← NIL;
stats.prtRemoved ← stats.prtRemoved + 1;
};
Statistics
StatsRecord: TYPE = RECORD [
lookups: INT ← 0,
newActiveFiles: INT ← 0,
removals: INT ← 0,
prtRecorded: INT ← 0,
prtRemoved: INT ← 0
];
stats: REF StatsRecord = NEW[StatsRecord];
Lock Table
buckets: CARDINAL = 109;
LockTable: TYPE = ARRAY [0..buckets) OF FSLock.ActiveFile;
lockTbl: REF LockTable ← NEW [LockTable ← ALL[NIL]];
Package Reference Table
prtBuckets: CARDINAL = 109;
PackageReferenceTable: TYPE = ARRAY [0..prtBuckets) OF REF PRTEntry;
PRTEntry: TYPE = RECORD [chain: REF PRTEntry, ref: REF];
prt: REF PackageReferenceTable ← NEW [PackageReferenceTable ← ALL[NIL]];
RefHash: PROC [r: REF] RETURNS [CARDINAL] = INLINE {
RETURN [Basics.BITXOR[Basics.LowHalf[LOOPHOLE[r, LONG CARDINAL]], Basics.HighHalf[LOOPHOLE[r, LONG CARDINAL]]] MOD prtBuckets];
};
}.