Archive for June, 2010

The Initial Version of Stackless.py with Select

June 9, 2010

Hi Folks:

Introduction:

Enclosed is a link to the initial copy of Stackless.py with select. This is different from the EventHandler class I presented at the dry run at Montreal Python 13 on April 26th. That version was completely clean roomed from Robert Pike’s Implementation of Newsqueak paper. Although I wrote the implementation, most of the credit has to be given to my friend Kevin Bulušeck for doing a clever Stackless Python mockup that I referenced. I also have to thank Russ Cox for pointing me to the Plan9 implementation at http://swtch.com/usr/local/plan9/src/libthread/channel.c and answering a few questions.

Usage

Select is now a tasklet method.


tasklet.select(list of chanops)
"""returns (channel, operation, value).

channel.receiveCase()
"""returns a receive chanop

channel.sendCase()
"""returns a send chanop

An example:

import stackless

def sender(ch, val):
    ch.send(val)

def receiver(ch):
    val = ch.receive()

def selector(a, b, c):

    print "selector: begin"
    count = 0
    while count < 3:
        ch, operation, value =  stackless.getcurrent().select([a.sendCase("A"), \
                                                       b.receiveCase(), \
                                                       c.sendCase("C")])
        if ch == a:
           print "sender A completed"
        elif ch == b:
           print "received ", value, "from receiver B"
        elif ch == c:
           print "sender C completed"
        else:
           print "should not get here"

        count += 1

    print "selector: end"

if __name__ == '__main__':
    a = stackless.channel("CHANNEL-A")
    b = stackless.channel("CHANNEL-B")
    c = stackless.channel("CHANNEL-C")

    stackless.tasklet(selector, "SELECTOR")(a, b, c)
    stackless.tasklet(receiver, "RECEIVER-A")(a)
    stackless.tasklet(sender,"SENDER-B")(b, "B")
    stackless.tasklet(receiver,"RECEIVER-C")(c)
    stackless.run()

Of course, a hash table can be used in lieu of if statements. Also unlike the Go/Newsqueak version, cases can be dynamically added and removed. I believe the only real limitation is that a channel cannot do both a sendCase and receiveCase at the same time.

Under the hood, the main changes are: 1) there is a new object, chanop (channel operation) 2)channel has two new methods: receiveCase() and sendCase() that return chanops. Chanop is meant to be manipulated by stackless and not the programmer. 3) channel now has a queue of operations rather than tasklets.

I would appreciate it if folks could download the code, play with it and make comments. Remember the code is still rather rough. It would be nice to see how easy/hard it is to implement select in other stackless.py based implementations 🙂 In the meanwhile, I will write tests and clean up the code. I also want to further experiment with implementing join objects a la JoCAML and Polyphonic C#.

Cheers,
Andrew

Advertisements