[ivy]<Satterthwaite>Mimosa>OSMiscOpsImpl.mesa!2

OSMiscOpsImpl.Mesa
Satterthwaite, June 18, 1986 9:51:31 am PDT
Maxwell, August 11, 1983 8:23 am
Paul Rovner, November 19, 1983 5:03 pm
Russ Atkinson (RRA) March 6, 1985 10:05:58 pm PST
DIRECTORY
Basics: TYPE USING [LongNumber],
BasicTime: TYPE USING [GMT, Now, nullGMT],
BcdDefs: TYPE USING [VersionStamp],
OSMiscOps: TYPE USING [Address],
PrincOpsUtils: TYPE USING [BITXOR],
ProcessorFace: TYPE USING [processorID],
VM: TYPE USING [AddressForPageNumber, Allocate, Free, Interval, PageNumber, PageNumberForAddress];
OSMiscOpsImpl: PROGRAM
IMPORTS BasicTime, PrincOpsUtils, ProcessorFace, VM
EXPORTS OSMiscOps = {
bulk free storage management
intervals: LIST OF VM.Interval ← NIL;
Pages: PUBLIC PROC[n: CARDINAL] RETURNS[base: OSMiscOps.Address] = {
IF n = 0 THEN base ← NIL
ELSE {
interval: VM.Interval = VM.Allocate[count: n];
intervals ← CONS[interval, intervals];
base ← VM.AddressForPageNumber[interval.page]};
RETURN};
FreePages: PUBLIC PROC[base: OSMiscOps.Address] = {
page: VM.PageNumber;
last: LIST OF VM.Interval ← NIL;
IF base = NIL THEN RETURN;
page ← VM.PageNumberForAddress[base];
FOR list: LIST OF VM.Interval ← intervals, list.rest UNTIL list = NIL DO
IF list.first.page = page THEN {
VM.Free[list.first];
IF last = NIL THEN intervals ← list.rest ELSE last.rest ← list.rest;
EXIT};
last ← list;
ENDLOOP;
};
version stamp management
GetNetAndHost: PROC RETURNS[net, host: CARDINAL] = {
pId: ARRAY [0..3) OF WORD = LOOPHOLE[ProcessorFace.processorID];
sum: WORD = PrincOpsUtils.BITXOR[pId[0], PrincOpsUtils.BITXOR[pId[1], pId[2]]];
net ← sum/256; host ← sum MOD 256};
lastTime: BasicTime.GMT ← BasicTime.nullGMT;
GenerateUniqueId: PUBLIC PROC RETURNS[BcdDefs.VersionStamp] = {
net, host: CARDINAL;
time: BasicTime.GMT;
[net, host] ← GetNetAndHost[];
DO
time ← BasicTime.Now[];
IF lastTime = BasicTime.nullGMT OR time # lastTime THEN EXIT;
ENDLOOP;
lastTime ← time;
RETURN[[net: net, host: host, time: LOOPHOLE[time, CARD]]]};
new version stamp operations
StampSize: NAT = 3;
Stamp: PUBLIC TYPE = RECORD[word: ARRAY [0..StampSize) OF CARDINAL];
AddStamps: PROC[s1, s2: Stamp] RETURNS[sum: Stamp] = {
carry: [0..1] ← 0;
i: NAT;
FOR i DECREASING IN [0..StampSize) DO
t: Basics.LongNumber ← [lc[s1.word[i].LONG + s2.word[i].LONG + carry.LONG]];
sum.word[i] ← t.lowbits; carry ← t.highbits;
ENDLOOP;
FOR i DECREASING IN [0..StampSize) WHILE carry # 0 DO
t: Basics.LongNumber ← [lc[sum.word[i].LONG + carry.LONG]];
sum.word[i] ← t.lowbits; carry ← t.highbits;
ENDLOOP};
RotateStamp: PROC[s: Stamp] RETURNS[Stamp] = INLINE {RETURN [AddStamps[s, s]]};
MergeStamps: PUBLIC PROC [sum, item: Stamp] RETURNS [Stamp] = {
RETURN[AddStamps[RotateStamp[sum], item]]};
}.