tasks language support for
play

Tasks: Language Support for The problem Event-Driven Programming - PDF document

SoCal Workshop Feb 2, 2008 Outline Tasks: Language Support for The problem Event-Driven Programming Example: Threads vs. Events The TaskJava language Related work Jeffrey Fischer, Rupak Majumdar, and Todd Millstein


  1. SoCal Workshop Feb 2, 2008 Outline Tasks: Language Support for  The problem Event-Driven Programming  Example: Threads vs. Events  The TaskJava language  Related work Jeffrey Fischer, Rupak Majumdar, and Todd Millstein  Applications UCLA Computer Science Dept. The Problem The Problem  Current solutions for interleaved computation  Current solutions for interleaved computation suffer a number of drawbacks suffer a number of drawbacks  Multi-threaded servers  Event-driven servers  Introduce concurrency  Must manually translate to continuation-passing style  Performance issues when using large number of threads  Difficult to follow control flow  May lead to bugs!  Not suitable for some contexts (embedded systems, some OS kernels, business processes)  Cannot easily take advantage of language features such as inheritance and exceptions Our solution: TaskJava Code layout: threads vs. events High performance concurrency while preserving Multithreaded version program structure.  Extension to Java foo() { X = blockingCall(buf);  Programming model: Tasks “look like” threads, but if (x==OK) {...} run like events else {...} } Blocks in  Compiler performs modular CPS translation operating system Jeff Fischer, UCLA 1

  2. SoCal Workshop Feb 2, 2008 Code layout: threads vs. events Code layout: threads vs. events Multithreaded version Event-driven version Multithreaded version Event-driven version foo() { foo() { nonblockCall(buf, nonblockCall(buf, foo2); foo2); foo() { foo() { } } X = X = blockingCall(buf); blockingCall(buf); Initiate call Scheduler runs other events Scheduler runs other events and return if (x==OK) {...} Continuation if (x==OK) {...} else {...} else {...} } } foo2(x) { foo2(x) { if (x==OK) {...} if (x==OK) {...} else {...} else {...} } } Scheduler runs continuation Bugs in event-driven code Bugs in event-driven code nonblockCall(buf, cnt) { nonblockCall(buf, cnt) { nonblockCall(buf, cnt) { nonblockCall(buf, cnt) { foo() { foo() { ... ... ... ... nonblockCall(buf, nonblockCall(buf, reg(e 1 , e 2 , nb2); reg(e 1 , e 2 , nb2); reg(e 1 , e 2 , nb2); reg(e 1 , e 2 , nb2); foo2); foo2); } } } } } } Register events Scheduler runs other events Scheduler runs other events and callback with nb2(event) { nb2(event) { foo2(result) { nb2(event) { nb2(event) { foo2(result) { scheduler nb2(event) { nb2(event) { if (result==OK){ if (event==e 1 ) { if (event==e 1 ) { if (event==e 1 ) { if (result==OK){ if (event==e 1 ) { if (event==e 1 ) { if (event==e 1 ) { ... ... ... ... ... ... ... ... } else { cnt(OK); cnt(OK); cnt(OK); } else { cnt(OK); cnt(OK); cnt(OK); } } ... } } ... } } } else cnt(NOT_OK); else cnt(NOT_OK); else cnt(NOT_OK); } else cnt(NOT_OK); else cnt(NOT_OK); else cnt(NOT_OK); } } } } } } } } Bugs in event-driven code Code layout: TaskJava Source code Compiled code nonblockCall(buf, cnt) { nonblockCall(buf, cnt) { foo() { ... ... nonblockCall(buf, reg(e 1 , e 2 , nb2); reg(e 1 , e 2 , nb2); foo2); foo() { } } } blockingCall(buf, foo2); Lost continuation async foo() { } bug if nb2 forgets Scheduler runs other events X = to call foo2 blockingCall(buf); nb2(event) { foo2(result) { nb2(event) { nb2(event) { Scheduler runs other events if (x==OK) {...} if (result==OK){ if (event==e 1 ) { if (event==e 1 ) { if (event==e 1 ) { else {...} ... ... ... ... } } else { cnt(OK); cnt(OK); cnt(OK); foo2(x) { } if (x==OK) {...} ... } } } else cnt(NOT_OK); else cnt(NOT_OK); else cnt(NOT_OK); else {...} Lost exception bug if } } } } } nb2 forgets to pass error to foo2 Jeff Fischer, UCLA 2

  3. SoCal Workshop Feb 2, 2008 TaskJava features TaskJava features Asychronous Class WriteTask implements Task { Class WriteTask implements Task { method call The Task void run() { ... void run() { ... interface looks do { write(buffer); do { write(buffer); like Java’s } while (buffer.hasRemaining()); ... } while (buffer.hasRemaining()); ... Thread interface } } Method async void write(CharBuffer buffer) async void write(CharBuffer buffer) annotation throws IOException { throws IOException { Event e = wait (channel, Event.WRITE, Event e = wait (channel, Event.WRITE, Event.ERROR); Event.ERROR); switch (e.type()) { switch (e.type()) { case Event.WRITE: ch.write(buffer); break; case Event.WRITE: ch.write(buffer); break; case Event.ERROR: throw new IOException(); case Event.ERROR: throw new IOException(); } } } } } } TaskJava features Translating TaskJava to Java Class WriteTask implements Task {  Bodies of Task run and async methods split void run() { ... into continuation passing style do { write(buffer); } while (buffer.hasRemaining()); ...  Explicit callbacks introduced by compiler Yield until one } of the events async void write(CharBuffer buffer) occurs throws IOException {  wait (Set) → Event e = wait (channel, Event.WRITE, <Scheduler>.register(Set, new cb(...)) Event.ERROR); switch (e.type()) { case Event.WRITE: ch.write(buffer); break;  Scheduler class provided as option to case Event.ERROR: throw new IOException(); compiler } Errors signaled } } by throwing exceptions Formalizing TaskJava Translating TaskJava: the tricky bits  Local variables  Defined semantic rules and type system  Move to heap if used across async calls  Nested asynchronous calls  Prove key properties:  Introduce temporary variables  Type soundness  No lost continuations or lost exceptions  Loops  Flatten and use switch statement to simulate goto’s  Translation to Java  Exceptions  Separate callbacks for error control flow Jeff Fischer, UCLA 3

  4. SoCal Workshop Feb 2, 2008 Formalizing TaskJava Formalizing TaskJava e → e’ e → e’ Program Program Current task’s Current task’s Evaluator Evaluator expr expr E[Wait (es )] E[Wait(es)] E[ ε ] E[ ε ] Scheduler state Scheduler state S → S’ S → S’ Non-deterministic Non-deterministic {(E 1 [], es 1 ), {(E 1 [], es 1 ), Scheduler (E 2 [], es 2 ),…} Scheduler (E 2 [], es 2 ),…} Formalizing TaskJava Formalizing TaskJava e → e’ e → e’ Program Program Current task’s Current task’s Evaluator Evaluator expr expr E[Wait (es )] E[Wait (es )] E[ ε ] E[ ε ] Scheduler state Scheduler state S → S’ S → S’ Non-deterministic Non-deterministic {(E 1 [], es 1 ), {(E 1 [], es 1 ), Scheduler (E 2 [], es 2 ),…} Scheduler (E 2 [], es 2 ),…} Formalizing TaskJava So, what’s new?  Type system tracks blocking methods e → e’ Program Current task’s  Compiler translates only blocking methods Evaluator expr  Safe  Coexists with existing libraries E[Wait (es )] E[ ε ]  Compiler generates scheduler-independent Scheduler state S → S’ Non-deterministic code {(E 1 [], es 1 ), Scheduler (E 2 [], es 2 ),…}  Case study: web server with pure-event and thread-pooled schedulers Jeff Fischer, UCLA 4

  5. SoCal Workshop Feb 2, 2008 Related work Related work: Cooperative Multitasking  User-level threads through stack  Cooperative multitasking manipulation  Functional programming languages  Many implementations  E.g. [Engelschall 00], [von Behren, et. al. 03]  Other language approaches  Does not work for most VM-based languages  Scheduler is fixed Related work: Functional programming Related work: Functional programming languages languages  Scheme: avoid inversion of control issues in web  “Continuations from generalized stack programming inspection” [Pettyjohn, et al. 05]  First-class continuations [Graunke 01], [Queinnec 03]  Whole program CPS transformations [Matthews, et. al. 04]  Implements Scheme continuations on .NET VM  Concurrent ML [Reppy 91]  Uses exception handlers and stack copying  User-level pre-emptive threads and first class events  Built on top of continuations Related work: other language approaches Applications of TaskJava  TAME: C++ Library for event-driven programming  TaskJava in embedded environments [Krohn and Kohler 06]  Implements a localized CPS-transform via templates  Emphasizes flexibility over safety  W eb applications  MAWL [Ball and Aktins 99]  DSL for Web applications  Scala actor library  Programming provides continuation as a closure  Type system ensures that “async” call does not return values Jeff Fischer, UCLA 5

Recommend


More recommend