[pypy-svn] r28781 - pypy/dist/pypy/lib

stephan at codespeak.net stephan at codespeak.net
Wed Jun 14 18:29:07 CEST 2006


Author: stephan
Date: Wed Jun 14 18:29:05 2006
New Revision: 28781

Modified:
   pypy/dist/pypy/lib/stackless.py
Log:
removed exessive comments and DEBUG code.


Modified: pypy/dist/pypy/lib/stackless.py
==============================================================================
--- pypy/dist/pypy/lib/stackless.py	(original)
+++ pypy/dist/pypy/lib/stackless.py	Wed Jun 14 18:29:05 2006
@@ -6,90 +6,40 @@
 
 import sys
 
-DEBUG = True
-DEBUG = False
-
 switches = 0
 
-def ASSERT_Q(task):
-    try:
-        if task is not None:
-            assert isinstance(task,(tasklet,TaskletProxy))
-            if task.next is not None:
-                assert isinstance(task.next,(tasklet, TaskletProxy, Scheduler))
-            if task.prev is not None:
-                assert isinstance(task.prev,(tasklet, TaskletProxy, Scheduler))
-    except AssertionError:
-        if DEBUG:
-            print 'task to insert as _head is wrong'
-            print task
-        raise
-
 from _stackless import coroutine, greenlet
 
 __all__ = 'run getcurrent getmain schedule tasklet \
                 channel TaskletExit coroutine greenlet'.split()
 
-class TaskletExit(Exception):pass
-
-# 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.
+main_tasklet = main_coroutine = None
+scheduler = None
+channel_hook = None
+schedlock = False
+_schedule_fasthook = None
+_schedule_hook = None
 
-This is a necessary Stackless 3.1 feature.
-"""
+class TaskletExit(Exception):pass
 
 def SETNEXT(obj, val):
-    if DEBUG:
-        print 'SETNEXT', obj, val
     obj.next = val
 
 def SETPREV(obj, val):
-    if DEBUG:
-        print 'SETPREV', obj, val
     obj.prev = val
 
 def SETNONE(obj):
-    if DEBUG:
-        print 'SETNONE'
     obj.prev = obj.next = None
 
 def SWAPVAL(task1, task2):
-    try:
-        assert task1 is not None
-        assert task2 is not None
-    except:
-        print 'AssertionError in SWAPVAL', task1, task2
-        raise
-    if DEBUG:
-        print 'SWAPVAL(%s, %s)' % (task1, task2)
-        print '\t', task1.tempval
-        print '\t', task2.tempval
+    assert task1 is not None
+    assert task2 is not None
     task1.tempval, task2.tempval = task2.tempval, task1.tempval
 
 def SETVAL(task, val):
-    try:
-        assert task is not None
-    except:
-        print 'AssertionError in SETVAL'
-        raise
-    if isinstance(val, bomb):
-        print val.type, val.value
-    if DEBUG:
-        print 'SETVAL(%s, %s)' % (task, val)
+    assert task is not None
     task.tempval = val
 
-# thread related stuff: assuming NON threaded execution for now
-
-def check_for_deadlock():
-    return True
-    #return False
-
 last_thread_id = 0
 
 def restore_exception(etype, value, stack):
@@ -143,6 +93,7 @@
     traceback = None
     type = None
     value = None
+
     def __init__(self,etype=None, value=None, traceback=None):
         self.type = etype
         self.value = value
@@ -158,15 +109,8 @@
 
 def curexc_to_bomb():
     import sys
-    # XXX note that you should clear the exception
     return bomb(*sys.exc_info())
 
-# channel: see below
-
-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.
@@ -180,9 +124,6 @@
     """
     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
@@ -193,12 +134,6 @@
     """
     pass
 
-# def getcurrent() : see below
-
-# def run(timeout): see below
-
-# def schedule(retval=stackless.current) : see below
-
 def schedule_remove(retval=None):
     """
     schedule(retval=stackless.current) -- switch to the next runnable tasklet.
@@ -208,9 +143,6 @@
     """
     pass
 
-note = """
-should be implemented for debugging purposes. Low priority
-"""
 def set_channel_callback(callable):
     """
     set_channel_callback(callable) -- install a callback for channels.
@@ -226,13 +158,9 @@
     channel_hook = callable
 
 def _schedule_callback(prev, next):
-    # lot's of error checking missing
     global _schedule_hook
     return _schedule_hook(prev, next)
 
-note = """
-should be implemented for debugging purposes. Low priority
-"""
 def set_schedule_callback(func):
     """
     set_schedule_callback(callable) -- install a callback for scheduling.
@@ -257,35 +185,6 @@
     else:
         _schedule_fasthook = _schedule_callback
 
-# class tasklet: see below
-
-# end interface
-
-main_tasklet = None
-main_coroutine = None
-scheduler = None
-channel_hook = None
-schedlock = False
-_schedule_fasthook = None
-_schedule_hook = None
-
-def __init():
-    global main_tasklet
-    global main_coroutine
-    global scheduler 
-    main_coroutine = c = coroutine.getcurrent()
-    main_tasklet = TaskletProxy(c)
-    SETNEXT(main_tasklet, main_tasklet)
-    SETPREV(main_tasklet, main_tasklet)
-    main_tasklet.is_main = True
-    scheduler = Scheduler()
-
-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(timeout=0):
     """
     run_watchdog(timeout) -- run tasklets until they are all
@@ -297,20 +196,14 @@
     tasklet that caused a timeout, if any.
     If an exception occours, it will be passed to the main tasklet.
     """
-    if DEBUG:
-        print 'stackless.run()'
     me = scheduler.current_remove()
     if me is not main_tasklet:
         raise RuntimeError("run() must be run from the main thread's \
                              main tasklet")
     try:
         retval = scheduler.schedule_task(me, scheduler._head)
-        if DEBUG:
-            print 'run: returning to main'
-        #scheduler.current_insert(me)
         return retval
     except Exception, exp:
-        print 'run: in Excpetion', exp
         b = curexc_to_bomb()
         SETVAL(me, b)
         scheduler.current_insert(me)
@@ -341,56 +234,6 @@
     prev = scheduler._head
     next = prev.next
     return scheduler.schedule_task(prev, next)
-"""
-/***************************************************************************
-
-    Tasklet Flag Definition
-    -----------------------
-
-    blocked:        The tasklet is either waiting in a channel for
-                    writing (1) or reading (-1) or not blocked (0).
-                    Maintained by the channel logic. Do not change.
-
-    atomic:         If true, schedulers will never switch. Driven by
-                    the code object or dynamically, see below.
-
-    ignore_nesting: Allows auto-scheduling, even if nesting_level
-                    is not zero.
-
-    autoschedule:   The tasklet likes to be auto-scheduled. User driven.
-
-    block_trap:     Debugging aid. Whenever the tasklet would be
-                    blocked by a channel, an exception is raised.
-
-    is_zombie:      This tasklet is almost dead, its deallocation has
-                    started. The tasklet *must* die at some time, or the
-                    process can never end.
-
-    pending_irq:    If set, an interrupt was issued during an atomic
-                    operation, and should be handled when possible.
-
-
-    Policy for atomic/autoschedule and switching:
-    ---------------------------------------------
-    A tasklet switch can always be done explicitly by calling schedule().
-    Atomic and schedule are concerned with automatic features.
-
-    atomic  autoschedule
-
-        1       any     Neither a scheduler nor a watchdog will
-                        try to switch this tasklet.
-
-        0       0       The tasklet can be stopped on desire, or it
-                        can be killed by an exception.
-
-        0       1       Like above, plus auto-scheduling is enabled.
-
-    Default settings:
-    -----------------
-    All flags are zero by default.
-
- ***************************************************************************/
-"""
 
 class tasklet(coroutine):
     """
@@ -404,16 +247,6 @@
                  'nesting_level','next','paused','prev','recursion_depth',
                  'restorable','scheduled','tempval','thread_id']
 
-    ## note: most of the above should be properties
-
-    ## note that next and prev are not here.
-    ## should this be implemented, or better not?
-    ## I think yes. it is easier to keep the linkage.
-    ## tasklets gave grown this, and we can do different
-    ## classes, later.
-    ## well, it is a design question, but fow now probably simplest
-    ## to just copy that.
-
     def __new__(cls, func=None):
         return super(tasklet,cls).__new__(cls)
 
@@ -440,10 +273,6 @@
         if func is not None:
             self.bind(func)
 
-    def __del__(self):
-        if DEBUG:
-            print 'in __del__', self
-
     def __call__(self, *argl, **argd):
         self.setup(*argl, **argd)
         return self
@@ -474,7 +303,6 @@
         SETVAL(self, func)
 
     def _is_dead(self):
-        # XXX missing
         return self.is_zombie
 
     def insert(self):
@@ -490,7 +318,6 @@
         if self.next is None:
             scheduler.current_insert(self)
 
-    ## note: this is needed. please call coroutine.kill()
     def kill(self):
         """
         tasklet.kill -- raise a TaskletExit exception for the tasklet.
@@ -503,7 +330,6 @@
             coroutine.kill(self)
         return self.raise_excption(TaskletExit)
 
-    ## 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 
@@ -530,12 +356,8 @@
         Run this tasklet, given that it isn't blocked.
         Blocked tasks need to be reactivated by channels.
         """
-        ## note: please support different schedulers
-        ## and don't mix calls to module functions with scheduler methods.
         scheduler.schedule_task(getcurrent(), self)
 
-    ## note: needed at some point. right now just a property
-    ## the stackless_flags should all be supported
     def set_atomic(self, val):
         """
         t.set_atomic(flag) -- set tasklet atomic status and return current one.
@@ -555,7 +377,6 @@
         self.atomic = val
         return tmpval
 
-    ## note: see above
     def set_ignore_nesting(self, flag):
         """
         t.set_ignore_nesting(flag) -- set tasklet ignore_nesting status and 
@@ -572,11 +393,6 @@
         self.ignore_nesting = flag
         return tmpval
 
-    ## note
-    ## tasklet(func)(*args, **kwds)
-    ## is identical to
-    ## t = tasklet; t.bind(func); t.setup(*args, **kwds)
-
     def finished(self):
         self.alive = False
         if self.next is not self:
@@ -586,9 +402,6 @@
         scheduler.remove_task(self)
         scheduler.schedule_task(self, next)
 
-        if DEBUG:
-            print 'in finished', self
-
     def setup(self, *argl, **argd):
         """
         supply the parameters for the callable
@@ -599,31 +412,6 @@
         SETVAL(self, None)
         self.alive = True
         self.insert()
-"""
-/***************************************************************************
-
-    Channel Flag Definition
-    -----------------------
-
-
-    closing:        When the closing flag is set, the channel does not
-                    accept to be extended. The computed attribute
-                    'closed' is true when closing is set and the
-                    channel is empty.
-
-    preference:     0    no preference, caller will continue
-                    1    sender will be inserted after receiver and run
-                    -1   receiver will be inserted after sender and run
-
-    schedule_all:   ignore preference and always schedule the next task
-
-    Default settings:
-    -----------------
-    All flags are zero by default.
-
- ***************************************************************************/
-"""
-
 
 def channel_callback(chan, task, sending, willblock):
     return channel_hook(chan, task, sending, willblock)
@@ -637,9 +425,6 @@
     is resumed. If there is no waiting sender, the receiver is suspended.
     """
 
-#    __slots__ = ['balance','closed','closing','preference','queue',
-#                 'schedule_all']
-
     def __init__(self):
         self.balance = 0
         self.closing = False
@@ -681,11 +466,7 @@
 
     def _channel_remove(self, d):
         ret = self.next
-        try:
-            assert isinstance(ret, (tasklet, TaskletProxy))
-        except:
-            print 'AssertionError in channel_remove'
-            raise
+        assert isinstance(ret, (tasklet, TaskletProxy))
         self.balance -= d
         self._rem(ret)
         ret.blocked = 0
@@ -701,8 +482,6 @@
         return task
 
     def _ins(self, task):
-        if DEBUG:
-            print '### channel._ins(%s)' % task
         if (task.next is not None) or (task.prev is not None):
             raise AssertionError('task.next and task.prev must be None')
         # insert at end
@@ -712,14 +491,8 @@
         SETPREV(self, task)
 
     def _rem(self, task):
-        if DEBUG:
-            print '### channel._rem(%s)' % task
-        try:
-            assert task.next is not None
-            assert task.prev is not None
-        except:
-            print 'AssertionError in channel._rem', task, task.next, task.prev
-            raise
+        assert task.next is not None
+        assert task.prev is not None
         #remove at end
         SETPREV(task.next, task.prev)
         SETNEXT(task.prev, task.next)
@@ -736,88 +509,50 @@
             schedlock = 0
 
     def _channel_action(self, arg, d, stackl):
-        try:
-            #source = getcurrent()
-            source = scheduler._head
-            target = self.next
-            if not source is getcurrent():
-                print '!!!!! scheduler._head is not current !!!!!', source, getcurrent()
-            interthread = 0 # no interthreading at the moment
-            if d > 0:
-                cando = self.balance < 0
-            else:
-                cando = self.balance > 0
+        source = scheduler._head
+        target = self.next
+        assert source is getcurrent()
+        interthread = 0 # no interthreading at the moment
+        if d > 0:
+            cando = self.balance < 0
+        else:
+            cando = self.balance > 0
 
-            if DEBUG:
-                print
-                print self
-                print '_channel_action(%s, %s)' % (arg, d)
-                print '_channel_action -> source:', source
-                print '_channel_action -> target:', target
-                print '--- cando --- :',cando
-                print scheduler
-                print
-                print
-            try:
-                assert abs(d) == 1
-            except:
-                print 'AssertionError in channel_action'
-                raise
-
-            SETVAL(source, arg)
-            if not interthread:
-                self._notify(source, d, cando, None)
-            if cando:
-                # communication 1): there is somebody waiting
-                target = self._channel_remove(-d)
-                SWAPVAL(source, target)
-                if interthread:
-                    raise Exception('no interthreading: I can not be reached...')
-                else:
-                    if self.schedule_all:
-                        if DEBUG:
-                            print '--- in if ---'
-                        scheduler.current_insert(target)
-                        target = source.next
-                    elif self.preference == -d:
-                        if DEBUG:
-                            print '--- in elif ---'
-                        scheduler._set_head(source.next)
-                        scheduler.current_insert(target)
-                        scheduler._set_head(source)
-                        #schedule._head = target
-                    else:
-                        if DEBUG:
-                            print '--- else ---'
-                        scheduler.current_insert(target)
-                        target = source
+        assert abs(d) == 1
+        SETVAL(source, arg)
+        if not interthread:
+            self._notify(source, d, cando, None)
+        if cando:
+            # communication 1): there is somebody waiting
+            target = self._channel_remove(-d)
+            SWAPVAL(source, target)
+            if interthread:
+                raise Exception('no interthreading: I can not be reached...')
             else:
-                # communication 2): there is nobody waiting
-                if source.block_trap:
-                    raise RuntimeError("this tasklet does not like to be blocked")
-                if self.closing:
-                    raise StopIteration()
-                scheduler.current_remove()
-                self._channel_insert(source, d)
-                target = scheduler._head
-        except Exception, exp:
-            if DEBUG:
-                print 'Exception in channel_action', exp, '\n\n'
-            raise
-        try:
-            if DEBUG:
-                print 'BEFORE SWITCH:',self
-            retval = scheduler.schedule_task(source, target)
-        except Exception, exp:
-            print 'schedule_task raised', exp
-            print sys.exc_info()
-            print retval
-            raise
+                if self.schedule_all:
+                    scheduler.current_insert(target)
+                    target = source.next
+                elif self.preference == -d:
+                    scheduler._set_head(source.next)
+                    scheduler.current_insert(target)
+                    scheduler._set_head(source)
+                else:
+                    scheduler.current_insert(target)
+                    target = source
+        else:
+            # communication 2): there is nobody waiting
+            if source.block_trap:
+                raise RuntimeError("this tasklet does not like to be blocked")
+            if self.closing:
+                raise StopIteration()
+            scheduler.current_remove()
+            self._channel_insert(source, d)
+            target = scheduler._head
+        retval = scheduler.schedule_task(source, target)
         if interthread:
             self._notify(source, d, cando, None)
         return retval
 
-    ## note: needed
     def close(self):
         """
         channel.close() -- stops the channel from enlarging its queue.
@@ -827,7 +562,6 @@
         """
         self.closing = True
 
-    ## note: needed. iteration over a channel reads it all.
     def next(self):
         """
         x.next() -> the next value, or raise StopIteration
@@ -836,52 +570,12 @@
             raise StopIteration()
         yield self.receive()
 
-    ## note: needed
     def open(self):
         """
         channel.open() -- reopen a channel. See channel.close.
         """
         self.closing = False
 
-    """
-    /**********************************************************
-
-      The central functions of the channel concept.
-      A tasklet can either send or receive on a channel.
-      A channel has a queue of waiting tasklets.
-      They are either all waiting to send or all
-      waiting to receive.
-      Initially, a channel is in a neutral state.
-      The queue is empty, there is no way to
-      send or receive without becoming blocked.
-
-      Sending 1):
-        A tasklet wants to send and there is
-        a queued receiving tasklet. The sender puts
-        its data into the receiver, unblocks it,
-        and inserts it at the top of the runnables.
-        The receiver is scheduled.
-      Sending 2):
-        A tasklet wants to send and there is
-        no queued receiving tasklet.
-        The sender will become blocked and inserted
-        into the queue. The next receiver will
-        handle the rest through "Receiving 1)".
-      Receiving 1):
-        A tasklet wants to receive and there is
-        a queued sending tasklet. The receiver takes
-        its data from the sender, unblocks it,
-        and inserts it at the end of the runnables.
-        The receiver continues with no switch.
-      Receiving 2):
-        A tasklet wants to receive and there is
-        no queued sending tasklet.
-        The receiver will become blocked and inserted
-        into the queue. The next sender will
-        handle the rest through "Sending 1)".
-     */
-    """
-
     def receive(self):
         """
         channel.receive() -- receive a value over the channel.
@@ -903,7 +597,6 @@
         """
         return self._channel_action(msg, 1, 1)
 
-    ## 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 
@@ -913,7 +606,6 @@
         b = bomb(exc, value)
         self.send(bomb)
 
-    ## needed
     def send_sequence(self, value):
         """
         channel.send_sequence(seq) -- sed a stream of values
@@ -957,12 +649,8 @@
         return 'Scheduler: [' + ' -> '.join(parts) + ']'
 
     def _chain_insert(self, task):
-        try:
-            assert task.next is None
-            assert task.prev is None
-        except:
-            print 'AssertionError in _chain_insert', task, task.prev, task.next
-            raise
+        assert task.next is None
+        assert task.prev is None
         if self._head is None:
             SETNEXT(task, task)
             SETPREV(task, task)
@@ -1012,11 +700,7 @@
         while not isinstance(prev, channel):
             prev = prev.prev
         chan = prev
-        try:
-            assert chan.balance
-        except:
-            print 'AssertionError in channel_remove_slow'
-            raise
+        assert chan.balance
         if chan.balance > 0:
             d = 1
         else:
@@ -1041,74 +725,41 @@
                 return errflag
 
     def schedule_task_block(self, prev):
-        if DEBUG:
-            print 'schedule_task_block(%s)' % prev
-        next = None
-        if check_for_deadlock():
-            try:
-                if main_tasklet.next is None:
-                    if isinstance(prev.tempval, bomb):
-                        SETVAL(main_tasklet, prev.tempval)
-                    return self.schedule_task(prev, main_tasklet)
-                retval = make_deadlock_bomb()
-                SETVAL(prev, retval)
-
-                return self.schedule_task(prev, prev)
-            except Exception, exp:
-                print 'exp in schedule_task_block', exp
-                raise
+        if main_tasklet.next is None:
+            if isinstance(prev.tempval, bomb):
+                SETVAL(main_tasklet, prev.tempval)
+            return self.schedule_task(prev, main_tasklet)
+        retval = make_deadlock_bomb()
+        SETVAL(prev, retval)
 
-
-        next = prev
-        return self.schedule_task(prev, next)
+        return self.schedule_task(prev, prev)
 
     def schedule_task(self, prev, next):
-        try:
-            global switches
-            switches += 1
-            myswitch = switches
-            if DEBUG:
-                print '\n\n!!! schedule_task(%s)' % myswitch, prev, next
-                print
-            if next is None:
-                return self.schedule_task_block(prev)
-            if next.blocked:
-                self.channel_remove_slow(next)
-                self.current_insert(next)
-            elif next.next is None:
-                self.current_insert(next)
-            if prev is next:
-                retval = prev.tempval
-                if isinstance(retval, bomb):
-                    self.bomb_explode(prev)
-                return retval
-            self._notify_schedule(prev, next, None)
-            #assert next is self._head
-            self._set_head(next)
-        except Exception, exp:
-            print '### Exception BEFORE switch', exp
-            raise
-
-        # lots of soft-/ hard switching stuff in C source
+        global switches
+        switches += 1
+        myswitch = switches
+        if next is None:
+            return self.schedule_task_block(prev)
+        if next.blocked:
+            self.channel_remove_slow(next)
+            self.current_insert(next)
+        elif next.next is None:
+            self.current_insert(next)
+        if prev is next:
+            retval = prev.tempval
+            if isinstance(retval, bomb):
+                self.bomb_explode(prev)
+            return retval
+        self._notify_schedule(prev, next, None)
+        self._set_head(next)
 
         next.switch()
 
-        try:
-            if DEBUG:
-                print 'after switch(%s) ->' % myswitch ,next
-                print
-            #self._set_head(next)
-            #self._head = next
-
-            retval = prev.tempval
-            if isinstance(retval, bomb):
-                print '!!!!! exploding !!!!!!'
-                self.bomb_explode(next)
+        retval = prev.tempval
+        if isinstance(retval, bomb):
+            self.bomb_explode(next)
 
-            return retval
-        except Exception, exp:
-            print '### Exception AFTER switch', exp
-            raise
+        return retval
 
     def schedule_callback(self, prev, next):
         ret = _schedule_hook(prev, next)
@@ -1117,7 +768,16 @@
         else:
             return -1
 
-
+def __init():
+    global main_tasklet
+    global main_coroutine
+    global scheduler 
+    main_coroutine = c = coroutine.getcurrent()
+    main_tasklet = TaskletProxy(c)
+    SETNEXT(main_tasklet, main_tasklet)
+    SETPREV(main_tasklet, main_tasklet)
+    main_tasklet.is_main = True
+    scheduler = Scheduler()
 
 __init()
 



More information about the Pypy-commit mailing list