{Begin SubSec Saving Interlisp State} {Title Saving Interlisp State} {Text {FnDef {Name LOGOUT} {Args FAST} {Text Stops Interlisp, and returns control to the operating system. From there, it is possible to continue Interlisp as of the {fn LOGOUT}. {fn LOGOUT} will not affect the state of open files. In Interlisp-D, {fn LOGOUT} writes out all altered pages from real memory to the file {lisp Lisp.virtualmem}. This usually takes about 30 seconds on the Xerox 1100. If {arg FAST} is non-{lisp NIL}, Interlisp is stopped without updating {lisp Lisp.virtualmem}. Note that it will not be possible to restart Interlisp from the point of the {fn LOGOUT}, and it may not be possible to restart it at all. Typing {lisp (LOGOUT T)} is preferable to just booting the machine, because it also does other cleanup operations (closing network connections, etc.). In Interlisp-10, if Interlisp was started as a subsidiary fork (see {fn SUBSYS}, {PageRef Fn SUBSYS}), control is returned to the higher fork. }} {note BEFORELOGOUTFORMS and AFTERLOGOUTFORMS evaluated before/after logout in Interlisp-D only! foo!} The function {fn SYSOUT} saves the current state of the Interlisp virtual memory on a file. The file package ({PageRef Tag FilePkg}) can be used to save particular function definitions and other arbitrary objects on files, but {fn SYSOUT} saves the {it total} state of the system. {note This capability can be useful in many situations: creating sysouts for other people to use, using as super-UNDO} The file produced by {fn SYSOUT} (known as "a sysout file",{index sysout file} or simply "a sysout") can be restarted from the operating system (by typing {lisp LISP {arg SYSOUTFILE}} in Interlisp-D or {lisp RUN {arg SYSOUTFILE}} in Interlisp-10). This will restart Interlisp, and restore the virtual memory to the exact state that it had when the sysout file was made. {FnDef {Name SYSOUT} {Args FILE} {Text Saves the current state of the Interlisp virtual memory on the file {arg FILE}, in a form that can be subsequently restarted. The current state of program execution is saved in the sysout file, so {lisp (PROGN (SYSOUT 'FOO) (PRINT 'HELLO))} will cause {lisp HELLO} to be printed after the sysout file is restarted. If {arg FILE} is non-{lisp NIL}, the variable {var SYSOUTFILE}{index SYSOUTFILE Var} is set to the body of {arg FILE}. If {arg FILE} is {lisp NIL}, then the value of {var SYSOUTFILE} instead. Therefore, {lisp (SYSOUT)} will save the current state on the next higher version of a file with the same name as the previous {fn SYSOUT}. Also, if the extension for {arg FILE} is not specified, the value of {var SYSOUT.EXT}{index SYSOUT.EXT Var} is used. This is initially {lisp SYSOUT} in Interlisp-D, {lisp SAV} in Tenex Interlisp-10, and {lisp EXE} in Tops-20 Interlisp-10. {fn SYSOUT} sets {var SYSOUTDATE}{index SYSOUTDATE Var} to {lisp (DATE)}, the time and date that the {fn SYSOUT} was performed. If {fn SYSOUT} was not able to create the sysout file, because of disk or computer error, or because there was not enough space on the directory, {fn SYSOUT} returns {lisp NIL}. Otherwise it returns the full file name of {arg FILE}. Actually, {fn SYSOUT} "returns" twice; when the sysout file is first created, and when it is subsequently restarted. In the latter case, {fn SYSOUT} returns the list {lisp ({arg FILE} . {arg MAKESYSFILE})}, where {arg FILE} is the sysout file, and {arg MAKESYSFILE} is the original Interlisp makesys file (see {fn MAKESYS}, below). For example, {lisp (if (LISTP (SYSOUT 'FOO)) then (PRINT 'HELLO))} will cause {lisp HELLO} to be printed when the sysout file is restarted, but not when {fn SYSOUT} is initially performed. Note: {fn SYSOUT} does not save the state of any open files. {fn WHENCLOSE} ({PageRef Fn WHENCLOSE}) can be used to associate certain operations with open files so that when a {lisp SYSOUT} is started up, these files will be reopened, and file pointers repositioned. }} In Interlisp-10, a sysout file only contains the parts of the virtual memory that the user has changed. When the sysout file is restarted, the other pages are taken from the makesys file of the Interlisp system within which the sysout file was made (see {fn MAKESYS}, below). Therefore, whenever the Interlisp system is reassembled and/or reloaded, old sysout files are {it not} compatible with the new system. In Interlisp-D, a sysout file contains a copy of the entire allocated virtual memory, so it is very large. A normal sized sysout file contains about 4000 pages. Unlike in Interlisp-10, a sysout file is copied into the virtual memory when it is restarted, to it is perfectly permissible to overwrite a sysout file on top of the currently running sysout, for example, {lisp (SYSOUT '{bracket DSK}FOO.SYSOUT;1)} to overwrite {lisp FOO.SYSOUT} on the local disk. Not only is this permissible, it is much faster than making a new sysout file (almost twice as fast, due to less disk overhead). Making a sysout file on the Xerox 1100 currently takes at least 5 minutes. {fn SYSOUT} evaluates the expressions on {var BEFORESYSOUTFORMS}{index BEFORESYSOUTFORMS Var} before creating the sysout file. This variable initially includes expressions to: (1) Set the variables {var SYSOUTDATE} and {var SYSOUTFILE} as described above; (2) Default the sysout file name {arg FILE} according to the values of the variables {var SYSOUTFILE} and {var SYSOUT.EXT}, as described above; and (3) Perform any necessary operations on open files as specified by calls to {fn WHENCLOSE} ({PageRef Fn WHENCLOSE}). After a sysout file is restarted (but {it not} when it is initially created), {fn SYSOUT} evaluates the expressions on {index AFTERSYSOUTFORMS Var}{var AFTERSYSOUTFORMS}. This initially includes expressions to: (1) Perform any necessary operations on previously-opened files as specified by calls to {fn WHENCLOSE} ({PageRef Fn WHENCLOSE}); (2) [Interlisp-10 only] Reset the terminal line length with {fn SETLINELENGTH} ({PageRef Fn SETLINELENGTH}); (3) [Interlisp-10 only] Reset the terminal control characters using {index SETTERMCHARS Fn}{fn SETTERMCHARS} ({PageRef Fn SETTERMCHARS}) if the operating system has changed from Tenex to Tops-20 or vice versa; (4) Possibly print a message, as determined by the value of {var SYSOUTGAG} (see below); and (5) Call {fn SETINITIALS} to reset the initials used for time-stamping ({PageRef Tag TimeStamps}). {VarDef {Name SYSOUTGAG} {Text The value of {var SYSOUTGAG} determines what is printed when a sysout file is restarted. If the value of {var SYSOUTGAG} is a list, the list is evaluated, and no additional message is printed. This allows the user to print a message. If {var SYSOUTGAG} is non-{lisp NIL} and not a list, no message is printed. Finally, if {var SYSOUTGAG} is {lisp NIL} (its initial value), and the sysout file is being restarted by the same user that made the sysout originally, the user is greeted by printing the value of {var HERALDSTRING} (see below) followed by a greeting message. If the {lisp SYSOUT} file was made by a different user, a message is printed, warning that the user profiles may be different (see {PageRef Tag Greeting}); }} {FnDef {Name SYSIN} {Args FILE} {Text [Interlisp-10 only] Restores the state of Interlisp from a sysout file. This is essentially the same as exiting Interlisp, and restarting a sysout file from the operating system executive. If {fn SYSIN} returns {lisp NIL}, there was a problem in reading the file. If {arg FILE} was not found, generates a {lisp FILE NOT FOUND} error. }} {FnDef {Name SYSOUTP} {Args FILE} {Text [Interlisp-10 only] Returns the name of the original Interlisp makesys file (see {fn MAKESYS}, below) if {arg FILE} is a sysout file, otherwise {lisp NIL}. {arg FILE} may also be a JFN. }} {Begin Note} SYSOUT and MAKESYS indicate their progress by altering the cursor, so the system doesn't look quite so dead during these long operations. Note: although likely more convenient, sysout to a file server tends to be markedly slower than sysout to the local disk; remote sysout performance will be significantly improved in subsequent releases. {End Note} {FnDef {FnName MAKESYS} {FnArgs FILE NAME} {Text Used to store a new Interlisp system on the "makesys file" {arg FILE}. Before this is done, the system is "initialized" by undoing the greet history, and clearing the display [Interlisp-D]. When the system is first started up, a "herald" is printed identifying the system, typically "{lisp Interlisp-{arg XX} {arg DATE} ...}". If {arg NAME} is non-{lisp NIL}, {fn MAKESYS} will use it instead of {lisp Interlisp-{arg XX}} in the herald. {fn MAKESYS} sets {Var HERALDSTRING}{index HERALDSTRING Var} to the herald string printed out. {fn MAKESYS} also sets the variable {index MAKESYSDATE Var}{var MAKESYSDATE} to {lisp (DATE)}, i.e. the time and date the system was made. }} {Begin Note} what use is HERALD if MAKESYS calls it? de-documented. (HERALD STRING) Makes {arg STRING} be the 'herald' for the system, i.e. the message printed when the system is first started. Primarily for use in conjunction with {fn MAKESYS}. {fn MAKESYS} is advised to set the variable {var HERALDSTRING} {index HERALDSTRING Var} to the concatenation of {lisp "Interlisp-10",} the month and day of the {fn MAKESYS}, and "..." and to call {fn HERALD} on this string. {End Note} {note MAKESYS evals forms on BEFOREMAKESYSFORMS, which undo greet history, set MAKESYSDATE, and call HAROLD} In Interlisp-D, {fn MAKESYS} is almost the same as {fn SYSOUT}, except that it does some cleaning-up operations (such as clearing the screen). In Interlisp-10, however, {fn MAKESYS} is considerably different from {fn SYSOUT}, because it saves {it all} of the pages in the Interlisp virtual memory, and allows the makesys file to be shared between multiple users. {index shared pages} {index private pages} The Interlisp-10 system initially obtained by the user is shared; that is, all active users of Interlisp-10 are actually using the same pages of memory. As a user adds to the system, private pages are added to his memory. Similarly, if the user changes anything in the original shared Interlisp-10, for example, by advising a system function, a private copy of the changed page is created. In addition to the swapping time saved by having several users accessing the same memory, the sharing mechanism permits a large saving in garbage collection time, since it is not necessary to garbage collect any data in the shared system, and thus Interlisp-10 does not need to chase from any pointers on shared pages during garbage collections. This reduction in garbage collection time is possible because the shared system usually is not modified very much by the user. If the shared system is changed extensively, the savings in time will vanish, because once a page that was initially shared is made private, every pointer on it must be assumed active, because it may be pointed {it to} by something in the shared system. Since every pointer on an initially shared but now private page can also point to {it private} data, they must always be chased. A user may create his own shared system with the function {fn MAKESYS}. If several people are using the same system, making the system be shared will result in a savings in swapping time. Similarly, if a system is large and seldom modified, making it be shared will result in a reduction of garbage collection time, and may therefore be worthwhile even if the system is only being used by one user. One problem with using {fn MAKESYS} in Interlisp-10 is that it may protect large amounts of useless data from being garbage collected. For example, suppose that during the course of building an Interlisp system, a large number of list cells are used and discarded. If {fn MAKESYS} is now executed to store the system, all of that list cell space is stored, and protected from garbage collection (unless the user changes those pages, making a personal copy). To solve this problem, it is necessary to make sure that as little storage as possible is allocated while creating a new system, perhaps by setting {fn MINFS} ({PageRef Fn MINFS}) to a very low value. Of course, this will slow down Interlisp considerably, so making a new system will take a long time. }{End SubSec Saving Interlisp State}