-- File: CedarSnapshot.mesa
-- last edited by Levin:  June 1, 1982 9:17 am

DIRECTORY
  Space USING [Handle],
  Volume USING [ID, nullID];

CedarSnapshot: DEFINITIONS =

BEGIN

Outcome: TYPE = {
  checkpointed, potentiallyDangerousCodeLinks, insufficientDiskSpace,
  transactionsInProgress, rolledBack, overwrittenBcd};
CheckpointOutcome: TYPE = Outcome[checkpointed..transactionsInProgress];
RollbackOutcome: TYPE = Outcome[rolledBack..overwrittenBcd];
RiskyCheckpoint: TYPE = Outcome[potentiallyDangerousCodeLinks..potentiallyDangerousCodeLinks];
FailedCheckPoint: TYPE = Outcome[insufficientDiskSpace..transactionsInProgress];
FailedRollback: TYPE = Outcome[overwrittenBcd..overwrittenBcd];

Checkpoint: PROCEDURE [volume: Volume.ID ← Volume.nullID]
  RETURNS [outcome: Outcome];
  -- Checkpoint saves the volatile virtual memory state (i.e., all virtual memory
  -- spaces backed by anonymous secondary storage).  In addition, it invokes
  -- each registered CheckpointProc once, giving it the opportunity to request that
  -- other parts of virtual memory (i.e. parts backed by named secondary storage)
  -- be saved as well (see the description of Register, below).  If sufficient
  -- disk space is available, Checkpoint returns Outcome[checkpointed],
  -- otherwise, it returns Outcome[insufficientDiskSpace].  When Rollback (see below)
  -- is invoked, the saved state is restored, causing the program to appear to be
  -- inside Checkpoint again.  However, this time, it will return Outcome[rolledBack].
  -- Checkpoint guarantees that the anonymous memory state, as well as the state of any
  -- registered spaces, is preserved; however, changes in named files on disk that
  -- are mapped to virtual memory at the time of the Checkpoint may cause unexpected
  -- behavior at Rollback time.  (The most likely symptoms are File.Unknown or
  -- address faults when such areas of virtual memory are touched after Rollback.)
  -- Checkpoint saves all state information in a file on the argument volume; if
  -- the parameter is defaulted, the system volume is used.  This checkpoint file is
  -- automatically deleted when the volume on which it resides is booted.

RollBack: PROCEDURE [volume: Volume.ID ← Volume.nullID];
  -- A call on this procedure normally causes the invoking environment to disappear.
  -- The state previously saved by Checkpoint on the argument volume is restored
  -- (see above), and control is transferred to it.  (If volume is defaulted, the
  -- system volume is used.)  If no checkpointed state can be found, Rollback simply
  -- returns to its caller.  After the rollback is completed, each registered
  -- RollbackProc (see Register, below) is invoked once.

Delete: PROCEDURE [volume: Volume.ID ← Volume.nullID];
  -- This procedure causes the checkpointed state stored on the argument volume
  -- (if defaulted, the system volume) to be deleted.  A subsequent Rollback will
  -- have no effect.  This procedure has no effect on the registered CheckpointProcs
  -- and RollbackProcs.

CheckpointProc: TYPE = PROCEDURE [AddSpaceProc];
RollbackProc: TYPE = PROCEDURE [After];
AddSpaceProc: TYPE = PROCEDURE [Space.Handle];
After: TYPE = {checkpoint, rollback};

Register: PROCEDURE [c: CheckpointProc ← NIL, r: RollbackProc ← NIL];
  -- Clients of this interface may register procedures with the checkpoint mechanism
  -- at any time prior to the invocation of Checkpoint.  Checkpoint invokes each
  -- registered CheckpointProc once before constructing the checkpoint and passes
  -- an AddSpaceProc to be used to tell the checkpoint mechanism what space or spaces
  -- are to be included in the saved state.  Each mapped portion of such a space must
  -- be backed by a named file (i.e., its backing storage must not have been acquired
  -- by mapping to Space.defaultWindow).  Although the entire space need not be mapped,
  -- any mapped subspace must be writable.  The AddSpaceProc may be invoked only from
  -- within the CheckpointProc invoked by Checkpoint.  Checkpoint procs are invoked
  -- in the opposite order in which they were registered, i.e., the most recently
  -- registered procedure is invoked first and the least recently registered one is
  -- invoked last.  RollbackProcs are invoked after a checkpoint (even if the
  -- checkpoint was unsuccessful) and after a RollBack.  In both cases, they are
  -- executed in the order in which they were registered, i.e. the least recently
  -- registered procedure is executed first and the most recently registered one is
  -- executed last.

Deregister: PROCEDURE [c: CheckpointProc ← NIL, r: RollbackProc ← NIL];
  -- A client may use this procedure to cancel a previously registered CheckpointProc
  -- and/or RollbackProc.

END.