SystemImpl.mesa
Copyright (C) 1984, 1985, 1986 by Xerox Corporation. All rights reserved.
Tim Diebert: November 24, 1986 2:56:33 pm PST
DIRECTORY
HostNumbers USING [ProcessorID],
Process USING [SecondsToTicks, SetTimeout],
ProcessorFace USING [GetGreenwichMeanTime, gmtEpoch, processorID],
System;
SystemImpl: CEDAR MONITOR
IMPORTS
Process, ProcessorFace
EXPORTS System = BEGIN
UniversalID: PUBLIC TYPE = MACHINE DEPENDENT RECORD
[processor(0): HostNumbers.ProcessorID, sequence(3): LONG CARDINAL];
NOTE: The fields of a UniversalID should NOT be used as hints as to the location or age of the associated entity (e.g. file, volume).
~~~~~~~~~~ Universal identifiers: ~~~~~~~~~~
Generate new universalID from the processorID and universal id counter.
Sequence field of resultant value always less than
SecondsSinceEpoch[GetGreenwichMeanTime].
oneSecond: CONDITION;
uidCounter: LONG CARDINAL ← 0; -- always <= SecondsSinceEpoch[GetGreenwichMeanTime[]]
uidCounterValid: BOOLEANFALSE;
GetUniversalID: PUBLIC ENTRY PROC RETURNS [UniversalID] = {
ENABLE UNWIND => NULL;
secondsSinceEpoch: LONG CARDINAL;
nextUID: UniversalID;
If clock isn't set, GetGreenwichMeanTime returns gmtEpoch, so uidCounter=0
DO
secondsSinceEpoch ←
ProcessorFace.GetGreenwichMeanTime[] - ProcessorFace.gmtEpoch;
IF secondsSinceEpoch = 0 THEN ERROR;
IF ~uidCounterValid THEN { -- clock set after initialization
uidCounter ← secondsSinceEpoch; uidCounterValid ← TRUE};
IF uidCounter < secondsSinceEpoch THEN EXIT;
WAIT oneSecond;
ENDLOOP;
nextUID ← [processor: LOOPHOLE[ProcessorFace.processorID], sequence: uidCounter];
uidCounter ← uidCounter + 1;
RETURN[nextUID]};
Init: PROC [] = TRUSTED BEGIN
Process.SetTimeout[@oneSecond, Process.SecondsToTicks[1]];
END;
Init[];
END.