mirror of
https://github.com/dhil/phd-dissertation
synced 2026-03-13 11:08:25 +00:00
Compare commits
2 Commits
003c8e4d6c
...
53c76a0934
| Author | SHA1 | Date | |
|---|---|---|---|
| 53c76a0934 | |||
| 95244693f4 |
@@ -383,3 +383,4 @@
|
|||||||
\newcommand{\quoteRitchie}{\dec{ritchie}}
|
\newcommand{\quoteRitchie}{\dec{ritchie}}
|
||||||
\newcommand{\quoteHamlet}{\dec{hamlet}}
|
\newcommand{\quoteHamlet}{\dec{hamlet}}
|
||||||
\newcommand{\Proc}{\dec{Proc}}
|
\newcommand{\Proc}{\dec{Proc}}
|
||||||
|
\newcommand{\schedule}{\dec{schedule}}
|
||||||
144
thesis.tex
144
thesis.tex
@@ -2391,11 +2391,11 @@ installs a new instance of $\environment$, which is the environment
|
|||||||
belonging to $user'$, and runs the resumption $resume$ under this
|
belonging to $user'$, and runs the resumption $resume$ under this
|
||||||
instance.
|
instance.
|
||||||
%
|
%
|
||||||
The new instance of $\env$ shadows the initial instance, and therefore
|
The new instance of $\environment$ shadows the initial instance, and
|
||||||
it will intercept and handle any subsequent invocations of $\Ask$
|
therefore it will intercept and handle any subsequent invocations of
|
||||||
arising from running the resumption. A subsequent invocation of $\Su$
|
$\Ask$ arising from running the resumption. A subsequent invocation of
|
||||||
will install another environment instance, which will shadow both the
|
$\Su$ will install another environment instance, which will shadow
|
||||||
previously installed instance and the initial instance.
|
both the previously installed instance and the initial instance.
|
||||||
%
|
%
|
||||||
|
|
||||||
To make this concrete, let us plug together the all components of our
|
To make this concrete, let us plug together the all components of our
|
||||||
@@ -2691,39 +2691,44 @@ handler. In this particular instance, it means that the $\nondet$
|
|||||||
handler is part of the extent.
|
handler is part of the extent.
|
||||||
%
|
%
|
||||||
We ultimately want to return just a list of $\alpha$s to ensure every
|
We ultimately want to return just a list of $\alpha$s to ensure every
|
||||||
process has run to completion. To achieve this, we define an auxiliary
|
process has run to completion. To achieve this, we need a function
|
||||||
function which accepts as list of process states as input and
|
that keeps track of the state of every process, and in particular it
|
||||||
recursively runs any suspended computations under the $\nondet$
|
must run each $\Suspended$-tagged computation under the $\nondet$
|
||||||
handler.
|
handler to produce another list of process state, which must be
|
||||||
|
handled recursively.
|
||||||
%
|
%
|
||||||
\[
|
\[
|
||||||
\bl
|
\bl
|
||||||
\runNext : \List~(\Pstate~\alpha~\{\Fork:\Bool;\varepsilon\}) \to \List~\alpha \eff \varepsilon\\
|
\schedule : \List~(\Pstate~\alpha~\{\Fork:\Bool;\varepsilon\}) \to \List~\alpha \eff \varepsilon\\
|
||||||
\runNext~ps \defas
|
\schedule~ps \defas
|
||||||
\concatMap\,(\lambda p.
|
|
||||||
\ba[t]{@{}l}
|
\ba[t]{@{}l}
|
||||||
\Case\;p\;\{
|
\Let\;run \revto
|
||||||
\ba[t]{@{}l@{~}c@{~}l}
|
\Rec\;sched\,\Record{ps;done}.\\
|
||||||
\Done~res &\mapsto& [res]\\
|
\qquad\Case\;ps\;\{
|
||||||
\Suspended~m &\mapsto& \runNext\,(\nondet~m) \})\,ps
|
\ba[t]{@{}r@{~}c@{~}l}
|
||||||
\ea
|
\nil &\mapsto& done\\
|
||||||
|
(\Done~res) \cons ps' &\mapsto& sched\,\Record{ps';res \cons done}\\
|
||||||
|
(\Suspended~m) \cons ps' &\mapsto& sched\,\Record{ps' \concat (\nondet~m);\, done} \}
|
||||||
|
\ea\\
|
||||||
|
\In\;run\,\Record{ps;\nil}
|
||||||
\ea
|
\ea
|
||||||
\el
|
\el
|
||||||
\]
|
\]
|
||||||
%
|
%
|
||||||
The function $\runNext$ inspects each process in the input list $ps$
|
The function $\schedule$ implements a process scheduler. It takes as
|
||||||
to see whether it done or paused. It translates a $\Done$-tagged value
|
input a list of process states, where $\Suspended$-tagged computations
|
||||||
into a singleton list, whereas if it is a $\Suspended$-tagged
|
may perform the $\Fork$ operation. Locally it defines a recursive
|
||||||
computation, then the computation is run under the $\nondet$ handler
|
function $sched$ which carries a list of active processes $ps$ and the
|
||||||
to in order to handle invocations of $\Fork$, and $\runNext$ is
|
results of completed processes $done$. The function inspects the
|
||||||
recursively applied to the result.
|
process list $ps$ to test whether it is empty or nonempty. If it is
|
||||||
%
|
empty it returns the list of results $done$. Otherwise, if the head is
|
||||||
The function
|
$\Done$-tagged value, then the function is recursively invoked with
|
||||||
$\concatMap : (\alpha \to \List~\beta) \to \List~\alpha \to
|
tail of processes $ps'$ and the list $done$ augmented with the value
|
||||||
\List~\beta$ maps a function that produces a list of $\beta$s from an
|
$res$. If the head is a $\Suspended$-tagged computation $m$, then
|
||||||
$\alpha$ over a list of $\alpha$s, thus producing a list of list of
|
$sched$ is recursively invoked with the process list $ps'$
|
||||||
$\beta$s. The resulting list is flatten by using list concatenation to
|
concatenated with the result of running $m$ under the $\nondet$
|
||||||
combine the list members.
|
handler.
|
||||||
|
|
||||||
%
|
%
|
||||||
Using the above machinery, we can define a function which adds
|
Using the above machinery, we can define a function which adds
|
||||||
time-sharing capabilities to the system.
|
time-sharing capabilities to the system.
|
||||||
@@ -2731,13 +2736,13 @@ time-sharing capabilities to the system.
|
|||||||
\[
|
\[
|
||||||
\bl
|
\bl
|
||||||
\timeshare : (\UnitType \to \alpha \eff \Proc) \to \List~\alpha\\
|
\timeshare : (\UnitType \to \alpha \eff \Proc) \to \List~\alpha\\
|
||||||
\timeshare~m \defas \runNext\,[\Suspended\,(\lambda\Unit.\reifyP~m)]
|
\timeshare~m \defas \schedule\,[\Suspended\,(\lambda\Unit.\reifyP~m)]
|
||||||
\el
|
\el
|
||||||
\]
|
\]
|
||||||
%
|
%
|
||||||
The function $\timeshare$ handles the invocations of $\Fork$ and
|
The function $\timeshare$ handles the invocations of $\Fork$ and
|
||||||
$\Interrupt$ in some computation $m$ by starting it in suspended state
|
$\Interrupt$ in some computation $m$ by starting it in suspended state
|
||||||
under the $\reifyP$ handler. The $\runNext$ actually starts the
|
under the $\reifyP$ handler. The $\schedule$ actually starts the
|
||||||
computation, when it runs the computation under the $\nondet$ handler.
|
computation, when it runs the computation under the $\nondet$ handler.
|
||||||
%
|
%
|
||||||
|
|
||||||
@@ -2780,7 +2785,7 @@ invocation of $\Interrupt$ along side $\Write$.
|
|||||||
\[
|
\[
|
||||||
\bl
|
\bl
|
||||||
\echo' : \String \to \UnitType \eff \{\Interrupt : \UnitType \opto \UnitType;\Write : \Record{\UFD;\String} \opto \UnitType\}\\
|
\echo' : \String \to \UnitType \eff \{\Interrupt : \UnitType \opto \UnitType;\Write : \Record{\UFD;\String} \opto \UnitType\}\\
|
||||||
\echo'~cs \defas \Do\;\Interrupt~\Unit;\,\Do\;\Write\,\Record{\stdout;cs}
|
\echo'~cs \defas \Do\;\Interrupt\,\Unit;\,\Do\;\Write\,\Record{\stdout;cs}
|
||||||
\el
|
\el
|
||||||
\]
|
\]
|
||||||
%
|
%
|
||||||
@@ -2790,6 +2795,79 @@ backwards compatible, since the original definition of $\echo$ can be
|
|||||||
used in a context that prohibits occurrences of $\Interrupt$. Clearly,
|
used in a context that prohibits occurrences of $\Interrupt$. Clearly,
|
||||||
this alternative definition cannot be applied in such a context.
|
this alternative definition cannot be applied in such a context.
|
||||||
|
|
||||||
|
There is backwards-compatible way to bundle the two operations
|
||||||
|
together. We can implement a handler that \emph{intercepts}
|
||||||
|
invocations of $\Write$ and handles them by performing an interrupt
|
||||||
|
and, crucially, reperforming the intercepted write operation.
|
||||||
|
%
|
||||||
|
\[
|
||||||
|
\bl
|
||||||
|
\dec{interruptWrite} :
|
||||||
|
\ba[t]{@{~}l@{~}l}
|
||||||
|
&(\UnitType \to \alpha \eff \{\Interrupt : \UnitType \opto \UnitType;\Write : \Record{\UFD;\String} \opto \UnitType\})\\
|
||||||
|
\to& \alpha \eff \{\Interrupt : \UnitType \opto \UnitType;\Write : \Record{\UFD;\String} \opto \UnitType\}
|
||||||
|
\ea\\
|
||||||
|
\dec{interruptWrite}~m \defas
|
||||||
|
\ba[t]{@{~}l}
|
||||||
|
\Handle\;m~\Unit\;\With\\
|
||||||
|
~\ba{@{~}l@{~}c@{~}l}
|
||||||
|
\Return\;res &\mapsto& res\\
|
||||||
|
\OpCase{\Write}{\Record{fd;cs}}{resume} &\mapsto&
|
||||||
|
\ba[t]{@{}l}
|
||||||
|
\interrupt\,\Unit;\\
|
||||||
|
resume\,(\Do\;\Write~\Record{fd;cs})
|
||||||
|
\ea
|
||||||
|
\ea
|
||||||
|
\ea
|
||||||
|
\el
|
||||||
|
\]
|
||||||
|
%
|
||||||
|
This handler is not `self-contained' as the other handlers we have
|
||||||
|
defined previously. It gives in some sense a `partial' interpretation
|
||||||
|
of $\Write$ as it leaves open the semantics of $\Interrupt$ and
|
||||||
|
$\Write$, i.e. this handler must be run in a suitable context of other
|
||||||
|
handlers.
|
||||||
|
|
||||||
|
Let us plug this handler into the previous example to see what
|
||||||
|
happens.
|
||||||
|
%
|
||||||
|
\[
|
||||||
|
\ba{@{~}l@{~}l}
|
||||||
|
&\bl
|
||||||
|
\basicIO\,(\lambda\Unit.\\
|
||||||
|
\qquad\timeshare\,(\lambda\Unit.\\
|
||||||
|
\qquad\qquad\dec{interruptWrite}\,(\lambda\Unit.\\
|
||||||
|
\qquad\qquad\qquad\sessionmgr\,\Record{\Root;\lambda\Unit.\\
|
||||||
|
\qquad\qquad\qquad\qquad\status\,(\lambda\Unit.
|
||||||
|
\ba[t]{@{}l}
|
||||||
|
\If\;\fork~\Unit\;\Then\;
|
||||||
|
\su~\Alice;\,
|
||||||
|
\quoteRitchie~\Unit\\
|
||||||
|
\Else\;
|
||||||
|
\su~\Bob;\,
|
||||||
|
\quoteHamlet~\Unit)})))
|
||||||
|
\ea
|
||||||
|
\el \smallskip\\
|
||||||
|
\reducesto^+&
|
||||||
|
\bl
|
||||||
|
\Record{
|
||||||
|
\ba[t]{@{}l}
|
||||||
|
[0, 0];
|
||||||
|
\texttt{"}\ba[t]{@{}l}
|
||||||
|
\texttt{UNIX is basically To be, or not to be,\nl{}}\\
|
||||||
|
\texttt{a simple operating system, that is the question:\nl{}}\\
|
||||||
|
\texttt{but Whether 'tis nobler in the mind to suffer\nl{}}\\
|
||||||
|
\texttt{you have to be a genius to understand the simplicity.\nl{}"}}
|
||||||
|
\ea
|
||||||
|
\ea\\
|
||||||
|
: \Record{\List~\Int; \UFile}
|
||||||
|
\el
|
||||||
|
\ea
|
||||||
|
\]
|
||||||
|
%
|
||||||
|
Evidently, each write operation has been interleaved, resulting in a
|
||||||
|
mishmash poetry of Shakespeare and \UNIX{}.
|
||||||
|
|
||||||
\subsection{State: file i/o}
|
\subsection{State: file i/o}
|
||||||
\label{sec:tiny-unix-io}
|
\label{sec:tiny-unix-io}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user