On Wed, Sep 29, 2010 at 12:20 AM, Igor Stasenko siguctua@gmail.com wrote:
On 29 September 2010 09:35, Eliot Miranda eliot.miranda@gmail.com wrote:
Hi Igor,
On Tue, Sep 28, 2010 at 10:48 PM, Igor Stasenko siguctua@gmail.com
wrote:
As far as i understood , this is a way to insert own function to force VM to interrupt.
Alas I think it's the reverse of this. It is a way of getting the VM's
heartbeat to interrupt other functions. In both Cog VMs there is a heartbeat (preferrably in a high-priroity thread) that interrupts the VM at approximately 1KHz. It does this by setting the VM's stackLimit to a value that will cause the next stack check to always fail (stacks grow down so (unsigned)-1 is the value). Then the VM checks for events as part of its stack overflow processing. This makes the stack check do double-duty, and avoids having to maintain a counter which (a) is slow due to a read-modify-write cycle and (b) runs at a variable rate because the rate at which the counter counts depends on what the VM is doing. However, the heartbeat depends on the VM performing frequent stack checks (which it does on non-primiive sends) which won't help if for example the VM is executing a long-running primitive.
The Bochs plugin executes x86 code generated by the Cog JIT when
simulating the Cog VM. Bochs would happily run forever if the Cog JIT generated code that looped and I'd be hosed, except that setInterruptCheckChain allows the Bochs plugin to stop running when it is interrupted. So this isn't even close to what you want, right?
So as i understood by reverse is, that this is the way to force some other (non-main thread) to interrupt itself once heartbeat occurs. Right? Okay, this is userful as well as reverse control: Is there a thread-safe function to force VM to interrupt?
AFAIK its signalExternalSemaphore(), but what if you don't want to signal anything?
For example: i want my plugin to periodically update some small number of objects (probably smallints) held in some array.
This is cool.
But i don't see another insertion point, which could make this feature
complete.
Suppose my plugin needs to handle some external events. Then, in my custom interrupt checker i can check if there any pending events to handle, while during interrupt i should be able to install own routine as well, which could actually handle events (like convert events to some object(s) and/or signal semaphore
etc)
without worrying that i'm doing this in the middle of interpreter cycle, which may damage interpreter's volatile state.
Well, the signalExternalSemaphore mechanism (at least in Cog) is
thread-safe and can be used at any time form any thread to request a signal that will get performed at the next event check.
No, its not the same. During asynchronous event, of course you are limited to semaphores. But during synchronous interrupt you can do much more.
For synchronous activities one could indeed have a simple on-event-check chain. But you could do this with a process waiting on a Delay, polling occasionally, instead of calling some interrupt check function at high frequency every time the VM checks for events. It does that anyway in ioProcessEvents().
What's the use case?
For instance, create a linked list and append new objects directly to
that list once new events available. Then language side won't even need to bother using extra primitive to pool/read events from some source , and can simply do own stuff once new object(s) 'magically' appear in such list.
While one could provide a thread-safe object manipulation mechanism (I wrote a slow prototype in the VisualWorks VM in 1998) I think the best way to do this is with a callback. So Smalltalk code ends up translating from the C data into Smalltalk objects and manipulating the linked list and doing whatever else is needed. Doing otherwise really complicates the garbage collector etc. If instead one focusses on making callbacks as easy and efficient to use and possible one has a general mechanism and overall the system is simpler.
See the recordMouseEvent() and its friends (sqNextEventPut, eventBuffer[1024] ...) in sqWin32Window, for better understanding my point :)
Which makes my point well. These are simply maintaining a queue. If one has callbacks then the bulk of the Windows event handling system can be lifted up into the image. This is what Vassili Bykov did in Newspeak above my Alien callbacks. In Newspeak the Windows MainWndProc is a callback:
protected setupWindowProc = ( windowProc:: api Callback block: [:args :result | result returnInteger: (dispatchMessage: args)] stdcallArgsClass: api WindowProc )
The threaded FFI I'm working on will allow one to attempt a callback at
any time. The callback will simply block until it is safe for it to take over the VM. So this will also be thread-safe. But its not one yet.
HTH Eliot
P.S. I saw your other messages and will try and respond tomorrow.
Good.
-- Best regards, Igor Stasenko AKA sig.
-- Best regards, Igor Stasenko AKA sig.