[pypy-svn] r24187 - in pypy/dist/pypy/objspace: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Thu Mar 9 18:29:39 CET 2006
Author: cfbolz
Date: Thu Mar 9 18:29:28 2006
New Revision: 24187
Modified:
pypy/dist/pypy/objspace/logic.py
pypy/dist/pypy/objspace/test/test_logicobjspace.py
Log:
(pedronis, cfbolz):
slightly insane prototype using greenlets to simulate microthreads which are
scheduled using the logic/dataflow variables. Warning: makes your head explode.
Modified: pypy/dist/pypy/objspace/logic.py
==============================================================================
--- pypy/dist/pypy/objspace/logic.py (original)
+++ pypy/dist/pypy/objspace/logic.py Thu Mar 9 18:29:28 2006
@@ -2,7 +2,33 @@
from pypy.interpreter import gateway, baseobjspace, argument
from pypy.interpreter.error import OperationError
-# __________________________________________________________________________
+USE_GREENLETS = False
+try:
+ from py.magic import greenlet
+except ImportError:
+ USE_GREENLETS = False
+
+if USE_GREENLETS:
+ runnable_uthreads = {}
+ uthreads_blocked_on = {}
+ main_greenlet = greenlet.getcurrent()
+
+ def uthread(space, w_callable, __args__):
+ def run():
+ space.call_args(w_callable, __args__)
+ gr = greenlet(run)
+ current = greenlet.getcurrent()
+ runnable_uthreads[current] = True
+ gr.switch()
+ while runnable_uthreads:
+ next_greenlet, _ = runnable_uthreads.popitem()
+ if next_greenlet and next_greenlet is not current:
+ runnable_uthreads[current] = True
+ next_greenlet.switch()
+ return space.w_None
+ app_uthread = gateway.interp2app(uthread, unwrap_spec=[baseobjspace.ObjSpace,
+ baseobjspace.W_Root,
+ argument.Arguments])
class W_Var(baseobjspace.W_Root, object):
def __init__(w_self):
@@ -19,26 +45,40 @@
return w_curr
def force(space, w_self):
- if not isinstance(w_self, W_Var):
- return w_self
- w_last = find_last_var_in_chain(w_self)
- w_obj = w_last.w_bound_to
- if w_obj is None:
- # XXX here we would have to suspend the current thread
- raise OperationError(space.w_ValueError,
- space.wrap("trying to perform an operation on an unbound variable"))
- else:
- # actually attach the object directly to each variable
- # to remove indirections
- w_curr = w_self
- while 1:
- assert isinstance(w_curr, W_Var)
- w_next = w_curr.w_bound_to
- if not isinstance(w_next, W_Var):
- break
- w_curr.w_bound_to = w_obj
- w_curr = w_next
- return w_obj
+ while 1:
+ if not isinstance(w_self, W_Var):
+ return w_self
+ w_last = find_last_var_in_chain(w_self)
+ w_obj = w_last.w_bound_to
+ if w_obj is None:
+ # XXX here we would have to suspend the current thread
+ if not USE_GREENLETS:
+ raise OperationError(space.w_RuntimeError,
+ space.wrap("trying to perform an operation on an unbound variable"))
+ else:
+ current = greenlet.getcurrent()
+ uthreads_blocked_on.setdefault(w_last, []).append(current)
+ while runnable_uthreads:
+ next_greenlet, _ = runnable_uthreads.popitem()
+ if next_greenlet:
+ next_greenlet.switch()
+ # there is a value here now
+ break
+ else:
+ raise OperationError(space.w_RuntimeError,
+ space.wrap("blocked on variable, but no uthread that can bind it"))
+ else:
+ # actually attach the object directly to each variable
+ # to remove indirections
+ w_curr = w_self
+ while 1:
+ assert isinstance(w_curr, W_Var)
+ w_next = w_curr.w_bound_to
+ if not isinstance(w_next, W_Var):
+ break
+ w_curr.w_bound_to = w_obj
+ w_curr = w_next
+ return w_obj
def newvar(space):
return W_Var()
@@ -74,6 +114,10 @@
w_next = w_curr.w_bound_to
w_curr.w_bound_to = w_obj
w_curr = w_next
+ if USE_GREENLETS:
+ now_unblocked_uthreads = uthreads_blocked_on.pop(w_last, [])
+ for uthread in now_unblocked_uthreads:
+ runnable_uthreads[uthread] = True
return space.w_None
app_bind = gateway.interp2app(bind)
@@ -203,4 +247,22 @@
space.wrap(app_is_unbound))
space.setitem(space.builtin.w_dict, space.wrap('bind'),
space.wrap(app_bind))
+ if USE_GREENLETS:
+ def exitfunc():
+ current = greenlet.getcurrent()
+ while runnable_uthreads:
+ next_greenlet, _ = runnable_uthreads.popitem()
+ if next_greenlet and next_greenlet is not current:
+ runnable_uthreads[current] = True
+ next_greenlet.switch()
+ del runnable_uthreads[current]
+ if uthreads_blocked_on:
+ print "there are still blocked uthreads!"
+ for var, blocked in uthreads_blocked_on.iteritems():
+ print var, blocked
+ assert 0
+ app_exitfunc = gateway.interp2app(exitfunc, unwrap_spec=[])
+ space.setitem(space.sys.w_dict, space.wrap("exitfunc"), space.wrap(app_exitfunc))
+ space.setitem(space.builtin.w_dict, space.wrap('uthread'),
+ space.wrap(app_uthread))
return space
Modified: pypy/dist/pypy/objspace/test/test_logicobjspace.py
==============================================================================
--- pypy/dist/pypy/objspace/test/test_logicobjspace.py (original)
+++ pypy/dist/pypy/objspace/test/test_logicobjspace.py Thu Mar 9 18:29:28 2006
@@ -47,7 +47,7 @@
X = newvar()
def f(x):
return x + 1
- raises(ValueError, f, X)
+ raises(RuntimeError, f, X)
def test_bind_to_self(self):
X = newvar()
More information about the Pypy-commit
mailing list