[pypy-svn] r27026 - pypy/dist/pypy/module/stackless/test
stephan at codespeak.net
stephan at codespeak.net
Wed May 10 10:16:01 CEST 2006
Author: stephan
Date: Wed May 10 10:15:58 2006
New Revision: 27026
Added:
pypy/dist/pypy/module/stackless/test/coro1.py
pypy/dist/pypy/module/stackless/test/stack1.py
pypy/dist/pypy/module/stackless/test/stack2.py (contents, props changed)
pypy/dist/pypy/module/stackless/test/stack3.py (contents, props changed)
pypy/dist/pypy/module/stackless/test/stackless_.py
Log:
proof of concept implementation of stackless on top of coroutine.
Added: pypy/dist/pypy/module/stackless/test/coro1.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/stackless/test/coro1.py Wed May 10 10:15:58 2006
@@ -0,0 +1,28 @@
+from stackless import coroutine
+
+d = {}
+
+def f():
+ print 'in f'
+
+def g(coro,t):
+ print 'in g %s' % t
+ coro.switch()
+
+def main():
+ cm = coroutine.getcurrent()
+ d[cm] = 'main'
+ cf = coroutine()
+ d[cf] = 'f'
+ print 'cf:',cf
+ cf.bind(f)
+ cg = coroutine()
+ d[cg] = 'g'
+ print 'cg:',cg
+ cg.bind(g,cf,'test')
+ cg.switch()
+ print 'back in main'
+ print d
+
+if __name__ == '__main__':
+ main()
Added: pypy/dist/pypy/module/stackless/test/stack1.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/stackless/test/stack1.py Wed May 10 10:15:58 2006
@@ -0,0 +1,18 @@
+from stackless_ import *
+
+def f():
+ print 'in f'
+
+def g(t):
+ print 'in g %s' % t
+ schedule()
+
+def main():
+ cg = tasklet(g)('test')
+ cf = tasklet(f)()
+ schedule()
+ print 'in main'
+
+if __name__ == '__main__':
+ main()
+
Added: pypy/dist/pypy/module/stackless/test/stack2.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/stackless/test/stack2.py Wed May 10 10:15:58 2006
@@ -0,0 +1,20 @@
+from stackless_ import *
+
+def f(outchan):
+ for i in range(10):
+ print 'f send',i
+ outchan.send(i)
+ outchan.send(-1)
+
+def g(inchan):
+ while 1:
+ val = inchan.receive()
+ if val == -1:
+ break
+ print 'g received',val
+
+ch = channel()
+t1 = tasklet(f)(ch)
+t2 = tasklet(g)(ch)
+
+t1.run()
Added: pypy/dist/pypy/module/stackless/test/stack3.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/stackless/test/stack3.py Wed May 10 10:15:58 2006
@@ -0,0 +1,43 @@
+def receiver(chan, name):
+ while 1:
+ try:
+ data = chan.receive()
+ except:
+ print name, "** Ouch!!! **"
+ raise
+ print name, "got:", data
+ if data == 42:
+ chan.send("%s says bye" % name)
+ return
+
+import sys
+import stackless
+if hasattr(stackless,'coroutine'):
+ import stackless_ as stackless
+
+chan = stackless.channel()
+t1 = stackless.tasklet(receiver)(chan, "inky")
+t2 = stackless.tasklet(receiver)(chan, "dinky")
+stackless.run()
+try:
+ for i in 2,3,5,7, 42:
+ print "sending", i
+ chan.send(i)
+ chan.send(i)
+ #if i==7:
+ # print "sending Exception"
+ # chan.send_exception(ValueError, i)
+except ValueError:
+ e, v, t = sys.exc_info()
+ print e, v
+ del e, v, t
+print "main done."
+#
+# trying to clean up things, until we have a real
+# channel deallocator:
+print "trying cleanup:"
+while chan.balance:
+ if chan.balance < 0:
+ chan.send(42)
+ else:
+ print chan.receive()
Added: pypy/dist/pypy/module/stackless/test/stackless_.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/stackless/test/stackless_.py Wed May 10 10:15:58 2006
@@ -0,0 +1,148 @@
+from stackless import coroutine
+
+__all__ = 'run getcurrent getmain schedule tasklet channel'.split()
+
+main_tasklet = None
+next_tasklet = None
+scheduler = None
+
+coro_reg = {}
+
+def __init():
+ global maintasklet
+ mt = tasklet()
+ mt._coro = c = coroutine.getcurrent()
+ maintasklet = mt
+ coro_reg[c] = mt
+
+def run():
+ schedule()
+
+def getcurrent():
+ c = coroutine.getcurrent()
+ return coro_reg[c]
+
+def getmain():
+ return main_tasklet
+
+def schedule():
+ scheduler.schedule()
+
+class tasklet(object):
+ def __init__(self,func=None):
+ self._func = func
+
+ def __call__(self,*argl,**argd):
+ self._coro = c = coroutine()
+ c.bind(self._func,*argl,**argd)
+ coro_reg[c] = self
+ self.insert()
+ return self
+
+ def awake(self):pass
+
+ def sleep(self):pass
+
+ def run(self):
+ scheduler.setnexttask(self)
+ schedule()
+
+ def insert(self):
+ scheduler.insert(self)
+
+ def remove(self):
+ scheduler.remove(self)
+
+ def kill(self):pass
+
+class channel(object):
+ def __init__(self):
+ self.balance = 0
+ self._readq = []
+ self._writeq = []
+
+ def send(self, msg):
+ ct = getcurrent()
+ scheduler.remove(ct)
+ self._writeq.append((ct,msg))
+ self.balance += 1
+ if self._readq:
+ nt, self._readq = self._readq[0], self._readq[1:]
+ scheduler.priorityinsert(nt)
+ schedule()
+
+ def receive(self):
+ ct = getcurrent()
+ if self._writeq:
+ (wt,retval), self._writeq = self._writeq[0], self._writeq[1:]
+ scheduler.priorityinsert(wt)
+ self.balance -= 1
+ return retval
+ else:
+ self._readq.append(ct)
+ scheduler.remove(ct)
+ schedule()
+ return self.receive()
+
+class Scheduler(object):
+ def __init__(self):
+ self.tasklist = []
+ self.nexttask = None
+
+ def empty(self):
+ return not self.tasklist
+
+ def __str__(self):
+ return repr(self.tasklist) + '/%s' % self.nexttask
+
+ def insert(self,task):
+ if (task not in self.tasklist) and task is not maintasklet:
+ self.tasklist.append(task)
+ if self.nexttask is None:
+ self.nexttask = 0
+
+ def priorityinsert(self,task):
+ if task in self.tasklist:
+ self.tasklist.remove(task)
+ if task is maintasklet:
+ return
+ if self.nexttask:
+ self.tasklist.insert(self.nexttask,task)
+ else:
+ self.tasklist.insert(0,task)
+ self.nexttask = 0
+
+ def remove(self,task):
+ try:
+ i = self.tasklist.index(task)
+ del(self.tasklist[i])
+ if self.nexttask > i:
+ self.nexttask -= 1
+ if len(self.tasklist) == 0:
+ self.nexttask = None
+ except ValueError:pass
+
+ def next(self):
+ if self.nexttask is not None:
+ task = self.tasklist[self.nexttask]
+ self.nexttask += 1
+ if self.nexttask == len(self.tasklist):
+ self.nexttask = 0
+ return task
+ else:
+ return maintasklet
+
+ def setnexttask(self,task):
+ if task not in self.tasklist:
+ self.tasklist.insert(task)
+ try:
+ i = self.tasklist.index(task)
+ self.nexttask = i
+ except IndexError:pass
+
+ def schedule(self):
+ n = self.next()
+ n._coro.switch()
+
+scheduler = Scheduler()
+__init()
More information about the Pypy-commit
mailing list