Merge branch 'master' of git.martlubbers.net:msc-thesis1617
[msc-thesis1617.git] / pres.system.tex
1 \subsection{Overview}
2 \begin{frame}
3 \frametitle{Current state of mTask}
4 \begin{itemize}
5 \item Suits our needs as an EDSL
6 \item It all seems perfect
7 \item \ldots\pause{} but\ldots
8 \pause{}
9 \item No interaction
10 \item Compilation requires reprogramming
11 \item Entire system is created and fixed
12 \end{itemize}
13 \end{frame}
14
15 \begin{frame}
16 \frametitle{Solution}
17 \begin{itemize}[<+->]
18 \item Reuse mTask
19 \item New bytecode backend for mTask
20 \item Interpreter on client
21 \item Server in iTasks with integration
22 \item No taskserver generation, onetime programming
23 \item Dynamic task sending
24 \end{itemize}
25 \end{frame}
26
27 \subsection{Extending mTask}
28 \begin{frame}[fragile]
29 \frametitle{Adding a View}
30 \begin{lstlisting}[language=Clean]
31
32 :: ByteCode a p = BC (RWS () [BC] BCState ())
33
34 :: RWS r w s a = RWS (r s -> (a, s, w))
35 :: BC = BCNop | BCPush BCValue | ...
36 :: BCValue = E.e: BCValue e & mTaskType, TC e
37 :: BCShare = { sdsi :: Int, sdsval :: BCValue, sdsname :: String }
38 :: BCState = { freshl :: Int, freshs :: Int, sdss :: [BCShare] }
39
40 class mTaskType a | toByteCode, fromByteCode, iTask, TC a
41 class toByteCode a :: a -> String
42 class fromByteCode a :: String -> a
43
44 instance ByteCode arith, boolExpr, ...
45 \end{lstlisting}
46 \end{frame}
47
48 \begin{frame}[fragile]
49 \frametitle{Implementation}
50 \begin{itemize}
51 \item Reader Write State Transformer Monad
52 \item Write instruction
53 \item Carry state
54 \item Hand-crafted helpers
55 \end{itemize}
56 \begin{lstlisting}[language=Clean]
57 op2 :: (ByteCode a p1) (ByteCode a p2) BC -> ByteCode b Expr
58 op2 (BC x) (BC y) bc = BC (x >>| y >>| tell [bc])
59
60 tell2 :: [BC] -> (ByteCode a p)
61 tell2 x = BC (tell x)
62
63 instance arith ByteCode where
64 lit x = tell2 [BCPush (BCValue x)]
65 (+.) x y = op2 x y BCAdd
66 ...
67 \end{lstlisting}
68 \end{frame}
69
70 \begin{frame}[fragile]
71 \frametitle{Control flow}
72 \begin{itemize}
73 \item Use labels
74 \item Label are resolved
75 \pause{}
76 \item Thus no reuse
77 \end{itemize}
78 \pause{}
79 \begin{lstlisting}[language=Clean]
80 :: BC = ... | BCLab Int | ...
81
82 freshlabel = get >>= \st=:{freshl}->put {st & freshl=freshl+1} >>| pure freshl
83
84 instance IF ByteCode
85 where
86 IF b t e = BCIfStmt b t e
87 (?) b t = BCIfStmt b t (tell` [])
88
89 BCIfStmt (BC b) (BC t) (BC e) = BC (
90 freshlabel >>= \else->freshlabel >>= \endif->
91 b >>| tell [BCJmpF else] >>|
92 t >>| tell [BCJmp endif, BCLab else] >>|
93 e >>| tell [BCLab endif]
94 )
95 \end{lstlisting}
96 \end{frame}
97
98 \begin{frame}[fragile]
99 \frametitle{Assignment and SDSs}
100 \begin{lstlisting}[language=Clean]
101 instance sds ByteCode where
102 sds f = {main = BC (freshshare
103 >>= \sdsi->pure {BCShare|sdsname="",sdsi=sdsi,sdsval=BCValue 0}
104 >>= \sds->pure (f (tell2 [BCSdsFetch sds]))
105 >>= \(v In bdy)->modify (addSDS sds v)
106 >>| unBC (unMain bdy))
107 }
108
109 instance assign ByteCode where
110 (=.) (BC v) (BC e) = BC (e >>| censor makeStore v)
111
112 addSDS sds v s = {s & sdss=[{sds & sdsval=BCValue v}:s.sdss]}
113
114 makeStore [BCSdsFetch i] = [BCSdsStore i]
115 makeStore [BCDigitalRead i] = [BCDigitalWrite i]
116 makeStore [...] = [...]
117 \end{lstlisting}
118 \end{frame}
119
120 \begin{frame}[fragile]
121 \frametitle{Bandwidth is scarce}
122 Publish SDS explicitly
123 \pause{}
124 \begin{lstlisting}
125 class sdspub v where
126 pub :: (v t Upd) -> (v () Stmt)
127
128 instance sdspub ByteCode where
129 pub (BC x)
130 = BC (censor (\[BCSdsFetch s]->[BCSdsPublish s]) x)
131 \end{lstlisting}
132 \end{frame}
133
134 \begin{frame}[fragile]
135 \frametitle{Task scheduling}
136 \begin{block}{Arduino C++ system}
137 \begin{itemize}
138 \item Task server
139 \item Tasks start other tasks
140 \end{itemize}
141 \end{block}
142 \pause{}
143 \begin{block}{Interpreted Bytecode system}
144 \begin{itemize}[<+->]
145 \item Task accompanied with strategy
146 \item \CI{OnShot}, \CI{OnInterval}, \CI{OnInterrupt}
147 \item How to handle termination?
148 \end{itemize}
149 \pause{}
150 \begin{lstlisting}[language=Clean]
151 class retrn v where
152 retrn :: v () Expr
153 \end{lstlisting}
154 \end{block}
155 \end{frame}
156
157 \subsection{Devices}
158 \begin{frame}[fragile]
159 \frametitle{Devices}
160 \begin{itemize}[<+->]
161 \item Standard C client software
162 \item Modular implementation
163 \item Specification generated from the macros
164 \end{itemize}
165 \pause{}
166 \begin{lstlisting}[language=C,caption={interface.h}]
167 ...
168 #elif defined TARGET_STM32F767ZI
169 #define APINS 128
170 ...
171 #define HAVELED 1
172 #define HAVEHB 1
173
174 #elif defined ARDUINO_ESP8266_NODEMCU
175 ...
176 bool input_available(void);
177 uint8_t read_byte(void);
178 void write_byte(uint8_t b);
179
180 #if DPINS > 0
181 void write_dpin(uint8_t i, bool b);
182 ...
183 \end{lstlisting}
184 \end{frame}
185
186 \begin{frame}[fragile]
187 \frametitle{Storage}
188 \begin{itemize}[<+->]
189 \item Heap is there, but inefficient
190 \item Allocate space in global data
191 \item Selfmanage it
192 \item Tasks grow up
193 \item SDSs grow down
194 \item Compacting on removal
195 \end{itemize}
196 \pause{}
197 \begin{lstlisting}[language=C]
198 struct task {
199 uint16_t tasklength;
200 uint16_t interval;
201 unsigned long lastrun;
202 uint8_t taskid;
203 uint8_t *bc;
204 };
205 \end{lstlisting}
206 \end{frame}
207
208 \begin{frame}[fragile]
209 \frametitle{Interpreter}
210 Stack machine, modular
211 \pause{}
212 \begin{lstlisting}[language=C]
213 #define f16(p) program[pc]*265+program[pc+1]
214
215 void run_task(struct task *t){
216 uint8_t *program = t->bc;
217 int plen = t->tasklength, pc = 0, sp = 0;
218 while(pc < plen){
219 switch(program[pc++]){
220 case BCPUSH:
221 stack[sp++] = pc++ //Simplified
222 break;
223 case BCADD:
224 stack[sp-2] = stack[sp-2] + stack[sp-1];
225 sp -= 1;
226 break;
227 case BCJMPT:
228 pc = stack[--sp] ? program[pc]-1 : pc+1;
229 break;
230 #if APINS > 0
231 case BCANALOGREAD:
232 ...
233 \end{lstlisting}
234 \end{frame}
235
236 \subsection{Server}
237 \begin{frame}[fragile]
238 \frametitle{Device storage}
239 \begin{lstlisting}[language=Clean]
240 :: Channels :== ([MTaskMSGRecv], [MTaskMSGSend], Bool)
241 :: MTaskResource
242 = TCPDevice TCPSettings
243 | SerialDevice TTYSettings
244 | ...
245 :: MTaskDevice =
246 { deviceTask :: Maybe TaskId , deviceError :: Maybe String
247 , deviceChannels :: String , deviceName :: String
248 , deviceState :: BCState , deviceTasks :: [MTaskTask]
249 , deviceResource :: MTaskResource
250 , deviceSpec :: Maybe MTaskDeviceSpec
251 , deviceShares :: [MTaskShare]
252 }
253
254 channels :: MTaskDevice -> Shared Channels
255
256 class MTaskDuplex a where
257 synFun :: a (Shared Channels) -> Task ()
258 \end{lstlisting}
259 \end{frame}
260
261 \begin{frame}
262 \frametitle{SDS storage}
263 \begin{block}{Approaches}
264 \begin{itemize}[<+->]
265 \item One SDS per SDS
266 \item One SDS per Device and map
267 \item One SDS in the entire system and map
268 \end{itemize}
269 \end{block}
270
271 \pause{}
272
273 \begin{block}{Notifications}
274 \begin{itemize}[<+->]
275 \item Tasks monitoring the SDSs
276 \item Parametric lenses!
277 \end{itemize}
278 \end{block}
279 \end{frame}
280
281 \begin{frame}[fragile]
282 \frametitle{SDS (2)}
283 \framesubtitle{Parametric Lenses}
284 \begin{block}{What is the \CI{p} for in \CI{RWShared p r w}}
285 \pause{}
286 \begin{itemize}
287 \item Parameter fixed when writing
288 \item Used for notifications
289 \item On write the SDS returns \CI{p -> Bool}
290 \end{itemize}
291 \pause{}
292 \end{block}
293 \begin{lstlisting}[language=Clean]
294 sdsFocus :: p1 (RWShared p1 r w) -> RWShared p2 r w | iTask p
295 \end{lstlisting}
296 \end{frame}
297
298 \begin{frame}[fragile]
299 \frametitle{Solve the notification problem and how to relay information?}
300 \begin{itemize}
301 \item Tailor made share
302 \item The read and write functions have the World
303 \end{itemize}
304
305 \pause{}
306
307 \begin{onlyenv}<2>
308 \begin{lstlisting}[language=Clean]
309 :: P :== Maybe (MTaskDevice, Int)
310 deviceStore :: RWShared P [MTaskDevice] [MTaskDevice]
311 deviceStore = SDSSource {SDSSource
312 | name="deviceStore", read=realRead, write=realWrite}
313 where
314 realDeviceStore :: Shared [MTaskDevice]
315 realDeviceStore = sharedStore "mTaskDevices" []
316
317 realRead :: P *IWorld -> (MaybeError TaskException [MTaskDevice], *IWorld)
318 realRead p iw = read realDeviceStore iw
319 \end{lstlisting}
320 \end{onlyenv}
321
322 \begin{onlyenv}<3>
323 \begin{lstlisting}[language=Clean]
324 realWrite :: P [MTaskDevice] *IWorld
325 -> (MaybeError TaskException (SDSNotifyPred P), *IWorld)
326 realWrite mi w iw
327 # (merr, iw) = write w realDeviceStore iw
328 | isNothing mi = (Ok $ gEq{|*|} mi, iw)
329 # (Just (dev, ident)) = mi
330 | ident == -1 = (Ok $ gEq{|*|} mi, iw)
331 = case find ((==)dev) w of
332 Nothing = (Error $ exception "Device lost", iw)
333 Just {deviceShares} = case find (\d->d.identifier == ident) deviceShares of
334 Nothing = (Error $ exception "Share lost", iw)
335 Just s = case sendMessagesIW [MTUpd ident s.MTaskShare.value] dev iw of
336 (Error e, iw) = (Error e, iw)
337 (Ok _, iw) = (Ok $ gEq{|*|} mi, iw)
338 \end{lstlisting}
339 \end{onlyenv}
340 \end{frame}
341
342 \begin{frame}[fragile]
343 \frametitle{Specific SDS functions}
344 \begin{lstlisting}
345 deviceStoreNP :: Shared [MTaskDevice]
346 deviceStoreNP = sdsFocus Nothing deviceStore
347
348 deviceShare :: MTaskDevice -> Shared MTaskDevice
349 deviceShare d = mapReadWriteError
350 ( \ds->case find ((==)d) ds of
351 Nothing = exception "Device lost"
352 Just d = Ok d)
353 , \w ds->case splitWith ((==)d) ds of
354 ([], _) = Error $ exception "Device lost"
355 ([_], ds) = Ok $ Just [w:ds])
356 $ sdsFocus (Just (d, -1)) deviceStore
357
358 shareShare :: MTaskDevice MTaskShare -> Shared BCValue
359 ...
360 \end{lstlisting}
361 \end{frame}
362
363 \subsection{Communication}
364 \begin{frame}
365 \frametitle{The glue of the system}
366 \pause{}
367 \begin{block}{Communication}
368 \begin{itemize}
369 \item Compile, send and interact with Tasks
370 \item Interact with SDSs
371 \item All communication via channels
372 \end{itemize}
373 \end{block}
374 \end{frame}
375
376 \begin{frame}[fragile]
377 \frametitle{Messages}
378 \begin{lstlisting}[language=Clean]
379 :: MTaskId :== Int
380 :: MSDSId :== Int
381 :: MTaskFreeBytes :== Int
382 :: MTaskMSGRecv
383 = MTTaskAck MTaskId MTaskFreeBytes | MTTaskDelAck MTaskId
384 | MTSDSAck MSDSId | MTSDSDelAck MSDSId
385 | MTPub MSDSId BCValue | MTMessage String
386 | MTDevSpec MTaskDeviceSpec | MTEmpty
387
388 :: MTaskMSGSend
389 = MTTask MTaskInterval String | MTTaskDel MTaskId
390 | MTShutdown | MTSds MSDSId BCValue
391 | MTUpd MSDSId BCValue | MTSpec
392 \end{lstlisting}
393 \end{frame}
394
395 \begin{frame}[fragile]
396 \frametitle{Connecting with a device}
397 \begin{lstlisting}[language=Clean]
398 process :: MTaskDevice (Shared Channels) -> Task ()
399 process ...
400
401 makeDevice :: String MTaskResource -> MTaskDevice
402
403 connectDevice :: MTaskDevice -> Task MTaskDevice
404 connectDevice device = set ([], [], False) ch
405 >>| appendTopLevelTask newMap True
406 ( process device ch -||- catchAll (getSynFun device.deviceData ch) errHdl)
407 >>= \tid->upd (\d->{d&deviceTask=Just tid,deviceError=Nothing}) (deviceShare device)
408 >>| set (r,[MTSpec],ss) ch
409 >>| treturn device
410 where
411 errHdl e = upd (\d->{d & deviceTask=Nothing, deviceError=Just e}) (deviceShare device) @! ()
412 ch = channels device
413 \end{lstlisting}
414 \end{frame}
415
416 \begin{frame}
417 \frametitle{Compilation}
418 \begin{itemize}[<+->]
419 \item Get device's compiler state
420 \item Run the RWS
421 \item Resolve labels
422 \item Instantiate shares
423 \item Convert to messages
424 \item Update state
425 \item Send the messages
426 \end{itemize}
427 \end{frame}
428
429 \begin{frame}[fragile]
430 \frametitle{Interaction with devices}
431 \begin{block}{Send task}
432 \begin{lstlisting}[language=Clean]
433 sendTaskToDevice :: String (Main (ByteCode a Stmt)) (MTaskDevice, MTaskInterval)
434 -> Task (MTaskTask, [MTaskShare])
435 \end{lstlisting}
436 \end{block}
437 \end{frame}
438
439 \begin{frame}[fragile]
440 \frametitle{Example, blink}
441 \begin{lstlisting}[language=Clean]
442 blink :: Task ()
443 blink = addDevice
444 >>= connectDevice
445 >>= \stm->sendTaskToDevice "blink" blinkTask (stm, OnInterval 1000)
446 >>= \(st, [_,t])->forever (
447 updateSharedInformation "Which led to blink" [] (shareShare stm t)
448 ) >>* [OnAction (Action "Shutdown") $ always
449 $ deleteDevice stm >>| shutDown 0
450 ]
451 where
452 blinkTask = sds \led=LED1 In sds \x=True In {main =
453 ledOff led1 :. ledOff led2 :. ledOff led3 :.
454 IF x (ledOff led) (ledOn led) :.
455 x =. Not x}
456 \end{lstlisting}
457 \end{frame}