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: BOOLEAN ← FALSE;
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.