From: Mart Lubbers Date: Thu, 9 Feb 2023 10:02:18 +0000 (+0100) Subject: updates X-Git-Url: https://git.martlubbers.net/?a=commitdiff_plain;h=7af43f4cbbc7792ec22553a84468cde77f429a11;p=phd-thesis.git updates --- diff --git a/asbook.tex b/asbook.tex index 39b016a..834b3e8 100644 --- a/asbook.tex +++ b/asbook.tex @@ -4,7 +4,11 @@ \usepackage{pdfpages} \begin{document} -%\includepdf[landscape,booklet,pages={69-128}]{thesis.pdf}%chktex 29 chktex 8 -\includepdf[landscape,booklet,pages={1-12}]{top/finale.pdf}%chktex 29 chktex 8 +\includepdf[landscape,booklet,pages={1-22}]{thesis.pdf}%chktex 29 chktex 8 +%\includepdf[landscape,booklet,pages={69-142}]{thesis.pdf}%chktex 29 chktex 8 +%\includepdf[landscape,booklet,pages={143-184}]{thesis.pdf}%chktex 29 chktex 8 +%\includepdf[landscape,booklet,pages={185-}]{thesis.pdf}%chktex 29 chktex 8 + +%\includepdf[landscape,booklet,pages={1-12}]{top/finale.pdf}%chktex 29 chktex 8 %\includepdf[pages={211,212}]{thesis.pdf}%chktex 29 chktex 8 \end{document} diff --git a/back/acknowledgements.tex b/back/acknowledgements.tex index c159e0c..0fd46fe 100644 --- a/back/acknowledgements.tex +++ b/back/acknowledgements.tex @@ -14,61 +14,62 @@ First of all I would like to thank Rinus Plasmeijer, Pieter Koopman, and Jan Mar The BEST people, Adrian Ramsingh, Jeremy Singer, and Phil Trinder for the fruitful collaboration, and the memorable trip to Glasgow. The \glsxtrshort{CEFP}/SusTrainable group, for offering a platform for the various summer schools I had the opportunity to teach; and not to mention the countless meetings, dinners, and drinks we had. The Royal Dutch Navy, in particular Teun de Groot and Ton van Heusden, for trusting me by funding the project. -All the colleagues and others that I had the privilege of sharing an office with, meeting in conferences, interact with in the department, or work with in some other way: -Arjan Oortgiese, -Bas Lijnse, -Ellie Kimenai, -Fok Bolderheij, -Hans-Nikolai Vie\ss{}mann, -Ingrid Berenbroek, -John van Groningen, -Jurri\"en Stutterheim, -László Domoslai, -Marie-José van Diem, -Markus Klinik, -Peter Achten, -Ralf Hinze, -Simone Meeuwsen, -Sjaak Smetsers, -Steffen Michels, -Sven-Bodo Scholz, -Tim Steenvoorden. +\ldots +%All the colleagues and others that I had the privilege of sharing an office with, meeting in conferences, interact with in the department, or work with in some other way: +%Arjan Oortgiese, +%Bas Lijnse, +%Ellie Kimenai, +%Fok Bolderheij, +%Hans-Nikolai Vie\ss{}mann, +%Ingrid Berenbroek, +%John van Groningen, +%Jurri\"en Stutterheim, +%László Domoslai, +%Marie-José van Diem, +%Markus Klinik, +%Peter Achten, +%Ralf Hinze, +%Simone Meeuwsen, +%Sjaak Smetsers, +%Steffen Michels, +%Sven-Bodo Scholz, +%Tim Steenvoorden. +%% +%The many students that allowed me to (co) supervise them in their theses: +%Arjen Nederveen, +%Colin de Roos, +%Dave Artz, +%Elina Antonova +%Erin van der Veen, +%Gijs Alberts, +%Haye B\"ohm, +%Matheus Amazonas Cabral de Andrade, +%Michel de Boer, +%Sjoerd Crooijmans, +%Willem de Vos. % -The many students that allowed me to (co) supervise them in their theses: -Arjen Nederveen, -Colin de Roos, -Dave Artz, -Elina Antonova -Erin van der Veen, -Gijs Alberts, -Haye B\"ohm, -Matheus Amazonas Cabral de Andrade, -Michel de Boer, -Sjoerd Crooijmans, -Willem de Vos. - -I give special thanks to my mentors: -Jos Baack, Francisco Torreira, Franc Grootjen, Louis Vuurpijl, and Larry Caruthers. - -And of course my friends and acquaintances that supported me throughout the process. -Pieter Wolfert and Anouk Neerincx; -Chris Kamphuis and Maudy Bijen; -Koen Dercksen and Michelle Everard; -Jules Kruijswijk en Nadia Klijn; -George Gregoire; -\selectlanguage{russian}Александер Барков\selectlanguage{british}; -Tim Hirschler; -Emma Lindahl; -Truman Crandell; -Annerieke Wessels; -Camil Staps. - -\selectlanguage{dutch} -Als laatste wil ik diegene bedanken die het dichtst bij mij staan. -Elvira, Rosalie en Liselotte voor hun tomeloze geduld en ondersteuning wanneer dat nodig was. -Mijn ouders in het bijzonder voor hun liefde en vertrouwen. -Mijn oma, broers, schoonfamilie en alle andere familieleden die op wat voor manier dan ook bijgedragen hebben. -\selectlanguage{british} +%I give special thanks to my mentors: +%Jos Baack, Francisco Torreira, Franc Grootjen, Louis Vuurpijl, and Larry Caruthers. +% +%And of course my friends and acquaintances that supported me throughout the process. +%Pieter Wolfert and Anouk Neerincx; +%Chris Kamphuis and Maudy Bijen; +%Koen Dercksen and Michelle Everard; +%Jules Kruijswijk en Nadia Klijn; +%George Gregoire; +%\selectlanguage{russian}Александер Барков\selectlanguage{british}; +%Tim Hirschler; +%Emma Lindahl; +%Truman Crandell; +%Annerieke Wessels; +%Camil Staps. +% +%\selectlanguage{dutch} +%Als laatste wil ik diegene bedanken die het dichtst bij mij staan. +%Elvira, Rosalie en Liselotte voor hun tomeloze geduld en ondersteuning wanneer dat nodig was. +%Mijn ouders in het bijzonder voor hun liefde en vertrouwen. +%Mijn oma, broers, schoonfamilie en alle andere familieleden die op wat voor manier dan ook bijgedragen hebben. +%\selectlanguage{british} %\end{center} \input{subfilepostamble} diff --git a/intro/intro.tex b/intro/intro.tex index e35294f..6e21459 100644 --- a/intro/intro.tex +++ b/intro/intro.tex @@ -372,14 +372,14 @@ This paper-based episode contains the following papers: The paper also serves as a gentle introduction to, and contains a thorough literature study on \glsxtrlong{TH}. \end{enumerate} -\paragraph{Other publications on \texorpdfstring{\glspl{EDSL}}{eDSLs}:} -Furthermore, I co-authored a paper that is not part of the \gls{MTASK} system yet and hence not part of the dissertation. - -\begin{enumerate}[resume] - \item \emph{Strongly-Typed Multi-\kern-2.5ptView Stack-\kern-1.25ptBased Computations} \citep{koopman_strongly-typed_2022}\label{enum:stack-based} shows how to create type-safe \glspl{EDSL} representing stack-based computations. - Instead of encoding the arguments to a function as arguments in the host language, stack-based approaches use a run time stack that contains the arguments. - By encoding the required contents of the stack in the types, such systems can be made type safe. -\end{enumerate} +%\paragraph{Other publications on \texorpdfstring{\glspl{EDSL}}{eDSLs}:} +%Furthermore, I co-authored a paper that is not part of the \gls{MTASK} system yet and hence not part of the dissertation. +% +%\begin{enumerate}[resume] +% \item \emph{Strongly-Typed Multi-\kern-2.5ptView Stack-\kern-1.25ptBased Computations} \citep{koopman_strongly-typed_2022}\label{enum:stack-based} shows how to create type-safe \glspl{EDSL} representing stack-based computations. +% Instead of encoding the arguments to a function as arguments in the host language, stack-based approaches use a run time stack that contains the arguments. +% By encoding the required contents of the stack in the types, such systems can be made type safe. +%\end{enumerate} \paragraph{Contribution:} The papers of which I am first author are solely written by me, there were weekly meetings with co-authors in which we discussed and refined the ideas. diff --git a/other.bib b/other.bib index 594fc26..c04c692 100644 --- a/other.bib +++ b/other.bib @@ -2190,3 +2190,18 @@ Publisher: Association for Computing Machinery}, author = {{TOP Software}}, year = {2023}, } + +@article{hinze_derivable_2001, + title = {Derivable {Type} {Classes}}, + volume = {41}, + issn = {1571-0661}, + url = {https://www.sciencedirect.com/science/article/pii/S1571066105805420}, + doi = {https://doi.org/10.1016/S1571-0661(05)80542-0}, + abstract = {Generic programming allows you to write a function once, and use it many times at different types. A lot of good foundational work on generic programming has been done. The goal of this paper is to propose a practical way of supporting generic programming within the Haskell language, without radically changing the language or its type system. The key idea is to present generic programming as a richer language in which to write default method definitions in a class declaration. On the way, we came across a separate issue, concerning type-class overloading where higher kinds are involved. We propose a simple type-class system extension to allow the programmer to write richer contexts than is currently possible.}, + number = {1}, + journal = {Electronic Notes in Theoretical Computer Science}, + author = {Hinze, Ralf and Jones, Simon Peyton}, + year = {2001}, + pages = {5--35}, + file = {Hinze and Jones - 2001 - Derivable Type Classes.pdf:/home/mrl/.local/share/zotero/storage/33IF2HMZ/Hinze and Jones - 2001 - Derivable Type Classes.pdf:application/pdf}, +} diff --git a/preamble.tex b/preamble.tex index 78fe626..0301489 100644 --- a/preamble.tex +++ b/preamble.tex @@ -167,101 +167,13 @@ \usepackage{longtable} % Tables spanning pages \usepackage{threeparttable} % Tables with footnotes -% Code % Pseudocode \usepackage[algochapter,linesnumbered,lined,boxed]{algorithm2e} % Fix the algorithm font \renewcommand\AlCapFnt{\normalfont} -\usepackage{listings} -\newcounter{tmp} -% https://tex.stackexchange.com/questions/149056/how-can-i-define-additional-literate-replacements-without-deleting-existing-ones -\makeatletter -\def\addToLiterate#1{\edef\lst@literate{\unexpanded\expandafter{\lst@literate}\unexpanded{#1}}} -\lst@Key{moreliterate}{}{\addToLiterate{#1}} -\makeatother -% General listings settings -\lstset{% - basewidth=0.5em, - basicstyle=\tt\small, - breakatwhitespace=false, - breaklines=true, - captionpos=b, - columns=[c]fixed, - commentstyle=\sl, - escapeinside={[+}{+]}, % chktex 9 - frame=, - backgroundcolor=\color{lstbg}, - keepspaces=true, - keywordstyle=\bf, - postbreak=\mbox{\textcolor{gray}{$\hookrightarrow$}\space}, - showspaces=false, - showstringspaces=false, - showtabs=false, - stringstyle=\it, - tabsize=4, - upquote=true, - numberstyle=\tiny, -} -\usepackage{lstlangclean} -\usepackage{lstlanghaskell} -\usepackage{lstlangarduino} -\lstloadlanguages{% - {[Arduino]C++},% - {c},% - {Python},% - {Clean},% - {[Regular]Haskell}, - {[Lhs2Tex]Haskell}} -\newcommand{\cinline}[1]{\lstinline[language=c,postbreak=]|#1|} -\newcommand{\arduinoinline}[1]{\lstinline[language={[Arduino]C++},postbreak=]|#1|} -\newcommand{\pythoninline}[1]{\lstinline[language=Python,postbreak=]|#1|} -\newcommand{\cleaninline}[1]{\lstinline[language=Clean,postbreak=]|#1|} -\newcommand{\cleaninputlisting}[2][]{\renewcommand*{\lstlistingname}{Listing (\gls{CLEAN})}\lstinputlisting[escapeinside={/*}{*/},language=Clean,#1]{\subfix{#2}}} -\newcommand{\haskellinline}[1]{\lstinline[language={[Regular]Haskell},postbreak=]|#1|} -\newcommand{\haskellinputlisting}[2][]{\renewcommand*{\lstlistingname}{Listing (\gls{HASKELL})}\lstinputlisting[language={[Regular]Haskell},#1]{\subfix{#2}}} -\newcommand{\haskelllhstexinline}[1]{\lstinline[language={[Lhs2Tex]Haskell},postbreak=]|#1|} -%For storing listings in footnotes -\newsavebox{\LstBox} -% Fix list of listings title -\renewcommand{\lstlistlistingname}{List of Listings} -% Fix list of listings chapter separator -\makeatletter -\let\my@chapter\@chapter% -\renewcommand*{\@chapter}{% - \addtocontents{lol}{\protect\addvspace{10pt}}% - \my@chapter} -\makeatother -\lstnewenvironment{lstPython}[1][] - {% - \lstset{language=Python, #1} - \renewcommand*{\lstlistingname}{Listing (\gls{PYTHON})} - } - {} -\lstnewenvironment{lstClean}[1][] - {% - \lstset{language=Clean, #1} - \renewcommand*{\lstlistingname}{Listing (\gls{CLEAN})} - } - {} -\lstnewenvironment{lstArduino}[1][] - {% - \lstset{language={[Arduino]C++}, #1} - \renewcommand*{\lstlistingname}{Listing (\gls{CPP})} - } - {} -\lstnewenvironment{lstHaskell}[1][] - {% - \lstset{language={[Regular]Haskell},#1}% - \renewcommand*{\lstlistingname}{Listing (\gls{HASKELL})} - } - {} -\lstnewenvironment{lstHaskellLhstex}[1][] - {% - \lstset{language={[Lhs2Tex]Haskell},#1}% - \renewcommand*{\lstlistingname}{Listing (\gls{HASKELL})} - } - {} +% Listings +\input{preamble/listings} % Graphics \usepackage{graphicx} % Images diff --git a/preamble/listings.tex b/preamble/listings.tex new file mode 100644 index 0000000..1eb38c0 --- /dev/null +++ b/preamble/listings.tex @@ -0,0 +1,90 @@ +\usepackage{listings} +\newcounter{tmp} +% https://tex.stackexchange.com/questions/149056/how-can-i-define-additional-literate-replacements-without-deleting-existing-ones +\makeatletter +\def\addToLiterate#1{\edef\lst@literate{\unexpanded\expandafter{\lst@literate}\unexpanded{#1}}} +\lst@Key{moreliterate}{}{\addToLiterate{#1}} +\makeatother +% General listings settings +\lstset{% + basewidth=0.5em, + basicstyle=\tt\small, + breakatwhitespace=false, + breaklines=true, + captionpos=b, + columns=[c]fixed, + commentstyle=\sl, + escapeinside={[+}{+]}, % chktex 9 + frame=, + backgroundcolor=\color{lstbg}, + keepspaces=true, + keywordstyle=\bf, + postbreak=\mbox{\textcolor{gray}{$\hookrightarrow$}\space}, + showspaces=false, + showstringspaces=false, + showtabs=false, + stringstyle=\it, + tabsize=4, + upquote=true, + numberstyle=\tiny, +} +\usepackage{preamble/lstlangclean} +\usepackage{preamble/lstlanghaskell} +\usepackage{preamble/lstlangarduino} +\lstloadlanguages{% + {[Arduino]C++},% + {c},% + {Python},% + {Clean},% + {[Regular]Haskell}, + {[Lhs2Tex]Haskell}} +\newcommand{\cinline}[1]{\lstinline[language=c,postbreak=]|#1|} +\newcommand{\arduinoinline}[1]{\lstinline[language={[Arduino]C++},postbreak=]|#1|} +\newcommand{\pythoninline}[1]{\lstinline[language=Python,postbreak=]|#1|} +\newcommand{\cleaninline}[1]{\lstinline[language=Clean,postbreak=]|#1|} +\newcommand{\cleaninputlisting}[2][]{\renewcommand*{\lstlistingname}{Listing (\gls{CLEAN})}\lstinputlisting[escapeinside={/*}{*/},language=Clean,#1]{\subfix{#2}}} +\newcommand{\haskellinline}[1]{\lstinline[language={[Regular]Haskell},postbreak=]|#1|} +\newcommand{\haskellinputlisting}[2][]{\renewcommand*{\lstlistingname}{Listing (\gls{HASKELL})}\lstinputlisting[language={[Regular]Haskell},#1]{\subfix{#2}}} +\newcommand{\haskelllhstexinline}[1]{\lstinline[language={[Lhs2Tex]Haskell},postbreak=]|#1|} +%For storing listings in footnotes +\newsavebox{\LstBox} +% Fix list of listings title +\renewcommand{\lstlistlistingname}{List of Listings} +% Fix list of listings chapter separator +\makeatletter +\let\my@chapter\@chapter% +\renewcommand*{\@chapter}{% + \addtocontents{lol}{\protect\addvspace{10pt}}% + \my@chapter} +\makeatother + +\lstnewenvironment{lstPython}[1][] + {% + \lstset{language=Python, #1} + \renewcommand*{\lstlistingname}{Listing (\gls{PYTHON})} + } + {} +\lstnewenvironment{lstClean}[1][] + {% + \lstset{language=Clean, #1} + \renewcommand*{\lstlistingname}{Listing (\gls{CLEAN})} + } + {} +\lstnewenvironment{lstArduino}[1][] + {% + \lstset{language={[Arduino]C++}, #1} + \renewcommand*{\lstlistingname}{Listing (\gls{CPP})} + } + {} +\lstnewenvironment{lstHaskell}[1][] + {% + \lstset{language={[Regular]Haskell},#1}% + \renewcommand*{\lstlistingname}{Listing (\gls{HASKELL})} + } + {} +\lstnewenvironment{lstHaskellLhstex}[1][] + {% + \lstset{language={[Lhs2Tex]Haskell},#1}% + \renewcommand*{\lstlistingname}{Listing (\gls{HASKELL})} + } + {} diff --git a/lstlangarduino.sty b/preamble/lstlangarduino.sty similarity index 100% rename from lstlangarduino.sty rename to preamble/lstlangarduino.sty diff --git a/lstlangclean.sty b/preamble/lstlangclean.sty similarity index 100% rename from lstlangclean.sty rename to preamble/lstlangclean.sty diff --git a/lstlanghaskell.sty b/preamble/lstlanghaskell.sty similarity index 100% rename from lstlanghaskell.sty rename to preamble/lstlanghaskell.sty diff --git a/self.bib b/self.bib index daad4b1..a2f169d 100644 --- a/self.bib +++ b/self.bib @@ -160,7 +160,7 @@ publisher = {Association for Computing Machinery}, author = {Lubbers, Mart and Koopman, Pieter and Plasmeijer, Rinus}, year = {2022}, - note = {event-place: Kopenhagen, Denmark. under-review}, + note = {event-place: Kopenhagen, Denmark. in-press}, keywords = {clean, distributed applications, functional programming, internet of things, task oriented programming}, } diff --git a/top/blinktree.tex b/top/blinktree.tex new file mode 100644 index 0000000..57c6b19 --- /dev/null +++ b/top/blinktree.tex @@ -0,0 +1,17 @@ +\documentclass[tikz]{standalone} +\usepackage{stmaryrd} +\usetikzlibrary{arrows.meta,shapes.symbols,matrix,positioning} +\begin{document} +\begin{tikzpicture} + \matrix (tree) [matrix of nodes,nodes in empty cells, row sep=1em] { + & \verb#>>|.#\\ + \texttt{delay} & & \verb#>>=.#$~\lambda$\verb#x#$\shortrightarrow$\\ + & \texttt{writeD} & & |[fill=gray!15,label={[xshift=1em,label distance=-5pt]above:{\tiny interpreter}}]|\verb#blink (Not x)#\\ + }; + \draw (tree-1-2.south) -- (tree-2-1.north); + \draw (tree-1-2.south) -- (tree-2-3.north); + \draw (tree-2-3.south) -- (tree-3-2.north); + \draw (tree-2-3.south) -- ([xshift=-1.5em]tree-3-4.north); + \draw [->,dashed] ([xshift=-1.5em]tree-3-4.north) to [out=25,in=25] (tree-1-2.east); +\end{tikzpicture} +\end{document} diff --git a/top/green.tex b/top/green.tex index 962784d..064988d 100644 --- a/top/green.tex +++ b/top/green.tex @@ -208,7 +208,6 @@ The \cleaninline{rpeat} task combinator is a special type of \cleaninline{rpeatE The derived refresh rate of the repeat combinator is the refresh rate of the child if it is unstable. Otherwise, the refresh rate is the embedded rate time minus the start time. In case of the \cleaninline{rpeat} task, the default refresh rate is $\rewriterate{0}{0}$ so the task immediately refreshes and starts the task again. -\todo{netter opschrijven} \subsubsection{Delay combinators} Upon installation, a \cleaninline{delay} task is stored as a \cleaninline{waitUntil} task tree containing the time of installation added to the specified time to wait. diff --git a/top/imp.tex b/top/imp.tex index 6dbd564..cacceec 100644 --- a/top/imp.tex +++ b/top/imp.tex @@ -11,27 +11,32 @@ \begin{chapterabstract} This chapter shows the implementation of the \gls{MTASK} system by: \begin{itemize} + \item elaborating on the implementation and architecture of the \gls{RTS} of \gls{MTASK}; \item giving details of the implementation of \gls{MTASK}'s \gls{TOP} engine that executes the \gls{MTASK} tasks on the microcontroller; \item showing the implementation of the byte code compiler for \gls{MTASK}'s \gls{TOP} language; \item explaining the machinery used to automatically serialise and deserialise data to-and-fro the device. \end{itemize} \end{chapterabstract} -The \gls{MTASK} language targets resource-constrained edge devices that have little memory, processor speed and communication. -Furthermore, microcontrollers usually have flash-based program memory which wears out fairly quick. +\todo[inline]{Dit hoofdstuk is het ruwst van allen} +The \gls{MTASK} system targets resource-constrained edge devices that have little memory, processor speed and communication. +Such edge devices are often powered by microcontrollers. +They usually have flash-based program memory which wears out fairly quick. For example, the flash memory of the popular atmega328p powering the \gls{ARDUINO} UNO is just rated for 10000 write cycles. While this sounds like a lot, if new tasks are sent to the device every minute or so, a lifetime of only seven days is guaranteed. Hence, for dynamic applications, storing the program in the \gls{RAM} of the device and interpreting this code is necessary, saving precious write cycles of the program memory. - In the \gls{MTASK} system, this is done by the \gls{MTASK} \gls{RTS}. + +\section{\texorpdfstring{\Glsxtrlong{RTS}}{Run time system}} The \gls{RTS} is a customisable domain-specific \gls{OS} that takes care of the execution of tasks, but also low-level mechanisms such as the communication, multitasking, and memory management. Once a device is programmed with the \gls{MTASK} \gls{RTS}, it can continuously receive new tasks without the need for reprogramming. The \gls{OS} is written in portable \ccpp{} and only contains a small device-specific portion. In order to keep the abstraction level high and the hardware requirements low, much of the high-level functionality of the \gls{MTASK} language is implemented not in terms of lower-level constructs from \gls{MTASK} language but in terms of \ccpp{} code. -\section{\texorpdfstring{\Glsxtrlong{RTS}}{Run time system}} -The event loop of the \gls{RTS} is executed repeatedly and consists of three distinct phases. -After doing the three phases, the devices goes to sleep for as long as possible (see \cref{chp:green_computing_mtask}). +As most microcontrollers software is run solely by a cyclic executive instead of an \gls{OS}, the \gls{RTS} of the \gls{MTASK} system is implemented as such also. +It consists of a loop function with a relatively short execution time, similar to the one in \gls{ARDUINO}, that gets called repeatedly. +The event loop consists of three distinct phases. +After doing the three phases, the devices goes to sleep for as long as possible (see \cref{chp:green_computing_mtask} for more details on task scheduling). \subsection{Communication} In the first phase, the communication channels are processed. @@ -87,21 +92,48 @@ There are several possible messages that can be received from the server: \end{description} \subsection{Execution} -The second phase consists of performing one execution step for all tasks that wish for it. +The second phase performs one execution step for all tasks that wish for it. Tasks are ordered in a priority queue ordered by the time a task needs to be executed, the \gls{RTS} selects all tasks that can be scheduled, see \cref{sec:scheduling} for more details. Execution of a task is always an interplay between the interpreter and the \emph{rewriter}. +When a new task is received, the main expression is evaluated to produce a task tree. +A task tree is a tree in which each node represents a task combinator and the leaves are basic tasks. If a task is not initialized yet, i.e.\ the pointer to the current task tree is still null, the byte code of the main function is interpreted. The main expression always produces a task tree. Execution of a task consists of continuously rewriting the task until its value is stable. + Rewriting is a destructive process, i.e.\ the rewriting is done in place. The rewriting engine uses the interpreter when needed, e.g.\ to calculate the step continuations. The rewriter and the interpreter use the same stack to store intermediate values. Rewriting steps are small so that interleaving results in seemingly parallel execution. In this phase new task tree nodes may be allocated. -Both rewriting and initialization are atomic operations in the sense that no processing on SDSs is done other than SDS operations from the task itself. +Both rewriting and initialization are atomic operations in the sense that no processing on \glspl{SDS} is done other than \gls{SDS} operations from the task itself. The host is notified if a task value is changed after a rewrite step. +Take for example the blink task for which the code is shown in \cref{lst:blink_code}. + +\begin{lstClean}[caption={Code for a blink program.},label={lst:blink_code}] +fun \blink=(\st->delay (lit 500) >>|. writeD d3 st >>=. blink o Not) +In {main = blink true} +\end{lstClean} + +On receiving this task, the task tree is still null and the initial expression \cleaninline{blink true} is evaluated by the interpreter. +This results in the task tree shown in \cref{fig:blink_tree}. +Rewriting always starts at the top of the tree and traverses to the leaves, the basic tasks that do the actual work. +The first basic task encountered is the \cleaninline{delay} task, that yields no value until the time, \qty{500}{\ms} in this case, has passed. +When the \cleaninline{delay} task yielded a stable value, the task continues with the right-hand side of the \cleaninline{>>\|.} combinator. +This combinator has a \cleaninline{writeD} task at the left-hand side that becomes stable after one rewrite step in which it writes the value to the given pin. +When \cleaninline{writeD} becomes stable, the written value is the task value that is observed by the right-hand side of the \cleaninline{>>=.} combinator. +This will call the interpreter to evaluate the expression, now that the argument of the function is known. +The result of the function is basically the original task tree again, but now with the state inversed. + +\begin{figure} + \centering + \includestandalone{blinktree} + \caption{The task tree for a blink task in \cref{lst:blink_code} in \gls{MTASK}.}% + \label{fig:blink_tree} +\end{figure} + \subsection{Memory management} The third and final phase is memory management. The \gls{MTASK} \gls{RTS} is designed to run on systems with as little as \qty{2}{\kibi\byte} of \gls{RAM}. @@ -115,7 +147,7 @@ The self-managed memory uses a similar layout as the memory layout for \gls{C} p \begin{figure} \centering \includestandalone{memorylayout} - \caption{Memory layout}\label{fig:memory_layout} + \caption{Memory layout in the \gls{MTASK} \gls{RTS}.}\label{fig:memory_layout} \end{figure} A task is stored below the stack and its complete state is a \gls{CLEAN} record contain most importantly the task id, a pointer to the task tree in the heap (null if not initialised yet), the current task value, the configuration of \glspl{SDS}, the configuration of peripherals, the byte code and some scheduling information. @@ -133,7 +165,7 @@ If a task is to be removed, tasks with higher memory addresses are moved down. For task trees---stored in the heap---the \gls{RTS} already marks tasks and task trees as trash during rewriting so the heap can be compacted in a single pass. This is possible because there is no sharing or cycles in task trees and nodes contain pointers pointers to their parent. -\todo{plaa\-tje van me\-mo\-ry hier uitbreiden} +\todo[inline]{plaa\-tje van me\-mo\-ry hier uitbreiden?} \section{Compiler} \subsection{Instruction set} @@ -153,10 +185,10 @@ For example, shorthand instructions are omitted for brevity. Detailed semantics for the instructions are given in \cref{chp:bytecode_instruction_set}. One notable instruction is the \cleaninline{MkTask} instruction, it allocates and initialises a task tree node and pushes a pointer to it on the stack. -\begin{lstClean}[caption={The type housing the instruction set.},label={lst:instruction_type}] +\begin{lstClean}[caption={The type housing the instruction set in \gls{MTASK}.},label={lst:instruction_type}] :: BCInstr //Jumps - = BCJumpF JumpLabel | BCJump JumpLabel | BCLabel JumpLabel | BCJumpSR ArgWidth JumpLabel + = BCJumpF JumpLabel | BCLabel JumpLabel | BCJumpSR ArgWidth JumpLabel | BCReturn ReturnWidth ArgWidth | BCTailcall ArgWidth ArgWidth JumpLabel //Arguments | BCArgs ArgWidth ArgWidth @@ -374,7 +406,7 @@ Arguments wider than one stack cell are fetched in reverse to preserve the order {} & v = \Sigma^{i-1}_{j=0}\stacksize{a_{f^j}}~\text{ and }~ w = v + \stacksize{a_{f^i}}\\ \end{align*} -Translating the compilation schemes for functions to Clean is not as straightforward as other schemes due to the nature of shallow embedding.\todo{deze \P{} moet ge\-\"up\-da\-ted worden} +Translating the compilation schemes for functions to Clean is not as straightforward as other schemes due to the nature of shallow embedding. The \cleaninline{fun} class has a single function with a single argument. This argument is a Clean function that---when given a callable Clean function representing the mTask function---will produce \cleaninline{main} and a callable function. To compile this, the argument must be called with a function representing a function call in mTask. @@ -456,8 +488,6 @@ where rtrn m = m >>| tell` [BCMkTask (bcstable m)] \end{lstClean} -\todo[inline]{uitleg delay} - \subsection{Sequential combinator}\label{ssec:step} The \cleaninline{step} construct is a special type of task because the task value of the left-hand side may change over time. Therefore, the continuation tasks on the right-hand side are \emph{observing} this task value and acting upon it. @@ -596,13 +626,86 @@ instance sds BCInterpret where % VimTeX: SynIgnore off \section{\texorpdfstring{\Gls{C}}{C} code generation}\label{sec:ccodegen} +\todo[inline]{Dit is nog zeer ruw} All communication between the \gls{ITASK} server and the \gls{MTASK} server is type-parametrised. From the structural representation of the type, a \gls{CLEAN} parser and printer is constructed using generic programming. Furthermore, a \ccpp{} parser and printer is generated for use on the \gls{MTASK} device. The technique for generating the \ccpp{} parser and printer is very similar to template metaprogramming and requires a generic programming library or compiler support that includes a lot of metadata in the record and constructor nodes. +Using generic programming in the \gls{MTASK} system, both serialisation and deserialisation on the microcontroller and and the server is automatically generated. + +\subsection{Server} +On the server, off-the-shelve generic programming techniques are used to make the serialisation and deserialisation functions (see \cref{lst:ser_deser_server}). +Serialisation is a simple conversion from a value of the type to a string. +Deserialisation is a little bit different in order to support streaming\footnotemark{}. +\footnotetext{% + Here the \cleaninline{*!} variant of the generic interface is chosen that has less uniqueness constraints for the compiler-generated adaptors\citep{alimarine_generic_2005,hinze_derivable_2001}.% +} +Given a list of available characters, a tuple is always returned. +The right-hand side of the tuple contains the remaining characters, the unparsed input. +The left-hand side contains either an error or a maybe value. +If the value is a \cleaninline{?None}, there was no full value to parse. +If the value is a \cleaninline{?Just}, the data field contains a value of the requested type. + +\begin{lstClean}[caption={Serialisation and deserialisation functions in \gls{CLEAN}.},label={lst:ser_deser_server}] +generic toByteCode a :: a -> String +generic fromByteCode a *! :: [Char] -> (Either String (? a), [Char]) +\end{lstClean} + +\subsection{Client} +The \gls{RTS} of the \gls{MTASK} system runs on resource-constrained microcontrollers and is implemented in portable \ccpp{}. +In order to still achieve some type safety, the communication between the server and the client is automated, i.e.\ the serialisation and deserialisation code in the \gls{RTS} is generated. +The technique used for this is very similar to the technique shown in \cref{chp:first-class_datatypes}. +However, instead of using template metaprogramming, a feature \gls{CLEAN} lacks, generic programming is used also as a two-stage rocket. +In contrast to many other generic programming systems, \gls{CLEAN} allows for access to much of the metadata of the compiler. +For example, \cleaninline{Cons}, \cleaninline{Object}, \cleaninline{Field}, and \cleaninline{Record} generic constructors are enriched with their arity, names, types, \etc. +Furthermore, constructors can access the metadata of the objects and fields of their parent records. +Using this metadata, generic functions can be created that generate \ccpp{} type definitions, parsers and printers for any first-order \gls{CLEAN} type. +The exact details of this technique can be found later in a paper that is in preparation\todo{noe\-men?}. + +\Glspl{ADT} are converted to tagged unions, newtypes to typedefs, records to structs, and arrays to dynamically size-parametrised allocated arrays. +For example, the \gls{CLEAN} types in \cref{lst:ser_clean} are translated to the \ccpp{} types seen in \cref{lst:ser_c} + +\begin{lstClean}[caption={Simple \glspl{ADT} in \gls{CLEAN}.},label={lst:ser_clean}] +:: T a = A a | B NT {#Char} +:: NT =: NT Real +\end{lstClean} + +\begin{lstArduino}[caption={Simple \glspl{ADT} in \ccpp{}.},label={lst:ser_c}] +typedef double Real; +typedef char Char; + +typedef Real NT; +enum T_c {A_c, B_c}; + +struct Char_HshArray { uint32_t size; Char *elements; }; +struct T { + enum T_c cons; + struct { void *A; + struct { NT f0; struct Char_HshArray f1; } B; + } data; +}; +\end{lstArduino} + +For each of these generated types, two functions are created, a typed printer, and a typed parser (see \cref{lst:ser_pp}). +The parser functions are parametrised by a read function, an allocation function and parse functions for all type variables. +This allows for the use of these functions in environments where the communication is parametrised and the memory management is self-managed such as in the \gls{MTASK} \gls{RTS}. + +\begin{lstArduino}[caption={Printer and parser for the \glspl{ADT} in \ccpp{}.},label={lst:ser_pp}] +struct T parse_T(uint8_t (*get)(), void *(*alloc)(size_t), void *(*parse_0)(uint8_t (*)(), void *(*)(size_t))); + +void print_T(void (*put)(uint8_t), struct T r, void (*print_0)(void (*)(uint8_t), void *)); +\end{lstArduino} +\todo[inline]{uitbreiden, maar niet te veel} \section{Conclusion} -Tasks in the \gls{MTASK} system are executed on resource-constrained \gls{IOT} edge devices. +It is not straightforward to execute \gls{MTASK} tasks on resources-constrained \gls{IOT} edge devices. +To achieve this, the terms in the \gls{DSL} are compiled to domain-specific byte code. +This byte code is sent for interpretation to the light-weight \gls{RTS} of the edge device. +First the expression is evaluated. +The result of this evaluation, a run time representation of the task, is a task tree. +This task tree is rewritten according to rewrite rules until a stable value is observed. +Rewriting multiple tasks at the same time is achieved by interleaving the rewrite steps, resulting in seamingly parallel execution of the tasks. +All communication is automated. \todo[inline]{conclusion} diff --git a/top/lang.tex b/top/lang.tex index 0d2f3ab..1b5735d 100644 --- a/top/lang.tex +++ b/top/lang.tex @@ -326,7 +326,6 @@ Creating tasks is done by evaluating expressions. The result of an evaluated task expression is called a task tree, a run time representation of a task. In order to evaluate a task, the resulting task tree is \emph{rewritten}, i.e.\ similar to rewrite systems, they perform a bit of work, step by step. With each step, a task value is yielded that is observable by other tasks and can be acted upon. -\todo{dui\-de\-lijk ge\-noeg?} The implementation in the \gls{MTASK} \gls{RTS} for task execution is shown in \cref{chp:implementation}. The following sections show the definitions of the functions for creating tasks. @@ -688,7 +687,6 @@ The language is an enriched lambda calculus as a host language. It provides language constructs for arithmetic expressions, conditionals, functions, but also non-interactive basic tasks, task combinators, peripheral support, and integration with \gls{ITASK}. Terms in the language are just interfaces and can be interpreted by one or more interpretations. The most important interpretation of the language is the byte code compiler. -\todo{Uit\-brei\-den?} \input{subfilepostamble} \end{document} diff --git a/top/memorylayout.tex b/top/memorylayout.tex index f7e24c8..c18c2a5 100644 --- a/top/memorylayout.tex +++ b/top/memorylayout.tex @@ -1,4 +1,25 @@ \documentclass[tikz]{standalone} +%\usepackage{listings} +%\lstset{% +% basewidth=0.5em, +% basicstyle=\tt\scriptsize, +% breakatwhitespace=false, +% breaklines=true, +% captionpos=b, +% columns=[c]fixed, +% commentstyle=\sl, +% escapeinside={[+}{+]}, % chktex 9 +% frame=, +% keepspaces=true, +% keywordstyle=\bf, +% showspaces=false, +% showstringspaces=false, +% showtabs=false, +% stringstyle=\it, +% tabsize=4, +% numberstyle=\tiny, +% language=C, +%} \usetikzlibrary{arrows.meta,shapes.symbols,matrix,positioning} \begin{document} \begin{tikzpicture}[% @@ -50,5 +71,28 @@ \draw[dashed] (main-7-2.north west) -- (global-1-2.north east); \draw[dashed] (main-8-2.south west) -- (global-4-2.south east); + +% \node (tree) [right=of heap] { +%\begin{lstlisting} +%struct TaskTree { +% enum BCTaskType_c task_type; +% bool trash; +% uint16_t refresh_min; +% uint16_t refresh_max; +% struct TaskTree *parent; +% union { +% ... +% uint16_t readd; +% ... +% struct { +% struct TaskTree *lhs; +% struct TaskTree *rhs; +% } tand; +% ... +% } data;\end{lstlisting} +% }; +% +% \draw[dashed] (tree.north west) -- (heap-1-2.north east); +% \draw[dashed] (tree.south west) -- (heap-1-2.south east); \end{tikzpicture} \end{document} diff --git a/tvt/img/bar_chart.pdf b/tvt/img/bar_chart.pdf index 2abbc1b..a4a9885 100644 Binary files a/tvt/img/bar_chart.pdf and b/tvt/img/bar_chart.pdf differ diff --git a/tvt/img/gen_stacked_barchart.py b/tvt/img/gen_stacked_barchart.py index af3d6ec..ec73abb 100644 --- a/tvt/img/gen_stacked_barchart.py +++ b/tvt/img/gen_stacked_barchart.py @@ -44,7 +44,8 @@ print(df) fig, ax = plt.subplots() -ax.bar(df.columns, df.loc[components[-1]], label=components[-1]) +ax.bar(df.columns, df.loc[components[-1]], label=components[-1], + color=CB_color_cycle[-1]) baseline = df.loc[components[-1]] for i in range(len(components)-2, -1, -1): ax.bar(df.columns, df.loc[components[i]], label=components[i], @@ -81,8 +82,7 @@ ax.set_position([box.x0, box.y0, box.width * 0.7, box.height]) handles, labels = plt.gca().get_legend_handles_labels() ##order = list(range(len(components))) -order = list(range(len(components)-1, -1, -1)) -plt.legend([handles[idx] for idx in order],[labels[idx] for idx in order], loc='center left', bbox_to_anchor=(1, 0.5)) +plt.legend(reversed(handles),reversed(labels), loc='center left', bbox_to_anchor=(1, 0.5)) ##ax.legend()