Browse Source

Interruption via interception, last example.

master
Daniel Hillerström 5 years ago
parent
commit
95244693f4
  1. 1
      macros.tex
  2. 134
      thesis.tex

1
macros.tex

@ -383,3 +383,4 @@
\newcommand{\quoteRitchie}{\dec{ritchie}}
\newcommand{\quoteHamlet}{\dec{hamlet}}
\newcommand{\Proc}{\dec{Proc}}
\newcommand{\schedule}{\dec{schedule}}

134
thesis.tex

@ -2691,39 +2691,44 @@ handler. In this particular instance, it means that the $\nondet$
handler is part of the extent.
%
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
function which accepts as list of process states as input and
recursively runs any suspended computations under the $\nondet$
handler.
process has run to completion. To achieve this, we need a function
that keeps track of the state of every process, and in particular it
must run each $\Suspended$-tagged computation under the $\nondet$
handler to produce another list of process state, which must be
handled recursively.
%
\[
\bl
\runNext : \List~(\Pstate~\alpha~\{\Fork:\Bool;\varepsilon\}) \to \List~\alpha \eff \varepsilon\\
\runNext~ps \defas
\concatMap\,(\lambda p.
\schedule : \List~(\Pstate~\alpha~\{\Fork:\Bool;\varepsilon\}) \to \List~\alpha \eff \varepsilon\\
\schedule~ps \defas
\ba[t]{@{}l}
\Case\;p\;\{
\ba[t]{@{}l@{~}c@{~}l}
\Done~res &\mapsto& [res]\\
\Suspended~m &\mapsto& \runNext\,(\nondet~m) \})\,ps
\ea
\Let\;run \revto
\Rec\;sched\,\Record{ps;done}.\\
\qquad\Case\;ps\;\{
\ba[t]{@{}r@{~}c@{~}l}
\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
\el
\]
%
The function $\runNext$ inspects each process in the input list $ps$
to see whether it done or paused. It translates a $\Done$-tagged value
into a singleton list, whereas if it is a $\Suspended$-tagged
computation, then the computation is run under the $\nondet$ handler
to in order to handle invocations of $\Fork$, and $\runNext$ is
recursively applied to the result.
%
The function
$\concatMap : (\alpha \to \List~\beta) \to \List~\alpha \to
\List~\beta$ maps a function that produces a list of $\beta$s from an
$\alpha$ over a list of $\alpha$s, thus producing a list of list of
$\beta$s. The resulting list is flatten by using list concatenation to
combine the list members.
The function $\schedule$ implements a process scheduler. It takes as
input a list of process states, where $\Suspended$-tagged computations
may perform the $\Fork$ operation. Locally it defines a recursive
function $sched$ which carries a list of active processes $ps$ and the
results of completed processes $done$. The function inspects the
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
$\Done$-tagged value, then the function is recursively invoked with
tail of processes $ps'$ and the list $done$ augmented with the value
$res$. If the head is a $\Suspended$-tagged computation $m$, then
$sched$ is recursively invoked with the process list $ps'$
concatenated with the result of running $m$ under the $\nondet$
handler.
%
Using the above machinery, we can define a function which adds
time-sharing capabilities to the system.
@ -2731,13 +2736,13 @@ time-sharing capabilities to the system.
\[
\bl
\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
\]
%
The function $\timeshare$ handles the invocations of $\Fork$ and
$\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.
%
@ -2780,7 +2785,7 @@ invocation of $\Interrupt$ along side $\Write$.
\[
\bl
\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
\]
%
@ -2790,6 +2795,79 @@ backwards compatible, since the original definition of $\echo$ can be
used in a context that prohibits occurrences of $\Interrupt$. Clearly,
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}
\label{sec:tiny-unix-io}

Loading…
Cancel
Save