Exceptions using Delay

Tagged:
Project:GNU Smalltalk
Component:VM
Category:bug
Priority:normal
Assigned:Unassigned
Status:fixed
Description

The following code produces exceptions as below in bursts after a few seconds. More generally, it seems Delay starts failing in situations where the system is somewhat loaded (such as during the event- and render-loops in our SDL/cairo bindings-in-progress).

Code:

Object subclass: DelayExperiment [
    run [
        [ (Delay forMilliseconds: 1) wait ] repeat.
    ]
].
DelayExperiment new run.

Expected output: nothing, forever.

Actual output:

$ gst delay-bug.st 
"Global garbage collection... done"
Object: nil error: did not understand #goodness:
MessageNotUnderstood(Exception)>>signal
UndefinedObject(Object)>>doesNotUnderstand: #goodness:
optimized [] in BlockClosure class>>exceptionHandlerSearchBlock
[] in Kernel.CoreException>>instantiateNextHandler:
MethodContext(ContextPart)>>scanBacktraceForAttribute:do:
Kernel.CoreException>>instantiateNextHandler:
SystemExceptions.PrimitiveFailed(Exception)>>signal
SystemExceptions.PrimitiveFailed class(Exception class)>>signal
ProcessorScheduler(Object)>>primitiveFailed
ProcessorScheduler>>signal:atMilliseconds:
Delay class>>handleDelayEvent
optimized [] in Delay class>>runDelayProcess
[] in BlockClosure>>ifCurtailed:
BlockClosure>>ensure:
BlockClosure>>ifCurtailed:
Delay class>>runDelayProcess
optimized [] in Delay class>>startDelayLoop
[] in Process>>onBlock:at:suspend:
BlockClosure>>on:do:
[] in Process>>onBlock:at:suspend:
BlockClosure>>ensure:
[] in Process>>onBlock:at:suspend:
[] in BlockClosure>>asContext:
BlockContext class>>fromClosure:parent:
Object: ProcessorScheduler new "<0x4030c820>" error: primitive operation failed
SystemExceptions.PrimitiveFailed(Exception)>>signal
SystemExceptions.PrimitiveFailed class(Exception class)>>signal
ProcessorScheduler(Object)>>primitiveFailed
ProcessorScheduler>>signal:atMilliseconds:
Delay class>>handleDelayEvent
optimized [] in Delay class>>runDelayProcess
[] in BlockClosure>>ifCurtailed:
BlockClosure>>ensure:
BlockClosure>>ifCurtailed:
Delay class>>runDelayProcess
optimized [] in Delay class>>startDelayLoop
[] in Process>>onBlock:at:suspend:
BlockClosure>>on:do:
[] in Process>>onBlock:at:suspend:
BlockClosure>>ensure:
[] in Process>>onBlock:at:suspend:
[] in BlockClosure>>asContext:
BlockContext class>>fromClosure:parent:
Object: ProcessorScheduler new "<0x4030c820>" error: primitive operation failed
SystemExceptions.PrimitiveFailed(Exception)>>signal
SystemExceptions.PrimitiveFailed class(Exception class)>>signal
ProcessorScheduler(Object)>>primitiveFailed
ProcessorScheduler>>signal:atMilliseconds:
Delay class>>handleDelayEvent
optimized [] in Delay class>>runDelayProcess
[] in BlockClosure>>ifCurtailed:
BlockClosure>>ensure:
BlockClosure>>ifCurtailed:
Delay class>>runDelayProcess
optimized [] in Delay class>>startDelayLoop
[] in Process>>onBlock:at:suspend:
BlockClosure>>on:do:
[] in Process>>onBlock:at:suspend:
BlockClosure>>ensure:
[] in Process>>onBlock:at:suspend:
[] in BlockClosure>>asContext:
BlockContext class>>fromClosure:parent:
Object: ProcessorScheduler new "<0x4030c820>" error: primitive operation failed
SystemExceptions.PrimitiveFailed(Exception)>>signal
SystemExceptions.PrimitiveFailed class(Exception class)>>signal
ProcessorScheduler(Object)>>primitiveFailed
ProcessorScheduler>>signal:atMilliseconds:
Delay class>>handleDelayEvent
optimized [] in Delay class>>runDelayProcess
[] in BlockClosure>>ifCurtailed:
BlockClosure>>ensure:
BlockClosure>>ifCurtailed:
Delay class>>runDelayProcess
optimized [] in Delay class>>startDelayLoop
[] in Process>>onBlock:at:suspend:
BlockClosure>>on:do:
[] in Process>>onBlock:at:suspend:
BlockClosure>>ensure:
[] in Process>>onBlock:at:suspend:
[] in BlockClosure>>asContext:
BlockContext class>>fromClosure:parent:
...
...
...

Updates

#1 submitted by Paolo Bonzini on Mon, 01/14/2008 - 20:28

Can you try this?

diff --git a/libgst/prims.def b/libgst/prims.def
index 745d902..a243af4 100644
--- a/libgst/prims.def

+++ b/libgst/prims.def

@@ -3000,10 +3000,8 @@ primitive VMpr_Processor_signalAtMilliseconds [succeed,fail,check_interrupt]

         _gst_enable_interrupts ();
       }
      else

- {
- _gst_async_timed_wait (oop1, arg2);
- PRIM_SUCCEEDED;
- }

+ _gst_async_timed_wait (oop1, arg2);

+ PRIM_SUCCEEDED;

    }

  UNPOP (2);

#2 submitted by Paolo Bonzini on Mon, 01/14/2008 - 20:30

Better:

diff --git a/libgst/prims.def b/libgst/prims.def
index 745d902..a243af4 100644
--- a/libgst/prims.def
+++ b/libgst/prims.def
@@ -3000,10 +3000,8 @@ primitive VMpr_Processor_signalAtMilliseconds [succeed,fail,check_interrupt]
          _gst_enable_interrupts ();
        }
       else
-       {
-         _gst_async_timed_wait (oop1, arg2);
-         PRIM_SUCCEEDED;
-       }
+       _gst_async_timed_wait (oop1, arg2);
+      PRIM_SUCCEEDED;
     }
 
   UNPOP (2);

#3 submitted by Tony Garnock-Jones on Tue, 01/15/2008 - 07:07
Status:active» reviewed

Thank you, that fixes it (and I can see why, too: the millisecond count is constantly 1 in the example, and code in Delay.st could arrange for it to drop by the occasional few milliseconds by the time it reaches the primitive, which could trigger the faulty conditional branch).

(I've set the status to reviewed - is that the right thing to do here?)

#4 submitted by Paolo Bonzini on Fri, 01/18/2008 - 07:55
Status:reviewed» fixed

committed a few days ago to master and stable-3.0

User login