Polyphonic C - PowerPoint PPT Presentation

1 / 39
About This Presentation
Title:

Polyphonic C

Description:

Polyphonic C – PowerPoint PPT presentation

Number of Views:88
Avg rating:3.0/5.0
Slides: 40
Provided by: nic17
Category:
Tags: moly | polyphonic

less

Transcript and Presenter's Notes

Title: Polyphonic C


1
Polyphonic C
  • Nick Benton
  • Luca Cardelli
  • Cédric Fournet
  • Microsoft Research

2
Asynchrony is where its at
  • Distribution gt concurrency latency
    gt asynchrony gt more
    concurrency
  • Message-passing, event-based programming,
    dataflow models
  • For programming languages, coordination
    (orchestration) languages frameworks, workflow

3
Language support for concurrency
  • Make invariants and intentions more apparent
    (part of the interface)
  • Good software engineering
  • Allows the compiler much more freedom to choose
    different implementations
  • Also helps other tools

4
.NET today
  • Java-style monitors
  • OS shared memory primitives
  • Clunky delegate-based asynchronous calling model
  • Hard to understand, use and get right
  • Different models at different scales
  • Support for asynchrony all on the caller side
    little help building code to handle messages
    (must be thread-safe, reactive, and deadlock-free)

5
Polyphonic C
  • An extension of the C language with new
    concurrency constructs
  • Based on the join calculus
  • A foundational process calculus like the
    p-calculus but better suited to asynchronous,
    distributed systems
  • A single model which works both for
  • local concurrency (multiple threads on a single
    machine)
  • distributed concurrency (asynchronous messaging
    over LAN or WAN)
  • It is different
  • But its also simple if Mort can do any kind of
    concurrency, he can do this

6
In one slide
  • Objects have both synchronous and asynchronous
    methods.
  • Values are passed by ordinary method calls
  • If the method is synchronous, the caller blocks
    until the method returns some result (as usual).
  • If the method is async, the call completes at
    once and returns void.
  • A class defines a collection of chords
    (synchronization patterns), which define what
    happens once a particular set of methods have
    been invoked. One method may appear in several
    chords.
  • When pending method calls match a pattern, its
    body runs.
  • If there is no match, the invocations are queued
    up.
  • If there are several matches, an unspecified
    pattern is selected.
  • If a pattern containing only async methods fires,
    the body runs in a new thread.

7
A simple buffer
  • class Buffer
  • String get() async put(String s)
  • return s

8
A simple buffer
  • class Buffer
  • String get() async put(String s)
  • return s
  • An ordinary (synchronous) method with no
    arguments, returning a string

9
A simple buffer
  • class Buffer
  • String get() async put(String s)
  • return s
  • An ordinary (synchronous) method with no
    arguments, returning a string
  • An asynchronous method (hence returning no
    result), with a string argument

10
A simple buffer
  • class Buffer
  • String get() async put(String s)
  • return s
  • An ordinary (synchronous) method with no
    arguments, returning a string
  • An asynchronous method (hence returning no
    result), with a string argument
  • Joined together in a chord

11
A simple buffer
  • class Buffer
  • String get() async put(String s)
  • return s
  • Calls to put() return immediately (but are
    internally queued if theres no waiting get()).
  • Calls to get() block until/unless theres a
    matching put()
  • When theres a match the body runs, returning the
    argument of the put() to the caller of get().
  • Exactly which pairs of calls are matched up is
    unspecified.

12
A simple buffer
  • class Buffer
  • String get() async put(String s)
  • return s
  • Does example this involve spawning any threads?
  • No. Though the calls will usually come from
    different pre-existing threads.
  • So is it thread-safe? You dont seem to have
    locked anything
  • Yes. The chord compiles into code which uses
    locks. (And that doesnt mean everything is
    synchronized on the object.)
  • Which method gets the returned result?
  • The synchronous one. And there can be at most one
    of those in a chord.

13
Reader/Writer
  • using threads and mutexes in Modula 3
  • An introduction to programming with threads.
    Andrew D. Birrell, January 1989.

14
Reader/Writer in five chords
  • public class ReaderWriter
  • public void Exclusive() async Idle()
  • public void ReleaseExclusive() Idle()
  • public void Shared() async Idle() S(1)
  • public void Shared() async S(int n) S(n1)
  • public void ReleaseShared() async S(int n)
  • if (n 1) Idle() else S(n-1)
  • public ReaderWriter() Idle()
  • A single private message represents the state
  • none ?? Idle() ?? S(1) ?? S(2) ?? S(3)

15
Asynchronous requests and responses
  • Service exposes an async method which takes
    parameters and somewhere to put the result
  • a buffer, or a channel, or
  • a delegate

public delegate async IntCB(int v) public
class Service public async request(String arg,
IntCB callback) int result // do something
interesting callback(result)
16
Asynchronous requests and responses - Join
  • class Join2
  • void wait(out int i, out int j)
  • async first(int r1)
  • async second(int r2)
  • i r1 j r2 return
  • // client code
  • int i,j
  • Join2 x new Join2()
  • service1.request(arg1, new IntCB(x.first))
  • service2.request(arg2, new IntCB(x.second))
  • // do something useful
  • // now wait until both results have come back
  • x.wait(out i,out j)
  • // do something with i and j

17
Asynchronous requests and responses - Select
  • class Select
  • int wait()
  • async reply(int r)
  • return r
  • // client code
  • int i
  • Select x new Select()
  • service1.request(arg1, new IntCB(x.reply))
  • service2.request(arg2, new IntCB(x.reply))
  • // do something useful
  • // now wait until one result has come back
  • i x.wait()
  • // do something with i

18
Active Objects
public abstract class ActiveObject
MarshalByRefObject protected bool done
abstract protected void processmessage()
public ActiveObject () done false
mainloop() async mainloop() while
(!done) processmessage()
19
continued
class Stock ActiveObject override protected
void processmessage() public async
bid(BidOffer thebid) // process bid
messages override protected void
processmessage() public async register(Client
who) // process registration requests

20
Extending C with chords
  • Classes can declare methods using generalized
    chord-declarations instead of method-declarations
    .

chord-declaration method-header
method-header body method-header
attributes modifiers return-type async name
(parms)
  • Interesting well-formedness conditions
  • At most one header can have a return type (i.e.
    be synchronous).
  • The inheritance restriction.
  • ref and out parameters cannot appear in async
    headers.

21
Why only one synchronous method in a chord?
  • JoCaml allows multiple synchronous methods to be
    joined, as in the following rendezvous
  • But in which thread does the body run? In C,
    thread identity is very observable, since
    threads are the holders of particular re-entrant
    locks. So we rule this out in the interests of
    keeping commutative. (Of course, its still
    easy to code up an asymmetric rendezvous in
    Polyphonic C.)

int f(int x) int g(int y) return y to f
return x to g
22
The problem with inheritance
class C virtual void f() virtual async g()
virtual void f() virtual async h()
class D C override async g()
  • Weve half overridden f
  • Too easy to create deadlock or async leakage

void m(C x) x.g() x.f() m(new D())
23
The inheritance restriction
  • Two methods are co-declared if they appear
    together in a chord declaration.

Whenever a method is overridden,every
co-declared method must also be overridden.
  • Hence, the compiler rejects patterns such as
  • public virtual void f() private async g()
  • In general, inheritance and concurrency do not
    mix well.Our restriction is simple it could be
    made less restrictive.

24
Types etc.
  • async is a subtype of void
  • Allow covariant return types on those two
  • An async method may override a void one
  • A void delegate may be created from an async
    method
  • An async method may implement a void method in an
    interface
  • async methods are given the OneWay attribute,
    so remote calls are non-blocking

25
Implementation
  • Translate Polyphonic C -gt C
  • Built on Proebsting Hansons lcsc
  • Introduce queues for pending calls (holding
    blocked threads for sync methods, arguments for
    asyncs)
  • Generated code (using brief lock to protect queue
    state) looks for matches and then either
  • Enqueues args (async no match)
  • Enqueues thread and blocks (sync no match)
  • Dequeues other args and continues (sync match)
  • Wakes up blocked thread (async match with sync)
  • Spawns new thread (async match all async)
  • Efficient bitmasks to look for matches, no
    PulseAlls,

26
Samples
  • animated dining philosophers
  • web service combinators (Cardelli Davies)
  • adaptive scheduler (cf. Larus Parkes),
  • accessing web services (Terraserver),
  • active objects and remoting (stock trader)

27
Current and future work
  • Direct syntactic support for timeouts
  • Limited pattern-matching on message contents
  • Adding joinable transactions with explicit
    compensations
  • Behavioural types?

28
Conclusions
  • A clean, simple, new model for asynchronous
    concurrency in C
  • Declarative, local synchronization
  • Model good for both local and distributed
    settings
  • Efficiently compiled to queues and automata
  • Easier to express and enforce concurrency
    invariants
  • Compatible with existing constructs, though they
    constrain our design somewhat
  • Minimalist design pieces to build whatever
    complex synchronization behaviours you need
  • Solid foundations
  • Works well in practice

http//research.microsoft.com/nick/polyphony/
29
Fairer reader/writer lock
  • class ReaderWriterFair
  • ReaderWriter() idle()
  • private int n 0 // protected by s() or t()
  • public void Shared() async idle() n1
    s()
  • public void Shared() async s() n s()
  • public void ReleaseShared() async s()
  • if (--n 0) idle() else s()
  • public void Exclusive() async idle()
  • public void ReleaseExclusive() idle()
  • public void ReleaseShared() async t()
  • if (--n 0) idleExclusive() else t()
  • public void Exclusive() async s()
  • t() wait()
  • void wait() async idleExclusive()

30
Predictable Demo Dining Philosophers
waiting to eat
eating
waiting to eat
thinking
eating
31
Code extract
  • class Room
  • public Room (int size) hasspaces(size)
  • public void enter() private async
    hasspaces(int n)
  • if (n gt 1) hasspaces(n-1)
  • else isfull()
  • public void leave() private async
    hasspaces(int n)
  • hasspaces(n1)
  • public void leave() private async isfull()
    hasspaces(1)

32
A Better Syntax?
  • class ReaderWriter
  • private async Idle() // declare
    asyncs
  • private async S(int n)
  • public void Exclusive()
  • when Idle()
  • public void ReleaseExclusive()
  • Idle()
  • public void Shared() // syncs can
    have sequence of
  • when Idle() S(1) // when
    patterns involving
  • when S(int n) S(n1) // asyncs
  • public void ReleaseShared()
  • when S(int n)
  • if (n1) Idle() else S(n-1)

Could even allow when patterns as general
statements, though this seems in dubious taste
33
Santa Claus problem (Trono, Ben-Ari)
  • Santa sleeps until awakened by either all 9
    reindeer or by 3 of the 10 elves.
  • If woken by reindeer he harnesses them all up,
    they deliver presents together, he unharnesses
    them, they go off on holiday and he goes back to
    sleep.
  • If woken by a group of elves, he shows them into
    his office, consults with them on toy RD then
    shows them all out and goes back to sleep.
  • Surprisingly tricky to avoid bugs such as Santa
    going off without the reindeer, queue-jumping
    elves
  • Trono posed problem and gave incorrect solution
    using semaphores
  • Ben-Ari gave a non-trivial solution using Ada
    primitives and ugly, inefficient and
    unsatisfactory solution in Java

34
  • public class nway
  • public async produce(int n) public void
    consume()
  • if (n1)
  • alldone()
  • else
  • produce(n-1)
  • public void waitforalldone() async alldone()
  • return

35
  • class santa
  • static nway harness new nway()
  • static nway unharness new nway()
  • static nway roomin new nway()
  • static nway roomout new nway()
  • static void santalife()
  • while (true)
  • waittobewoken()
  • // get back here when dealt with elves or
    reindeer
  • static void waittobewoken() static async
    elvesready()
  • roomin.produce(3)
  • roomin.waitforalldone()
  • elveswaiting(0)
  • // all elves in the room, consult
  • roomout.produce(3)

36
  • static async elflife(int elfid)
  • while (true)
  • // work
  • elfqueue() // wait to join group of 3
  • roomin.consume() // wait to be shown in
  • // consult with santa
  • roomout.consume() // wait to be shown out
    again
  • static void elfqueue() static async
    elveswaiting(int e)
  • if (e2)
  • elvesready() // last elf in a group so
    wake santa
  • else
  • elveswaiting(e1)

37
Pattern Matching
  • async Sell(string item, Client seller)
  • async Buy (string item, Client buyer)
  • ... // match them up
  • Very useful, but hard to compile efficiently

38
Ordered processing, currently
  • class SequenceProcessor ActiveObject
  • private SortedList pending new
    SortedList()
  • private int next 0
  • public async Message(int stamp, string
    contents)
  • override protected void ProcessMessage()
  • if (stamp next)
  • DealWith(contents)
  • while (pending.ContainsKey(next))
  • DealWith((string)pendingnext)
  • pending.Remove(next)
  • else
  • pending.Add(stamp,contents)
  • ...

39
with matching
  • class SequenceProcessor ActiveObject
  • public async Message(int stamp, string
    contents)
  • override protected void ProcessMessage()
  • async waitingfor(int stamp)
  • DealWith(contents)
  • waitingfor(stamp)
  • SequenceProcessor()
  • waitingfor(0)
  • ...
Write a Comment
User Comments (0)
About PowerShow.com