[pypy-svn] r27178 - pypy/dist/pypy/module/stackless/test
tismer at codespeak.net
tismer at codespeak.net
Sat May 13 16:42:31 CEST 2006
Author: tismer
Date: Sat May 13 16:42:30 2006
New Revision: 27178
Modified:
pypy/dist/pypy/module/stackless/test/stackless_.py
Log:
some hints, comments and clarifications about how to implement stackless and what to ignore
Modified: pypy/dist/pypy/module/stackless/test/stackless_.py
==============================================================================
--- pypy/dist/pypy/module/stackless/test/stackless_.py (original)
+++ pypy/dist/pypy/module/stackless/test/stackless_.py Sat May 13 16:42:30 2006
@@ -11,7 +11,14 @@
# interface from original stackless
# class attributes are placeholders for some kind of descriptor
# (to be filled in later).
-
+
+note = """
+The bomb object decouples exception creation and exception
+raising. This is necessary to support channels which don't
+immediately react on messages.
+
+This is a necessary Stackless 3.1 feature.
+"""
class bomb(object):
"""
A bomb object is used to hold exceptions in tasklets.
@@ -34,14 +41,24 @@
traceback = None
type = None
value = None
-
+
+note = """
+cframes are an implementation detail.
+Do not implement this now. If we need such a thing in PyPy,
+then it will probably have a different layout.
+"""
class cframe(object):
"""
"""
__slots__ = ['f_back','obj1','obj2','obj3','i','n']
# channel: see below
-
+
+note = """
+The future of C stacks is undecided, yet. This applies
+for Stackless, only at the moment. PyPy will use soft-switching
+only, until we support external callbacks.
+"""
class cstack(object):
"""
A CStack object serves to save the stack slice which is involved
@@ -49,7 +66,11 @@
of program state. This structure is highly platform dependant.
Note: For inspection, str() can dump it as a string.
"""
-
+
+note = """
+I would implement it as a simple flag but let it issue
+a warning that it has no effect.
+"""
def enable_softswitch(flag):
"""
enable_softswitch(flag) -- control the switching behavior.
@@ -62,7 +83,10 @@
By default, soft switching is enabled.
"""
pass
-
+
+note = """
+Implementation can be deferred.
+"""
def get_thread_info(thread_id):
"""
get_thread_info(thread_id) -- return a 3-tuple of the thread's
@@ -78,7 +102,8 @@
# def run(timeout): see below
# def schedule(retval=stackless.current) : see below
-
+
+note = 'needed'
def schedule_remove(retval=None):
"""
schedule(retval=stackless.current) -- switch to the next runnable tasklet.
@@ -87,7 +112,10 @@
schedule_remove(retval=stackless.current) -- ditto, and remove self.
"""
pass
-
+
+note = """
+should be implemented for debugging purposes. Low priority
+"""
def set_channel_callback(callable):
"""
set_channel_callback(callable) -- install a callback for channels.
@@ -100,6 +128,9 @@
"""
pass
+note = """
+should be implemented for debugging purposes. Low priority
+"""
def set_schedule_callback(callable):
"""
set_schedule_callback(callable) -- install a callback for scheduling.
@@ -112,7 +143,13 @@
Pass None to switch monitoring off again.
"""
pass
-
+
+note = """
+this was an experiment on deriving from a module.
+The idea was to make runcount and current into properties.
+__tasklet__ and __channel__ are also not used.
+It is ok to ignore these.
+"""
class slpmodule(object):
"""
The stackless module has a special type derived from
@@ -124,7 +161,8 @@
"""
# class tasklet: see below
-
+
+note = 'drop'
def test_cframe(switches, words=0):
"""
test_cframe(switches, words=0) -- a builtin testing function that does
@@ -140,6 +178,7 @@
"""
pass
+note = 'drop'
def test_cframe_nr(switches):
"""
test_cframe_nr(switches) -- a builtin testing function that does nothing
@@ -149,6 +188,7 @@
"""
pass
+note = 'drop'
def test_outside():
"""
test_outside() -- a builtin testing function.
@@ -182,6 +222,12 @@
maintasklet = mt
coro_reg[c] = mt
+note = """
+It is not needed to implement the watchdog feature right now.
+But run should be supported in the way the docstring says.
+The runner is always main, which must be removed while
+running all the tasklets. The implementation below is wrong.
+"""
def run():
"""
run_watchdog(timeout) -- run tasklets until they are all
@@ -194,7 +240,13 @@
If an exception occours, it will be passed to the main tasklet.
"""
schedule()
-
+
+note = """
+I don't see why coro_reg is needed.
+tasklets should ideally inherit from coroutine.
+This will create unwanted attributes, but they will
+go away when we port this to interp-leve.
+"""
def getcurrent():
"""
getcurrent() -- return the currently executing tasklet.
@@ -225,18 +277,25 @@
# __slots__ = ['alive','atomic','block_trap','blocked','frame',
# 'ignore_nesting','is_current','is_main',
# 'nesting_level','next','paused','prev','recursion_depth',
-# 'restorable','scheduled','thread_id']
+# 'restorable','scheduled','thread_id']
+
+## note: most of the above should be properties
- def __init__(self,func=None):
+ def __init__(self, func=None):
+ ## note: this field should reuse tempval to save space
self._func = func
- def __call__(self,*argl,**argd):
+ def __call__(self, *argl, **argd):
+ ## note: please inherit
+ ## note: please use spaces after comma :-)
+ ## note: please express this using bind and setup
self._coro = c = coroutine()
c.bind(self._func,*argl,**argd)
coro_reg[c] = self
self.insert()
return self
-
+
+ ## note: deprecated
def become(self, retval=None):
"""
t.become(retval) -- catch the current running frame in a tasklet.
@@ -247,7 +306,8 @@
If retval is not given, the tasklet is used as default.
"""
pass
-
+
+ ## note: __init__ should use this
def bind(self):
"""
Binding a tasklet to a callable object.
@@ -258,6 +318,7 @@
"""
pass
+ ## note: deprecated
def capture(self, retval=None):
"""
t.capture(retval) -- capture the current running frame in a tasklet,
@@ -266,6 +327,7 @@
"""
pass
+ ## note: this is not part of the interface, please drop it
cstate = None
def insert(self):
@@ -275,7 +337,8 @@
Blocked tasklets need to be reactivated by channels.
"""
scheduler.insert(self)
-
+
+ ## note: this is needed. please call coroutine.kill()
def kill(self):
"""
tasklet.kill -- raise a TaskletExit exception for the tasklet.
@@ -285,7 +348,8 @@
the tasklet will silently die.
"""
pass
-
+
+ ## note: see the C implementation about how to use bombs
def raise_exception(self, exc, value):
"""
tasklet.raise_exception(exc, value) -- raise an exception for the
@@ -310,9 +374,13 @@
Run this tasklet, given that it isn't blocked.
Blocked tasks need to be reactivated by channels.
"""
- scheduler.setnexttask(self)
+ scheduler.setnexttask(self)
+ ## note: please support different schedulers
+ ## and don't mix calls to module functions with scheduler methods.
schedule()
-
+
+ ## note: needed at some point. right now just a property
+ ## the stackless_flags should all be supported
def set_atomic(self):
"""
t.set_atomic(flag) -- set tasklet atomic status and return current one.
@@ -329,7 +397,8 @@
See set_ignore_nesting.
"""
pass
-
+
+ ## note: see above
def set_ignore_nesting(self,flag):
"""
t.set_ignore_nesting(flag) -- set tasklet ignore_nesting status and
@@ -343,13 +412,19 @@
t.set_ignore_nesting(tmp)
"""
pass
-
+
+ ## note
+ ## tasklet(func)(*args, **kwds)
+ ## is identical to
+ ## t = tasklet; t.bind(func); t.setup(*args, **kwds)
def setup(self,*argl,**argd):
"""
supply the parameters for the callable
"""
pass
-
+
+ ## note: this attribute should always be there.
+ ## no class default needed.
tempval = None
class channel(object):
@@ -365,10 +440,12 @@
# 'schedule_all']
def __init__(self):
- self.balance = 0
+ self.balance = 0
+ ## note: this is a deque candidate.
self._readq = []
self._writeq = []
-
+
+ ## note: needed
def close(self):
"""
channel.close() -- stops the channel from enlarging its queue.
@@ -378,12 +455,14 @@
"""
pass
+ ## note: needed. iteration over a channel reads it all.
def next(self):
"""
x.next() -> the next value, or raise StopIteration
"""
pass
+ ## note: needed
def open(self):
"""
channel.open() -- reopen a channel. See channel.close.
@@ -426,7 +505,8 @@
nt, self._readq = self._readq[0], self._readq[1:]
scheduler.priorityinsert(nt)
schedule()
-
+
+ ## note: see the C implementation on how to use bombs.
def send_exception(self, exc, value):
"""
channel.send_exception(exc, value) -- send an exception over the
@@ -434,7 +514,8 @@
Behavior is like channel.send, but that the receiver gets an exception.
"""
pass
-
+
+ ## needed
def send_sequence(self, value):
"""
channel.send(value) -- send a value over the channel.
@@ -447,8 +528,10 @@
class Scheduler(object):
- def __init__(self):
- self.tasklist = []
+ def __init__(self):
+ ## note: better use a deque
+ self.tasklist = []
+ ## note: in terms of moving to interplevel, I would not do that
self.nexttask = None
def empty(self):
@@ -508,3 +591,6 @@
scheduler = Scheduler()
__init()
+
+## note: nice work :-)
+
More information about the Pypy-commit
mailing list