-- Transaction>TransactionInternal.mesa (last edited by Luniewski on January 30, 1981 5:16 PM)
-- This interface defines types, constants, and global variables which are private to the Transaction implementation software, and supplies the procedural interface between TransactionStateImpl and TransactionLogImpl.
DIRECTORY
Environment USING [PageCount, PageNumber, wordsPerPage],
Inline USING [LowHalf],
File USING [delete, grow, ID, PageCount, PageNumber, Permissions, read, shrink, write],
MiscAlpha USING [aCHKSUM],
Mopcodes USING [zMISC],
SimpleSpace USING [Handle, WindowOrigin],
Space USING [PageCount],
SpecialTransaction USING [OptionalCrash],
TransactionState USING [LogEntry, LogEntryPtr, FileOps, SpaceNodePtr];
TransactionInternal: DEFINITIONS
IMPORTS Inline =
BEGIN
FilePageNumber: TYPE = Environment.PageNumber; -- = LowHalf[File.PageNumber]. We will never use more than 2**16 pages in a log file, and would rather not store the extra bits.
FilePageCount: TYPE = Environment.PageCount; -- = LowHalf[File.PageCount]. We will never use more than 2**16 pages in a log file, and would rather not store the extra bits.
permissions: File.Permissions = File.read+File.write+File.grow+File.shrink+File.delete; -- to save space in the State Table, we only save the File.ID of a Log File. Since we created all of these files ourselves, we can reasonably supply any permissions we want.
TxIndex: TYPE = CARDINAL [0..77B]; -- (six bits) defines the maximum number of simultaneously active transactions.
nullTxIndex: TxIndex = LAST[TxIndex]; -- Must be LAST[]! This entry in the State Table is never used for a transaction. Instead, it holds checking information which is used to verify that the entire State Table has been written on the disk, as follows: a serial number is written in every entry in the State Table, before it is written on the disk; When the State Table is read from the disk during Crash REcovery, if the serial number of the last entry (i.e. state[nullTxIndex] ) matches that of all previous entries, it indicates that all of the previous entries were sucessfully written on the disk.
ValidTxIndex: TYPE = TxIndex[ FIRST[TxIndex] .. nullTxIndex - 1 ];
TxEdition: TYPE = CARDINAL [0..1777B]; -- (ten bits) identifies current edition of a particular transaction handle.
invalidTxEdition: TxEdition = FIRST[TxEdition]; -- used for nullHandle. Also, zero is the most likely value to be supplied by malfunctioning hardware/software.
ValidTxEdition: TYPE = TxEdition[ invalidTxEdition+1 .. LAST[TxEdition] ];
-- Note: TxIndex and TxEdition must total 16 bits or less, so that a Transaction.Handle will fit in one word.
Handle: TYPE = RECORD [txEdition: TxEdition, index: TxIndex]; -- the concrete type for a Transaction.Handle.
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- Transaction State Table (describes state of all current transactions)
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
StateFormatVersion: TYPE = RECORD [ CARDINAL ]; -- could be less than 16 bits.
stateFormatVersion: StateFormatVersion = [1]; -- change this every time the format of the State Table / State Data changes! (in a non-backward compatible manner) Changing this value invalidates all existing Transaction State files. Clients must be warned to run their old system past crash recovery and shut down cleanly before installing the new system.
StateEdition: TYPE = CARDINAL; -- (could be less than a full word)
State: TYPE = ARRAY TxIndex OF TxDescriptor; -- the State Table. Records the state of all current transactions, active or inactive.
-- A TxDescriptor records the state of one transaction. If you change its format (in a non-backward compatible manner), change stateFormatVersion! (unless you want to test crash recovery of the State Table)
TxDescriptor: TYPE = MACHINE DEPENDENT RECORD [ -- MACH DEP so that format is stable over compiler versions.
stateEdition (0: 0..15): StateEdition, -- a copy of currentStateEdition. First field of TxDesc so that a correct value indicates that all of the previous TxDesc, and at least the first word of this TxDesc, got written on the disk.
seal (1: 0..15): StateFormatVersion ← stateFormatVersion, -- identifies version of format of TxDesc and State.
txEdition (8: 0..9): TxEdition, -- identifies the current edition of this transaction. Not relevant to crash recovery.
fileInUse (8: 10..10): BOOLEAN, -- tells whether this transaction has actually begun using logFile yet. Not relevant to crash recovery.
logFile (2: 0..79): File.ID, -- the log file available for or being used by this transaction.
logFileSize (7: 0..15): FilePageCount, -- current size of logFile. Not relevant to crash recovery.
fill (8: 11..12): [0..1] ← 0,
vp (8: 13..79): SELECT status (8: 13..13): Status FROM
active => [ -- becomes active at Begin[], becomes free at completion of Commit, Abort, or Crash Recovery.
noMoreOperations (8: 14..14): BOOLEAN, -- no more logging operations allowed. Not relevant to crash recovery.
committed (8: 15..15): BOOLEAN, -- all changes to client’s files have been made on the disk.
spaceList (9: 0..31): TransactionState.SpaceNodePtr, -- head of list of Spaces involved in transaction. Not relevant to crash recovery.
pageFree (11: 0..15): FilePageNumber, -- first page of logFile not used yet. Not relevant to crash recovery.
countPrevLogEntry (12: 0..15): FilePageCount ], -- length of last log entry made (header + any data). Not relevant to crash recovery.
free => [ fill2 (8: 14..15): [0..1] ← 0 ], -- (fill out to a word boundary)
ENDCASE ];
TxDescPtr: TYPE = LONG POINTER TO TxDescriptor;
ActiveTxDescPtr: TYPE = LONG POINTER TO active TxDescriptor;
Status: TYPE = MACHINE DEPENDENT { active (0), free (1) }; -- status of a transaction Desc.
StateData: TYPE = MACHINE DEPENDENT RECORD [ -- layout of data written to the disk.
state (0): State, -- must be first field in record! (see InitializeStateB)
checksumData (832): ChecksumData ]; -- checksum of all previous words in StateData.
stateCount: Space.PageCount = (SIZE[StateData] + Environment.wordsPerPage-1) / Environment.wordsPerPage;
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- Transaction Log File (contains "undo" data for a single transaction)
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LogFileFormatVersion: TYPE = RECORD[ CARDINAL ]; -- could be less than 16 bits.
logFileFormatVersion: LogFileFormatVersion = [123456B]; -- change this every time the format of the Log File changes (in a non-backward compatible manner)! Changing this value invalidates all existing Transaction Log Files. Clients must be warned to run their old system past crash recovery and shut down cleanly before installing the new system.
LogFileEntry: TYPE = MACHINE DEPENDENT RECORD [
seal (0: 0..15): LogFileFormatVersion ← logFileFormatVersion, -- for Crash Recovery.
transactionHandle (1: 0..15): Handle, -- for Crash Recovery, just to help weed out obsolete log file contents.
countPrevEntry (2: 0..15): FilePageCount ← 0, -- size of previous LogFileEntry (header + any data).
op (3: 0..223): TransactionState.LogEntry, -- describes "undo" action for Abort and Crash Recovery.
spare (17: 0..31): LONG CARDINAL ← 0, -- (for future expansion)
transactionHandle2 (19: 0..15): Handle ]; -- a copy of transactionHandle. For Crash Recovery.
LogFileEntryPtr: TYPE = LONG POINTER TO LogFileEntry;
LogFileEntryData: TYPE = MACHINE DEPENDENT RECORD [ -- layout of data written to the disk.
logFileEntry (0): LogFileEntry,
checksumData (20): ChecksumData ]; -- checksum of all previous words in this LogFileEntry.
countLogEntry: Environment.PageCount = 1; -- at present, each log entry is written into a separate whole page. ( + any pages containing data)
standardLogFileCount: FilePageCount = 10; -- size of log files when not in use.
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- Procedures and variables
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- Inlines:
Checksum: PROCEDURE [cksumOfOtherData: CARDINAL, nWords: CARDINAL, p: LONG POINTER] RETURNS [cksum: ChecksumData] =
MACHINE CODE BEGIN Mopcodes.zMISC, MiscAlpha.aCHKSUM END; -- should be in Inline!
ChecksumData: TYPE = CARDINAL;
ShortenPageCount: PROCEDURE [fileCount: File.PageCount] RETURNS [FilePageCount] = INLINE {RETURN[Inline.LowHalf[fileCount]]}; -- (there’s a LOOPHOLE here)
ShortenPageNumber: PROCEDURE [filePage: File.PageNumber] RETURNS [FilePageNumber] = INLINE {RETURN[Inline.LowHalf[filePage]]}; -- (there’s a LOOPHOLE here)
-- Exported by TransactionStateImpl:
disabled: BOOLEAN; -- TRUE forces all (public) transaction operations to no-op.
state: LONG POINTER TO State; -- the State Table. (LOOPHOLE[state] is also a pointer to stateData)
stateSpace: SimpleSpace.Handle; -- the working copy of the state in VM.
state1Window, state2Window: SimpleSpace.WindowOrigin; -- the two representatives for the stable storage containing the state table.
MaybeCrash: SpecialTransaction.OptionalCrash --[unimportance: SpecialTransaction.Unimportance]--;
-- For testing only, calls client-supplied procedure to crash Pilot at critical points.
UpdateStateFile: --INTERNAL-- PROCEDURE [];
-- Writes two copies of the State Table onto the disk.
-- Exported by TransactionLogImpl:
InitializeLogsA: --INTERNAL-- PROCEDURE [];
-- Creates simple spaces. Must be called early during Pilot initialization.
InitializeLogsB: --INTERNAL-- PROCEDURE [];
LogInternal: --INTERNAL-- PROCEDURE [txi: ValidTxIndex, op: TransactionState.LogEntryPtr, fileOps: TransactionState.FileOps];
-- Internal version of TransactionState.Log (q.v.).
-- May raise Volume.InsufficientSpace.
END.
LOG
June 10, 1980 9:37 PMGobbelCreated file.
July 19, 1980 9:52 AMMcJonesAdjusted field positions in LogEntry for 80-bit universal ids, made first64K READONLY.
July 22, 1980 12:05 PMFayAdded Handle to get around exported type clash between TransactionImpl and TransactionStateImpl.
July 22, 1980 3:28 PMGobbelMake it work.
September 2, 1980 3:09 PMKnutsenAdded Log File defs, ValidTxIndex, LogInternal, parameters to LogsA/B. Removed ProcessLog.
September 11, 1980 5:17 PMKnutsenRestore MACHINE DEPENDENTness.
September 12, 1980 1:47 PMGobbelStarted stateFormatVersion over at 1, to be incremented for future changes.
September 25, 1980 12:52 PMGobbelAdded MaybeCrash.
January 24, 1981 3:15 PMGobbelNull edit to fix creation dates (you don’t want to know).
January 30, 1981 5:16 PMLuniewskiChanged Shorten* to be Inline’s instead of being equated to Inlines (Compiler bug).