Initial commit

master
Robert Strandh 11 years ago
commit 12040bc919

@ -0,0 +1,35 @@
NAME=lispos
TEXFILES=$(NAME).tex $(shell ./tex-dependencies $(NAME).tex)
BIBFILES=$(NAME).bib
PDF_T=$(shell ./strip-dependence inputfig $(TEXFILES))
VERBATIM=$(shell ./strip-dependence verbatimtabinput $(TEXFILES))
CODEFILES=$(shell ./strip-dependence inputcode $(TEXFILES))
PDF=$(subst .pdf_t,.pdf,$(PDF_T))
all : $(NAME).pdf
%.pdf: %.fig
fig2dev -Lpdftex -m 0.75 $< $@
%.pdf_t: %.fig %.pdf
fig2dev -Lpdftex_t -m 0.75 -p $(basename $<).pdf $< $@
%.code: %.lisp
./codify $<
$(NAME).pdf: $(TEXFILES) $(PDF) $(PDF_T) $(VERBATIM) $(CODEFILES) $(BIBFILES)
pdflatex $<
makeindex $(NAME)
bibtex $(NAME)
pdflatex $<
pdflatex $<
view: $(NAME).pdf
xpdf $<
clean:
rm -f *.aux *.log *~ *.pdf *.pdf *.pdf_t *.bbl *.blg
spotless: clean
rm -f *.ps *.dvi *.pdf *.pdf_t *.toc *.idx *.ilg *.ind *.fig.bak

@ -0,0 +1,94 @@
\chapter{All standard macros}
\label{app-all-standard-macros}
\texttt{and}
\texttt{assert}
\texttt{call-method}
\texttt{case}
\texttt{ccase}
\texttt{check-type}
\texttt{cond}
\texttt{ctypecase}
\texttt{declaim}
\texttt{decf}
\texttt{defclass}
\texttt{defconstant}
\texttt{defgeneric}
\texttt{define-compiler-macro}
\texttt{define-condition}
\texttt{define-method-combination}
\texttt{define-modify-macro}
\texttt{define-setf-expander}
\texttt{define-symbol-macro}
\texttt{defmacro}
\texttt{defmethod}
\texttt{defpackage}
\texttt{defparameter}
\texttt{defsetf}
\texttt{defstruct}
\texttt{deftype}
\texttt{defun}
\texttt{defvar}
\texttt{destructuring-bind}
\texttt{do}
\texttt{do*}
\texttt{do-all-symbols}
\texttt{do-external-symbols}
\texttt{do-symbols}
\texttt{dolist}
\texttt{dotimes}
\texttt{ecase}
\texttt{etypecase}
\texttt{formatter}
\texttt{handler-bind}
\texttt{handler-case}
\texttt{ignore-errors}
\texttt{in-package}
\texttt{incf}
\texttt{lambda}
\texttt{loop}
\texttt{loop-finish}
\texttt{multiple-value-bind}
\texttt{multiple-value-list}
\texttt{multiple-value-setq}
\texttt{nth-value}
\texttt{or}
\texttt{pop}
\texttt{pprint-exit-if-list-exhausted}
\texttt{pprint-logical-block}
\texttt{pprint-pop}
\texttt{print-unreadable-object}
\texttt{prog}
\texttt{prog*}
\texttt{prog1}
\texttt{prog2}
\texttt{psetf}
\texttt{psetq}
\texttt{push}
\texttt{pushnew}
\texttt{remf}
\texttt{restart-bind}
\texttt{restart-case}
\texttt{return}
\texttt{rotatef}
\texttt{setf}
\texttt{shiftf}
\texttt{step}
\texttt{time}
\texttt{trace}
\texttt{typecase}
\texttt{unless}
\texttt{untrace}
\texttt{when}
\texttt{with-accessors}
\texttt{with-compilation-unit}
\texttt{with-condition-restarts}
\texttt{with-hash-table-iterator}
\texttt{with-input-from-string}
\texttt{with-open-file}
\texttt{with-open-stream}
\texttt{with-output-to-string}
\texttt{with-package-iterator}
\texttt{with-simple-restart}
\texttt{with-slots}
\texttt{with-standard-io-syntax}

@ -0,0 +1,55 @@
\chapter{Environments}
\label{chap-environments}
Recall that an \emph{environment} is a mapping from \emph{names} to
\emph{objects}. This mapping consists of a set of \emph{bindings}.
When a user is created in the system, a \emph{default global
environment} is created for that user. The global environment of a
user consists of a \emph{system-wide} environment and a
\emph{user-specific} environment.
The system-wide environment consists of bindings that are themselves
immutable (i.e., the user is not allowed to alter the binding) such as
the binding of the symbol \texttt{cl:length} to the function that
returns the length of a sequence. The objects of these bindings are
also immutable, such as the length function itself. The system-wide
environment is the same for every user, allowing the installation of
software that is immediately visible to all users.
The user-specific environment consists of bindings that are created by
the user. These bindings are of three different kinds:
\begin{itemize}
\item Bindings created by the user for instance as a result of
executing a \texttt{defparameter} or \texttt{defun} form.
\item Default system-wide bindings that can be altered by the user,
such as the value of \texttt{*print-base*}.
\item Immutable bindings where the \emph{object} can be modified by
the user, such as system-defined generic functions to which the user
is allowed to add specific methods. Each user has a private copy of
such objects.
\end{itemize}
When a function or method object is created as a result of calling
\texttt{compile} on a lambda expression, or as a result of loading a
\emph{fasl} file, the object is \emph{linked} to the current global
environment, in that external references are then resolved. When such
a function or method object is given to a different user, that
different user can execute it, but external references in it will
still refer to the environment into which it was compiled or loaded.
This mechanism provides an efficient method of protection. A user A
can grant controlled access to part of his or her global environment
by allowing a user B to execute a function made available to him or
her through the \emph{object store}. \seechap{chap-object-store}
In a traditional modern operating system such as Unix, this kind of
controlled access required the use of the \emph{setuid} mechanism,
simply because in such a system there is no way to access an object
other than through the global file system, and the accessing user must
have the right permissions to access the object.
The same mechanism can be used by the system itself to protect objects
that would be unwise to give users direct access to, such as disks or
printers.

@ -0,0 +1,311 @@
\chapter{Introduction}
\pagenumbering{arabic}
\section{What a Lisp operating system is}
A Lisp Operating System (LispOS for short) is not just another
operating system that happens to be written in Lisp (although that
would be a good thing in itself). A LispOS is also an operating
system that uses the Lisp interactive environment as an inspiration
for the interface between the user and the system, and between
applications and the system.
In this document, we give some ideas on what a LispOS might contain,
how it would be different from existing operating systems, and how
such a system might be created.
\section{Problems with existing systems}
\subsection{The concept of a \emph{process}}
Most popular existing operating systems are derived from Unix which
was written in the 1970s. The computers for which Unix was intended
has a very small address space; too small for most usable end-user
applications. To solve this problem, the creators of Unix used the
concept of a \emph{process}. A large application was written so
that it consisted of several smaller programs, each of which ran in
its own address space. These smaller programs would communicate by
having one application write text to its output stream for another
application to read. This method of communication was called
a \emph{pipe} and a sequence of small applications was called
a \emph{pipeline}. As a typical example of a chain of applications,
consider the pipeline for producing a typeset document (one of the
main applications for which Unix was designed). This chain had a
program for creating tables (called \texttt{tbl}), a program for
generating pictures (called \texttt{pic}), a program for generating
equations (called \texttt{eqn}), and of course the typesetting program
itself (called \texttt{troff}).
Using pipes to communicate between different components of an
application has several disadvantages:
\begin{itemize}
\item To communicate complex data structures (such as trees or
graphs), they must be converted to a stream of bytes by the
creating component, and it must be analyzed and parsed into an
equivalent data structure by the using component. Not only is
this unparsing/parsing inefficient in terms of computing
resources, but it is also problematic from a
software-engineering point of view, because the external format
must be specified and maintained as a separate aspect of each
component.
\item An artificial \emph{order} between the different components is
imposed, so that components can not work as libraries that other
components can use in any order. Sometimes (as in the example
of the \texttt{troff} chain) the end result of a computation
depends in subtle ways on the order between the components of
the chain. Introducing a new component may require other
components to be modified.
\end{itemize}
It is an interesting observation that in most text books on
operating systems, the concept of a process is presented as playing
a central role in operating-system design, whereas it ought to be
presented as an unfortunate necessity due to the limited address
space of existing minicomputers in the 1970s. It is also presented
as \emph{the} method for obtaining some kind of \emph{security},
preventing one application from intentionally or accidentally
modifying the data of some other application. In reality, there are
several ways of obtaining such security, and separate address spaces
should be considered to be a method with too many disadvantages.
Nowadays, computers have addresses that are 64 bit wide, making it
possible to address almost 20 exabytes of data. To get an idea of
the order of magnitude of such a number, consider a fairly large
disc that can hold a terabyte of data. Then 20 million such discs
can be directly addressed by the processor. We can thus consider
the problem of too small an address space to be solved.
\subsection{Hierarchical file systems}
Existing operating system come with a \emph{hierarchical file
system}. There are two significant problems,
namely \emph{hierarchical} and \emph{file}.
The \emph{ hierarchy} is also a concept that dates back to the
1970s, and it was considered a vast improvement on flat file
systems. However, as some authors%
\footnote{See
\texttt{http://www.shirky.com/writings/ontology\_overrated.html}}
explain, most things are not naturally hierarchical. A hierarchical
organization imposes an artificial order between names. Whether a
document is called \texttt{Lisp/Programs/2013/stuff},
\texttt{Programs/Lisp/2013/stuff}, or something else like
\texttt{2013/Programs/Lisp/stuff}, is usually not important.
The problem with a \emph{file} is that it is only a sequence of
bytes with no structure. This lack of structure fits the Unix pipe
model very well, because intermediate steps between individual
software components can be saved to a file without changing the
result. But it also means that in order for complex data structures
to be stored in the file system, they have to be transformed into a
sequence of bytes. And whenever such a structure needs to be
modified by some application, it must again be parsed and
transformed into an in-memory structure.
\subsection{Distinction between primary and secondary memory}
Current system (at least for desktop computers) make a very clear
distinction between primary and secondary memory. Not only are the
two not the same, but they also have totally different semantics:
\begin{itemize}
\item Primary memory is \emph{volatile}. When power is turned off,
whatever was in primary memory is lost.
\item Secondary memory is \emph{permanent}. Stored data will not
disappear when power is turned off.
\end{itemize}
This distinction coupled with the semantics of the two memories
creates a permanent conundrum for the user of most applications, in
that if current application data is \emph{not} saved, then it will
be lost in case of power loss, and if it \emph{is} saved, then
previously saved data is forever lost.
Techniques were developed as early in the 1960s for presenting
primary and secondary memory as a single abstraction to the user.
For example, the Multics system had a single hierarchy of fixed-size
byte arrays (called segments) that served as permanent storage, but
that could also be treated as any in-memory array by applications.
As operating systems derived from Unix became widespread, these
techniques were largely forgotten.
\section{Objectives for a Lisp operating system}
The three main objectives of a Lisp operating system correspond to
solutions to the two main problems with exiting systems as indicated
in the previous section.
\subsection{Single address space}
Instead of each application having its own address space, we propose
that all applications share a single large address space. This way,
applications can share data simply by passing pointers around,
because a pointer is globally valid, unlike pointers in current
operating systems.
Clearly, if there is a single address space shared by all
applications, there needs to be a different mechanism to
ensure \emph{protection} between them so that one application can
not intentionally or accidentally destroy the data of another
application. Most high-level programming languages (in particular
Lisp, but also Java, and many more) propose a solution to this
problem by simply not allowing users to execute arbitrary machine
code. Instead, they allow only code that has been produced from the
high-level notation of the language and which excludes arbitrary
pointer arithmetic so that the application can only address its own
data. This technique is sometimes called "trusted compiler".
It might sometimes be desirable to write an application in a
low-level language like C or even assembler, or it might be
necessary to run applications that have been written for other
systems. Such applications could co-exist with the normal ones, but
they would have to work in their own address space as with current
operating systems, and with the same difficulties of communicating
with other applications.
\subsection{Object store based on tags}
Instead of a hierarchical file system, we propose an \emph{object
store} which can contain any objects. If a file (i.e. a
sequence of bytes) is desired, it would be stored as an array of
bytes.
Instead of organizing the objects into a hierarchy, objects in the
store can optionally be associated with an arbitrary number
of \emph{tags}. These tags are \emph{key/value} pairs, such as for
example the date of creation of the archive entry, the creator (a
user) of the archive entry, and the \emph{access permissions} for
the entry. Notice that tags are not properties of the objects
themselves, but only of the archive entry that allows an object to
be accessed. Some tags might be derived from the contents of the
object being stored such as the \emph{sender} or the \emph{date} of
an email message. It should be possible to accomplish most searches
of the store without accessing the objects themselves, but only the
tags. Occasionally, contents must be accessed such as when a raw
search of the contents of a text is wanted.
For a more detailed description of the object store, see
\refChap{chap-object-store}.
It is sometimes desirable to group related objects together as
with \emph{directories} of current operating systems. Should a user
want such a group, it would simply be another object (say instances
of the class \texttt{directory}) in the store. Users who can not
adapt to a non-hierarchical organization can even store such
directories as one of the objects inside another directory.
Here are some examples of possible keyword/value pairs, how they
might be used, and what kinds of values are permitted:
\newcolumntype{Y}{>{\raggedright\arraybackslash}X}
When (a pointer to) an object is returned to a user as a result of a
search of the object store, it is actually similar to what is called
a "capability" in the operating-system literature. Such a
capability is essentially only a pointer with a few bits indicating
what \emph{access rights} the user has to the objects. Each creator
may interpret the contents of those bits as he or she likes, but
typically they would be used to restrict access, so that for
instance executing a \emph{reader} method is allowed, but executing
a \emph{writer} method is not.
\subsection{Single memory abstraction}
Instead of two different memory abstractions (primary and
secondary), the Lisp operating system would contain a single
abstraction which looks like any interactive Lisp system, except
that data is permanent.
Since data is permanent, application writers are encouraged to
provide a sophisticated \emph{undo} facility.
The physical main (semiconductor) memory of the computer simply acts
as a \emph{cache} for the disk(s), so that the address of an object
uniquely determines where on the disk it is stored. The cache is
managed as an ordinary \emph{virtual memory} with existing
algorithms.
\subsection{Other features}
\subsubsection{Crash proof (maybe)}
There is extensive work on crash-proof systems, be it operating
systems or data base systems. In our opinion, this work is
confusing in that the objective is not clearly stated.
Sometimes the objective is stated as the desire that no data be lost
when power is lost. But the solution to that problem already exists
in every laptop computer; it simply provides a \emph{battery} that
allow the system to continue to work, or to be \emph{shut down} in a
controlled way.
Other times, the objective is stated as a protection against
defective software, so that data is stored at regular intervals
(checkpointing) perhaps combined with a \emph{transaction log} so
that the state of the system immediately before a crash can always
be recovered. But it is very hard to protect oneself against
defective software. There can be defects in the checkpointing code
or in the code for logging transactions, and there can be defects in
the underlying file system. We believe that it is a better use of
developer time to find and eliminate defects than to aim for a
recovery as a result of existing defects.
\subsubsection{Multiple simultaneous environments}
To allow for a user to add methods to standard generic functions
(such as \texttt{print-object}) without interfering with other
users, we suggest that each user gets a different \emph{global
environment}. The environment maps \emph{names}
to \emph{objects} such as functions, classes, types, packages, and
more. Immutable objects (such as the \texttt{common-lisp} package)
can exist in several different environments simultaneously, but
objects (such as the generic function \texttt{print-object} would be
different in different environments.
Multiple environments would also provide more safety for users in
that if a user inadvertently removes some system feature, then it
can be recovered from a default environment, and in the worst case a
fresh default environment could be installed for a user who
inadvertently destroyed large parts of his or her environment.
Finally, multiple environments would simplify experimentation with
new features without running the risk of destroying the entire
system. Different versions of a single package could exist in
different environments.
\section{How to accomplish it}
The most important aspect of a Lisp operating system is not that all
the code be written in Lisp, but rather to present a Lisp-like
interface between users and the system and between applications and
the system. It is therefore legitimate to take advantage of some
existing system (probably Linux or some BSD version) in order to
provide services such as device drivers, network communication,
thread scheduling, etc.
\subsection{Create a Lisp system to be used as basis}
The first step is to create a Common Lisp system that can be used as
a basis for the Lisp operating system. It should already allow for
multiple environments, and it should be available on 64-bit
platforms. Preferably, this system should use as little C code as
possible and interact directly with the system calls of the
underlying kernel.
\subsection{Create a single-user system as a Unix process}
The next step is to transform the Common Lisp system into an
operating system in the sense of the API for users and
applications. This system would contain the object store, but
perhaps not access control functionality.
When this step is accomplished, it is possible to write or adapt
applications such as text editors, inspectors, debuggers, GUI
interface libraries, etc. for the system.
\subsection{Create device drivers}
The final step is to replace the temporary Unix kernel with native
device drivers for the new system and to turn the system into a full
multi-user operating system.

@ -0,0 +1,110 @@
\chapter{Object store}
\label{chap-object-store}
The \emph{object store} is a system-wide database containing
any kind of objects. Each object is a \emph{capability}.
An object in the store can optionally be associated with a certain
number of \emph{attributes}. An attribute is a \emph{pair} consisting
of the \emph{attribute name} and the \emph{attribute value}. The
attribute name is a symbol in the \texttt{keyword} package. The
attribute value can be any object.
\begin{tabularx}{\linewidth}%
{|>{\setlength\hsize{.2\hsize}}X|%
>{\setlength\hsize{.8\hsize}}X|}
\hline
Keyword & Possible-values\\
\hline\hline
\textbf{category} &
The nature of the object such
as \textbf{movie}, \textbf{music}, \textbf{article}, \textbf{book}, \textbf{user
manual}, \textbf{dictionary}, \textbf{course}, \textbf{lecture},
\textbf{recipe}, \textbf{program}, \textbf{bank statement},
\textbf{email}. These would be chosen from an
editable set that is defined per user.\\
\hline
\textbf{name} &
A string that is displayed with the object, such as "A Dramatic
Turn of Events", "Three seasons", "Alternative energy".\\
\hline
\textbf{author} &
An object identifying a person, an organization, a company,
etc. \\
\hline
\textbf{genre} &
\textbf{progressive
metal}, \textbf{science}, \textbf{algorithms}, \textbf{garbage
collection}, \textbf{game}, \textbf{programming language
implementation}, \textbf{operating system}. These would be
chosen from an editable set that is defined per user.\\
\hline
\textbf{format} &
This attribute can be used to identify the file type of documents such
as \textbf{PDF}, \textbf{ogg/vorbis}, \textbf{MPEG4} \textbf{PNG}, in
which case the attribute can be assigned automatically, but also to
identify the source format of files in a directory containing
things like articles or user manuals, for
example \textbf{LaTeX}, \textbf{Texinfo}, \textbf{HTML}. These would
be chosen from an editable set that is defined per user. \\
\hline
\end{tabularx}
\begin{tabularx}{\linewidth}%
{|>{\setlength\hsize{.2\hsize}}X|%
>{\setlength\hsize{.8\hsize}}X|}
\hline
Keyword & Possible-values\\
\hline\hline
\textbf{date of creation} &
A date interval.\\
\hline
\textbf{composer} &
An object representing a person. On a compilation album there
can be more than one attribute of this kind. \\
\hline
\textbf{language} &
An object representing a natural language such
as \textbf{English}, \textbf{Vietnamese}, or a programming languages
such as \textbf{Lisp}, \textbf{Python}. These would
be chosen from an editable set that is defined per user. If
appropriate, a document can have several of these attributes, for
instance if some program uses multiple programming languages, or
if a document is written using several languages, such as a
dictionary. \\
\hline
\textbf{duration} &
An object representing a duration. \\
\hline
\textbf{source control} &
\textbf{GIT}, \textbf{SVN}, \textbf{CVS}, \textbf{darks}, etc. These
would be chosen from an editable set that is defined per user.\\
\hline
\end{tabularx}
In a typical operating system installation, there are many fairly
large objects such as movies, music files, pictures, etc. The amount
data associated with such an object that would be stored in the object
store is typically very small compared to the object itself. Even a
fairly modest text file probably has $10^4 -- 10^5$ characters in it,
whereas the meta-data probably takes up no more than $10^2 -- 10^3$
bytes. It is therefore likely that the entire object store will fit
in main memory. Scanning the entire object store would then take at
most a few second of CPU time. For better performance, one or more
\emph{indexes} could be created. The objects could for instance be
divided by \emph{category}.
Searching the object store amounts to defining a \emph{filter},
i.e. a function that, given a set of keyword/value pairs returns
\emph{true} if and only if the corresponding object should be included
in the search result.

@ -0,0 +1,78 @@
\chapter{Protection}
\label{chap-protection}
There are two kinds of protection that are important in an operating
system:
\begin{itemize}
\item \emph{protecting different users from each other}. A user A
should not be able to access or destroy the data of some other user
B, other than if B explicitly permits it, and then only in ways that
are acceptable to B.
\item \emph{protecting the system from the users}. Users should be
able to access system resources such as memory and peripherals only
in controlled ways, so as to guarantee the integrity of the system.
\end{itemize}
\section{Protecting users from each other}
We use a combination of \emph{access control lists} and
\emph{capabilities}. All heap-allocated objects except \texttt{cons}
cells and (heap-allocated) numbers are manipulated through a
\emph{tagged pointer}. In addition to containing a type tag, the
pointer also contains an \emph{access tag}. The access tag consists
of the 4 most-significant bits of a 64-bit pointer. Before a pointer
is used to fetch an object from memory, the access bits are cleared.
A primitive operation to fetch the access tag of a pointer is
available to any user code. Each of the 4 bits represents a potential
\emph{access restriction}, the significance of which is up to the
programmer. A function that wishes to restrict permission to some
object can test the corresponding access bit and signal an error if
that bit is set.
The author of some complex data structure may for instance grant
access to it only to certain other users. This would be done by
interpreting one of the access bits as \emph{read permission}, and by
having generic functions that access the data structures check that
this bit has the desired value (for instance in a \texttt{:before}
method).
The access bits of a capability are determined when the object is
accessed through the object store. \seechap{chap-object-store} One of
the possible key/value pairs associated with the object in the object
store corresponds to the access permissions in the form of an
\emph{access control list}. A user who accesses the object from the
object store will be checked against the access control list and
appropriate access bits will be added to the object before it is given
to the user.
\section{Protecting system from the users}
In a typical modern operating system, the system is protected from the
users through the use of a \emph{mode} of execution of the processor,
which can be either \emph{user mode} or \emph{supervisor mode}.
Certain instructions are restricted to supervisor mode, such as
instructions for input/output or for remapping the address space.
In \sysname{}, the normal mode of execution is \emph{supervisor mode}.
The code executed by the user is translated to machine code by a
\emph{trusted compiler} which is known not to generate code that, if
executed, might represent a risk to the integrity of the system.
Since no remapping of the address space is required as a result of an
\emph{interrupt} or a \emph{trap}, such events can be handled very
quickly.
Occasionally, it might be useful to write or install some software
that is compiled to machine code by some compiler that can not be
trusted. The result of such a compilation or installation is a single
(possibly large) Lisp function. When this function is executed, the
mode of execution is switched to \emph{user mode}. As with
traditional modern operating systems, the code of such software has
its own \emph{address space}, which means that it can not directly
manipulate \sysname{} capabilities. Instead, it has to communicate
with the system through the user of \emph{system calls}. A
system-wide object is referred to by such code through an interposing
\emph{object descriptor}, much like a file descriptor in Unix. The
details of this mechanism have not yet been fully determined.

@ -0,0 +1,5 @@
OUTFILE=$(echo $1 | sed -e 's/lisp/code/')
echo -n "\\" >$OUTFILE
echo "begin{Verbatim}[frame=single]" >>$OUTFILE
expand $1 >>$OUTFILE
echo "\\end{Verbatim}" >>$OUTFILE

@ -0,0 +1,291 @@
@book{Sedgewick:1996:IAA:227351,
author = {Sedgewick, Robert and Flajolet, Philippe},
title = {An introduction to the analysis of algorithms},
year = {1996},
isbn = {0-201-40009-X},
publisher = {Addison-Wesley Longman Publishing Co., Inc.},
address = {Boston, MA, USA},
}
@book{McConnell:2007:AA:1374801,
author = {McConnell, Jeffrey J.},
title = {Analysis of Algorithms},
year = {2007},
isbn = {9780763707828},
edition = {2},
publisher = {Jones and Bartlett Publishers, Inc.},
address = {USA},
}
@article{Sleator:1985:SBS:3828.3835,
author = {Sleator, Daniel Dominic and Tarjan, Robert Endre},
title = {Self-adjusting binary search trees},
journal = {J. ACM},
issue_date = {July 1985},
volume = {32},
number = {3},
month = jul,
year = {1985},
issn = {0004-5411},
pages = {652--686},
numpages = {35},
url = {http://doi.acm.org/10.1145/3828.3835},
doi = {10.1145/3828.3835},
acmid = {3835},
publisher = {ACM},
address = {New York, NY, USA},
}
@incollection{Bayer:2002:BDP:944331.944346,
author = {Bayer, Rudolf},
chapter = {B-trees and databases, past and future},
title = {Software pioneers},
editor = {Broy, Manfred and Denert, Ernst},
year = {2002},
isbn = {3-540-43081-4},
pages = {232--244},
numpages = {13},
url = {http://dl.acm.org/citation.cfm?id=944331.944346},
acmid = {944346},
publisher = {Springer-Verlag New York, Inc.},
address = {New York, NY, USA},
}
@article{Adelson-Velskii_Landis_1962,
title = {An algorithm for the organization of information},
volume = {3},
url = {http://en.scientificcommons.org/19884302},
number = {2},
journal = {Soviet Mathematics Doklady},
publisher = {JOINT PUBLICATIONS RESEARCH SERVICE WASHINGTON DC},
author = {Adelson-Velskii, G M and Landis, E M},
year={1962},
pages={263--266}
}
@article{Tan:1972:FIS:361573.361588,
author = {Tan, K. C.},
title = {On Foster's information storage and retrieval using AVL trees},
journal = {Commun. ACM},
issue_date = {Sept. 1972},
volume = {15},
number = {9},
month = sep,
year = {1972},
issn = {0001-0782},
pages = {843--},
url = {http://doi.acm.org/10.1145/361573.361588},
doi = {10.1145/361573.361588},
acmid = {361588},
publisher = {ACM},
address = {New York, NY, USA},
keywords = {binary trees, information retrieval, information storage, search trees},
}
@inproceedings{Wilson:1992:UGC:645648.664824,
author = {Wilson, Paul R.},
title = {Uniprocessor Garbage Collection Techniques},
booktitle = {Proceedings of the International Workshop on Memory Management},
series = {IWMM '92},
year = {1992},
isbn = {3-540-55940-X},
pages = {1--42},
numpages = {42},
url = {http://dl.acm.org/citation.cfm?id=645648.664824},
acmid = {664824},
publisher = {Springer-Verlag},
address = {London, UK, UK},
}
@book{Jones:2011:GCH:2025255,
author = {Jones, Richard and Hosking, Antony and Moss, Eliot},
title = {The Garbage Collection Handbook: The Art of Automatic Memory Management},
year = {2011},
isbn = {1420082795, 9781420082791},
edition = {1st},
publisher = {Chapman \& Hall/CRC},
}
@article{Andersson:1999:GBT:308088.308094,
author = {Andersson, Arne},
title = {General balanced trees},
journal = {J. Algorithms},
issue_date = {Jan. 1999},
volume = {30},
number = {1},
month = jan,
year = {1999},
issn = {0196-6774},
pages = {1--18},
numpages = {18},
url = {http://dx.doi.org/10.1006/jagm.1998.0967},
doi = {10.1006/jagm.1998.0967},
acmid = {308094},
publisher = {Academic Press, Inc.},
address = {Duluth, MN, USA},
}
@article{Stout:1986:TRO:6592.6599,
author = {Stout, Q. F and Warren, B. L},
title = {Tree rebalancing in optimal time and space},
journal = {Commun. ACM},
issue_date = {Sept. 1986},
volume = {29},
number = {9},
month = sep,
year = {1986},
issn = {0001-0782},
pages = {902--908},
numpages = {7},
url = {http://doi.acm.org/10.1145/6592.6599},
doi = {10.1145/6592.6599},
acmid = {6599},
publisher = {ACM},
address = {New York, NY, USA},
}
@article{Waters:1992:UNC:1039991.1039996,
author = {Waters, Richard C.},
title = {Using the new common Lisp pretty printer},
journal = {SIGPLAN Lisp Pointers},
issue_date = {April-June 1992},
volume = {V},
number = {2},
month = apr,
year = {1992},
issn = {1045-3563},
pages = {27--34},
numpages = {8},
url = {http://doi.acm.org/10.1145/1039991.1039996},
doi = {10.1145/1039991.1039996},
acmid = {1039996},
publisher = {ACM},
address = {New York, NY, USA},
}
@INPROCEEDINGS{Waters89xp:a,
author = {Richard C. Waters},
title = {XP: A Common Lisp Pretty Printing System},
booktitle = {A.I. Memo 1102a, MIT Artificial Intelligence Laboratory},
year = {1989}
}
BibTeX | BibTeX (beta) | EndNote | ACM Ref
@techreport{Huang:1990:FSM:898863,
author = {Huang, Bing and Langston, Michael A.},
title = {Fast Stable Merging and Sorting in Constant Extra Space},
year = {1990},
source = {http://www.ncstrl.org:8900/ncstrl/servlet/search?formname=detail\&id=oai%3Ancstrlh%3Autk_cs%3Ancstrl.utk_cs%2F%2FUT-CS-90-106},
publisher = {University of Tennessee},
address = {Knoxville, TN, USA},
}
@article{Huang:1988:PIM:42392.42403,
author = {Huang, Bing-Chao and Langston, Michael A.},
title = {Practical in-place merging},
journal = {Commun. ACM},
issue_date = {March 1988},
volume = {31},
number = {3},
month = mar,
year = {1988},
issn = {0001-0782},
pages = {348--352},
numpages = {5},
url = {http://doi.acm.org/10.1145/42392.42403},
doi = {10.1145/42392.42403},
acmid = {42403},
publisher = {ACM},
address = {New York, NY, USA},
}
@article{Katajainen:1996:PIM:642136.642138,
author = {Katajainen, Jyrki and Pasanen, Tomi and Teuhola, Jukka},
title = {Practical in-place mergesort},
journal = {Nordic J. of Computing},
issue_date = {Spring 1996},
volume = {3},
number = {1},
month = mar,
year = {1996},
issn = {1236-6064},
pages = {27--40},
numpages = {14},
url = {http://dl.acm.org/citation.cfm?id=642136.642138},
acmid = {642138},
publisher = {Publishing Association Nordic Journal of Computing},
address = {Finland},
keywords = {in-place algorithms, mergesort, sorting},
}
@inproceedings{Clinger:1990:RFP:93542.93557,
author = {Clinger, William D.},
title = {How to read floating point numbers accurately},
booktitle = {Proceedings of the ACM SIGPLAN 1990 conference on Programming language design and implementation},
series = {PLDI '90},
year = {1990},
isbn = {0-89791-364-7},
location = {White Plains, New York, USA},
pages = {92--101},
numpages = {10},
url = {http://doi.acm.org/10.1145/93542.93557},
doi = {10.1145/93542.93557},
acmid = {93557},
publisher = {ACM},
address = {New York, NY, USA},
}
@inproceedings{Burger:1996:PFN:231379.231397,
author = {Burger, Robert G. and Dybvig, R. Kent},
title = {Printing floating-point numbers quickly and accurately},
booktitle = {Proceedings of the ACM SIGPLAN 1996 conference on Programming language design and implementation},
series = {PLDI '96},
year = {1996},
isbn = {0-89791-795-2},
location = {Philadelphia, Pennsylvania, USA},
pages = {108--116},
numpages = {9},
url = {http://doi.acm.org/10.1145/231379.231397},
doi = {10.1145/231379.231397},
acmid = {231397},
publisher = {ACM},
address = {New York, NY, USA},
keywords = {floating-point printing, run-time systems},
}
@TECHREPORT{Gay90correctlyrounded,
author = {David M. Gay},
title = {Correctly Rounded Binary-Decimal and Decimal-Binary Conversions},
institution = {Numerical Analysis Manuscript 90-10, AT\&T Bell Laboratories},
year = {1990}
}
@inproceedings{Doligez:1993:CGG:158511.158611,
author = {Doligez, Damien and Leroy, Xavier},
title = {A concurrent, generational garbage collector for a multithreaded implementation of ML},
booktitle = {Proceedings of the 20th ACM SIGPLAN-SIGACT symposium on Principles of programming languages},
series = {POPL '93},
year = {1993},
isbn = {0-89791-560-7},
location = {Charleston, South Carolina, USA},
pages = {113--123},
numpages = {11},
url = {http://doi.acm.org/10.1145/158511.158611},
doi = {10.1145/158511.158611},
acmid = {158611},
publisher = {ACM},
address = {New York, NY, USA},
}
@book{Kiczales:1991:AMP:574212,
author = {Kiczales, Gregor and Rivieres, Jim Des},
title = {The Art of the Metaobject Protocol},
year = {1991},
isbn = {0262111586},
publisher = {MIT Press},
address = {Cambridge, MA, USA},
}

@ -0,0 +1,109 @@
\documentclass[11pt]{book}
\newcommand{\Comment}[1]{\begin{center}\tt #1 \end{center}}
% \usepackage{doublespace}
\usepackage[paperwidth=7.5in, paperheight=9.25in,
inner=35mm, outer=25mm,
tmargin=25mm, bmargin=30mm]{geometry}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{alltt}
\usepackage{moreverb}
\usepackage{fancyvrb}
\usepackage{epsfig}
\usepackage{makeidx}
\usepackage{float}
\usepackage{color}
\usepackage{amsthm}
\usepackage{changebar}
\usepackage{tabularx}
\usepackage[nottoc]{tocbibind}
\usepackage{shadow}
\setlength\sdim{2mm}
\floatplacement{figure}{!htbp}
\newfloat{codefragment}{!htbp}{cod}[chapter]
\floatname{codefragment}{Code fragment}
\newtheorem{theorem}{Theorem}[chapter]
\newtheorem{exercise}{Exercise}[chapter]
\newtheorem{definition}{Definition}[chapter]
\setlength{\parskip}{0.3cm}
\setlength{\parindent}{0cm}
\def\lispout#1{\underline{#1}}
\def\mop{MOP}
\def\bs{$\backslash$}
\def\lispobj#1{\textsl{#1}}
\def\lispobjindex#1{\lispobj{#1}\index{#1@\lispobj{#1}}}
\def\syntax#1{\texttt{#1}}
\def\metavar#1{\textit{#1}}
\def\keyword#1{\code{\textbf{#1}}}
\def\code#1{\textsf{#1}}
\def\fixme#1{\footnote{\color{red}FIXME: #1}}
\def\sysname{LispOS}
\def\inputfig#1{\input #1}
\def\inputtex#1{\input #1}
\def\inputal#1{\input #1}
\def\inputcode#1{\input #1}
\inputtex{logos.tex}
\inputtex{refmacros.tex}
\inputtex{other-macros.tex}
\newenvironment{itemize0}{
\begin{itemize}
\setlength{\parskip}{0cm}%
}
{\end{itemize}}
\newenvironment{enumerate0}{
\begin{enumerate}
\setlength{\parskip}{0cm}%
}
{\end{enumerate}}
\newenvironment{smalltt}{
\begin{alltt}
\small
}
{\end{alltt}}
%UPDATE version number when it changes.
\def\majorversion{0}
\def\minorversion{1}
\def\bookversion{\majorversion{}.\minorversion{}}
\title{{\Huge \sysname{}\\
Specification of a Lisp operating system.}}
\author{Robert Strandh}
\date{2013}
\makeindex
\begin{document}
\pagenumbering{roman}
\maketitle
\newpage
{\setlength{\parskip}{0cm}
\tableofcontents}
\inputtex{chap-intro.tex}
\inputtex{chap-object-store.tex}
\inputtex{chap-protection.tex}
\inputtex{chap-environments.tex}
\bibliography{lispos}{}
\bibliographystyle{alpha}
\printindex
\end{document}

@ -0,0 +1,46 @@
% Programming languages.
\def\cl{Common Lisp}
\def\clos{CLOS}
\def\closs{Common Lisp Object System}
\def\lisp{Lisp}
\def\hs{HyperSpec}
\def\bs{$\backslash$}
\def\lispobj#1{\textsl{#1}}
\def\emphindex#1{\emph{#1}\index{#1}}
\def\syntax#1{\texttt{#1}}
\def\metavar#1{\textit{#1}}
\def\code#1{\textsf{#1}}
\def\FIXME#1{\footnote{\color{red}FIXME: #1}}
\def\java{Java}
\def\csharp{C\#}
\def\javascript{JavaScript}
\def\php{PHP}
\def\self{Self}
\def\perl{Perl}
\def\python{Python}
\def\ruby{Ruby}
\def\smalltalk{Smalltalk}
\def\simula{Simula}
\def\clanguage{C}
\def\cplusplus{C++}
\def\fortran{Fortran}
\def\pascal{Pascal}
\def\algol{Algol}
\def\ml{ML}
\def\haskell{Haskell}
\def\miranda{Miranda}
\def\cobol{COBOL}
\def\plone{PL/I}
\def\emacs{Emacs}
% Operating systems and kernels.
\def\multics{Multics}
\def\unix{UNIX}% The Wikipedia article says this is the way it is written.
\def\gnulinux{GNU/Linux}
\def\linux{Linux}
\def\mach{Mach}
\def\atlas{Atlas}
\def\vms{VMS}
\def\ibmvmcms{VM/CMS}
\def\msdos{MS DOS}
\def\genera{Genera}

@ -0,0 +1,6 @@
\def\sll{simply linked list}
\def\Sll{Simply linked list}
\def\dll{doubly linked list}
\def\Dll{Doubly linked list}
\def\ttt{2-3 tree}

@ -0,0 +1,50 @@
\newcommand{\refalgo}[1]{algorithm~\ref{#1}}%
\newcommand{\refAlgo}[1]{Algorithm~\ref{#1}}%
\newcommand{\seealgo}[1]{(See \refAlgo{#1}.)}%
\newcommand{\seealgox}[2]{(See \refAlgo{#1} #2.)}%
\newcommand{\refpart}[1]{part~\ref{#1}}%
\newcommand{\refPart}[1]{Part~\ref{#1}}%
\newcommand{\seepart}[1]{(See \refPart{#1}.)}%
\newcommand{\seepartx}[2]{(See \refPart{#1} #2.)}%
\newcommand{\refchap}[1]{chapter~\ref{#1}}%
\newcommand{\refChap}[1]{Chapter~\ref{#1}}%
\newcommand{\seechap}[1]{(See \refChap{#1}.)}%
\newcommand{\seechapx}[2]{(See \refChap{#1} #2.)}%
\newcommand{\refapp}[1]{appendix~\ref{#1}}%
\newcommand{\refApp}[1]{Appendix~\ref{#1}}%
\newcommand{\seeapp}[1]{(See \refApp{#1}.)}%
\newcommand{\seeappx}[2]{(See \refApp{#1} #2.)}%
\newcommand{\refsec}[1]{section~\ref{#1}}%
\newcommand{\refSec}[1]{Section~\ref{#1}}%
\newcommand{\seesec}[1]{(See \refSec{#1}.)}%
\newcommand{\seesecx}[2]{(See \refSec{#1} #2.)}%
\newcommand{\reffig}[1]{figure~\ref{#1}}%
\newcommand{\refFig}[1]{Figure~\ref{#1}}%
\newcommand{\seefig}[1]{(See \refFig{#1}.)}%
\newcommand{\seefigx}[2]{(See \refFig{#1} #2.)}%
\newcommand{\refdef}[1]{definition~\ref{#1}}%
\newcommand{\refDef}[1]{Definition~\ref{#1}}%
\newcommand{\seedef}[1]{(See \refDef{#1}.)}%
\newcommand{\seedefx}[2]{(See \refDef{#1} #2.)}%
\newcommand{\reftheo}[1]{theorem~\ref{#1}}%
\newcommand{\refTheo}[1]{Theorem~\ref{#1}}%
\newcommand{\seetheo}[1]{(See \refTheo{#1}.)}%
\newcommand{\seetheox}[2]{(See \refTheo{#1} #2.)}%
\newcommand{\refexo}[1]{exercise~\ref{#1}}%
\newcommand{\refExo}[1]{Exercise~\ref{#1}}%
\newcommand{\seeexo}[1]{(See \refExo{#1}.)}%
\newcommand{\seeexox}[2]{(See \refExo{#1} #2.)}%
\newcommand{\refcode}[1]{code fragment~\ref{#1}}%
\newcommand{\refCode}[1]{Code fragment~\ref{#1}}%
\newcommand{\seecode}[1]{(See \refCode{#1}.)}%
\newcommand{\seecodex}[2]{(See \refCode{#1} #2.)}%

@ -0,0 +1,12 @@
#!/bin/sh
CHAINE=$1
MOTIF="^\\\\$CHAINE\{.*\}"
shift
for i in $*
do
egrep $MOTIF $i \
| sed "s/^\\\\$CHAINE{\(.*\)}/\1/" \
| tr ['\n'] [' ']
done

@ -0,0 +1,10 @@
#!/bin/sh
#set -x
TEXFILES=$(./strip-dependence inputtex $1)
echo -n $TEXFILES
for i in $TEXFILES
do
echo -n " " $(./tex-dependencies $i)
done
echo
Loading…
Cancel
Save