Cog: A question about: setInterruptCheckChain()

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
27 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Cog: A question about: setInterruptCheckChain()

Igor Stasenko
 
As far as i understood , this is a way to insert own
function to force VM to interrupt.

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.


--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Eliot Miranda-2
 
Hi Igor,

On Tue, Sep 28, 2010 at 10:48 PM, Igor Stasenko <[hidden email]> 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?



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.

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.




--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Igor Stasenko

On 29 September 2010 09:35, Eliot Miranda <[hidden email]> wrote:

>
> Hi Igor,
>
> On Tue, Sep 28, 2010 at 10:48 PM, Igor Stasenko <[hidden email]> 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 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.

See the recordMouseEvent() and its friends (sqNextEventPut,
eventBuffer[1024] ...) in sqWin32Window, for better understanding my
point :)


> 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.
Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Eliot Miranda-2
 


On Wed, Sep 29, 2010 at 12:20 AM, Igor Stasenko <[hidden email]> wrote:

On 29 September 2010 09:35, Eliot Miranda <[hidden email]> wrote:
>
> Hi Igor,
>
> On Tue, Sep 28, 2010 at 10:48 PM, Igor Stasenko <[hidden email]> 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.

Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Andreas.Raab
 
On 9/29/2010 9:36 AM, Eliot Miranda wrote:

>     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:

Thus losing any level of platform abstraction. A bad trade-off, IMO.

Cheers,
   - Andreas
Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Eliot Miranda-2
 


On Wed, Sep 29, 2010 at 10:22 AM, Andreas Raab <[hidden email]> wrote:

On 9/29/2010 9:36 AM, Eliot Miranda wrote:
   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:

Thus losing any level of platform abstraction. A bad trade-off, IMO.

The platform abstraction merely moves from the VM to classes in the image.  But it does mean that one can properly implement Windows event semantics (things like query quit events) that the queue prevents.  And it means that the VM gets simpler and complexity is handled by better facilities (in Smalltalk with its many advantages for creating and maintaining abstractions with concrete variant implementations).

But you and I have had this discussion a number of times and I take your point about the VM maintaining a black-box abstraction boundary whereas the in-image implementation is in theory porous.  As I've said before this doesn't strike me as that important when Smalltalk has had boundary violators such as instVarAt:[put:] for ever and they are rarely abused.  If one were to implement a native GUI event interface in Smalltalk using callbacks one would have to police the abstraction boundary.  But that's easily done, and there are other benefits
- the VM, being simpler, gets more longevity since changing the event interface doesn't imply a VM change
- the system, having native interfaces, can support each platform's facilities in full instead of providing the lowest common denominator

So IMO it is a good trade-off.

best
Eliot


Cheers,
 - Andreas

Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Nicolas Cellier

Another aspect of the trade-off is releasing creativity.
To change the VM you need advanced skills in both:
- Smalltalk VM internals
- and external libraries you want to use.
That resticts dramatically the list of creators.

Plus, the difficulties for sharing your creation, you shall distribute:
- either a binary version, but this means users cannot have a mixture
of different features if those require a core modification,
- or VMMaker patches but your audience will shrink again.

On the other hand, a VM providing a larger de facto immutable API:
- somehow is more secure (a guaranty we can run very old images in
very new OSes).
- can maintain the illusion that despite the efforts of OS and
hardware designers to make it ever more complex, a single person can
still understand (almost) the whole system.
- avoid the necessity to embed knowledge of dozens of different
variants of different OSes in your image.

Of course, the complexity still exists under the carpet... When I
contemplate all the unecessary complex knowledge from those beautiful
configure/cmake scripts and macros, I'm not convinced all this cruft
will be easier to modify in Smalltalk than it is in C world.

I perfectly understand too the desire of a VM maintainer to lighten
the burden ;) though.

Nicolas

2010/9/29 Eliot Miranda <[hidden email]>:

>
>
>
> On Wed, Sep 29, 2010 at 10:22 AM, Andreas Raab <[hidden email]> wrote:
>>
>> On 9/29/2010 9:36 AM, Eliot Miranda wrote:
>>>
>>>    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:
>>
>> Thus losing any level of platform abstraction. A bad trade-off, IMO.
>
> The platform abstraction merely moves from the VM to classes in the image.  But it does mean that one can properly implement Windows event semantics (things like query quit events) that the queue prevents.  And it means that the VM gets simpler and complexity is handled by better facilities (in Smalltalk with its many advantages for creating and maintaining abstractions with concrete variant implementations).
> But you and I have had this discussion a number of times and I take your point about the VM maintaining a black-box abstraction boundary whereas the in-image implementation is in theory porous.  As I've said before this doesn't strike me as that important when Smalltalk has had boundary violators such as instVarAt:[put:] for ever and they are rarely abused.  If one were to implement a native GUI event interface in Smalltalk using callbacks one would have to police the abstraction boundary.  But that's easily done, and there are other benefits
> - the VM, being simpler, gets more longevity since changing the event interface doesn't imply a VM change
> - the system, having native interfaces, can support each platform's facilities in full instead of providing the lowest common denominator
> So IMO it is a good trade-off.
> best
> Eliot
>>
>> Cheers,
>>  - Andreas
>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Andreas.Raab
 
On 9/29/2010 11:53 AM, Nicolas Cellier wrote:

> Another aspect of the trade-off is releasing creativity.
> To change the VM you need advanced skills in both:
> - Smalltalk VM internals
> - and external libraries you want to use.
> That resticts dramatically the list of creators.
>
> Plus, the difficulties for sharing your creation, you shall distribute:
> - either a binary version, but this means users cannot have a mixture
> of different features if those require a core modification,
> - or VMMaker patches but your audience will shrink again.

That's why we have plugins. Keeping the core of the VM as small as
possible is most definitely a Very Good Thing and not what's being
discussed here. What's being discussed here is if (from that point on)
one should provide layers of abstractions via plugins or if one should
just expose the image directly to all of the idiosyncrasies of the
platform, handing it pointers and let it make FFI calls.

It really is a matter of where you want to deal with certain aspects of
the system. I prefer to deal with that level of stuff in a plugin via C
because:
+ it provides a way to do ensure memory safety
+ it provides a way to provide abstractions
+ the code is faster to write and debug in C
+ access to facilities (threads, interrupts, atomicity) not available
otherwise

On the downside, there is:
- it's harder to modify for people who don't know C and are not set up
to build a plugin
- it's often aimed at the smallest common denominator (though not
necessarily)

Cheers,
   - Andreas

> On the other hand, a VM providing a larger de facto immutable API:
> - somehow is more secure (a guaranty we can run very old images in
> very new OSes).
> - can maintain the illusion that despite the efforts of OS and
> hardware designers to make it ever more complex, a single person can
> still understand (almost) the whole system.
> - avoid the necessity to embed knowledge of dozens of different
> variants of different OSes in your image.
>
> Of course, the complexity still exists under the carpet... When I
> contemplate all the unecessary complex knowledge from those beautiful
> configure/cmake scripts and macros, I'm not convinced all this cruft
> will be easier to modify in Smalltalk than it is in C world.
>
> I perfectly understand too the desire of a VM maintainer to lighten
> the burden ;) though.
>
> Nicolas
>
> 2010/9/29 Eliot Miranda<[hidden email]>:
>>
>>
>>
>> On Wed, Sep 29, 2010 at 10:22 AM, Andreas Raab<[hidden email]>  wrote:
>>>
>>> On 9/29/2010 9:36 AM, Eliot Miranda wrote:
>>>>
>>>>     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:
>>>
>>> Thus losing any level of platform abstraction. A bad trade-off, IMO.
>>
>> The platform abstraction merely moves from the VM to classes in the image.  But it does mean that one can properly implement Windows event semantics (things like query quit events) that the queue prevents.  And it means that the VM gets simpler and complexity is handled by better facilities (in Smalltalk with its many advantages for creating and maintaining abstractions with concrete variant implementations).
>> But you and I have had this discussion a number of times and I take your point about the VM maintaining a black-box abstraction boundary whereas the in-image implementation is in theory porous.  As I've said before this doesn't strike me as that important when Smalltalk has had boundary violators such as instVarAt:[put:] for ever and they are rarely abused.  If one were to implement a native GUI event interface in Smalltalk using callbacks one would have to police the abstraction boundary.  But that's easily done, and there are other benefits
>> - the VM, being simpler, gets more longevity since changing the event interface doesn't imply a VM change
>> - the system, having native interfaces, can support each platform's facilities in full instead of providing the lowest common denominator
>> So IMO it is a good trade-off.
>> best
>> Eliot
>>>
>>> Cheers,
>>>   - Andreas
>>
>>
>>
>
Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Bert Freudenberg
In reply to this post by Nicolas Cellier

On 29.09.2010, at 20:53, Nicolas Cellier wrote:

>  When I
> contemplate all the unecessary complex knowledge from those beautiful
> configure/cmake scripts and macros, I'm not convinced all this cruft
> will be easier to modify in Smalltalk than it is in C world.

You still have to know C and the C libraries to do anything at that level. Using FFI does not buy you anything in this regard.

While other languages see themselves as C extensions / glue languages and happily expose C constructs directly, IMHO Squeak should not depend on FFI, but use proper VM abstractions. Supporting FFI is good, depending on it, not.

- Bert -

Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Eliot Miranda-2
In reply to this post by Andreas.Raab
 


On Wed, Sep 29, 2010 at 12:22 PM, Andreas Raab <[hidden email]> wrote:

On 9/29/2010 11:53 AM, Nicolas Cellier wrote:
Another aspect of the trade-off is releasing creativity.
To change the VM you need advanced skills in both:
- Smalltalk VM internals
- and external libraries you want to use.
That resticts dramatically the list of creators.

Plus, the difficulties for sharing your creation, you shall distribute:
- either a binary version, but this means users cannot have a mixture
of different features if those require a core modification,
- or VMMaker patches but your audience will shrink again.

That's why we have plugins. Keeping the core of the VM as small as possible is most definitely a Very Good Thing and not what's being discussed here.

I think it /is/, and you shouldn't allow your disinclination for the FFI approach blind you to the fact that one way of keeping the VM small is to produce a really strong flexible FFI that supports threading and callbacks and to implement interfaces above the line.  Do you seriously believe things like the ODBC connect should be implemented in plugins?

What's being discussed here is if (from that point on) one should provide layers of abstractions via plugins or if one should just expose the image directly to all of the idiosyncrasies of the platform, handing it pointers and let it make FFI calls.

In the case of event callbacks its a different issue.  The current event queue abstraction is broken in that it prevents Smalltalk code from answering questions asked through events such as WM_QUERYENDSESSION because the VM is forced to queue events, and hence can only provide a default answer in the window proc.  So there are areas where having proper callbacks is required to be able to integrate properly with the host operating system.

I don't disagree with what you say about plugins, or about maintaining cross-platform abstractions in the VM for core functionality that is common across platforms, but I think its clear one needs true callbacks, and that at least for integrating with the GUI this is the best way to implement it.


It really is a matter of where you want to deal with certain aspects of the system. I prefer to deal with that level of stuff in a plugin via C because:
+ it provides a way to do ensure memory safety

there's nothing in plugins per-se to maintain memory safety.  A mistake in a plugin is as destructive as a mistake in an FFI call.  In either case a wrapper around a particular call can validate and provide safety.
 
+ it provides a way to provide abstractions

- so does Smalltalk, and t least in SMalltalk we have inheritance to enable us to express cross-platform APIs in abstract classes and map these down onto particular platforms in concrete subclasses.  This is /far better/ than the sprawling mess that is the platforms tree in the VM.
 
+ the code is faster to write and debug in C

this is debatable.  In the VW FFI with the ability to catch exceptions and pass them back up (doesn't always work, a bad emory corruption may crash the entire system) makes thing easier.  But low-level debugging is painful in general.
 
+ access to facilities (threads, interrupts, atomicity) not available otherwise

Again, a strong FFI provides at least some of these facilities.  Not everything can be done through the FFI, but a lot can be done, and elegantly and extensibly, by Smalltalk programmers, not a few VM specialists.


On the downside, there is:
- it's harder to modify for people who don't know C and are not set up to build a plugin
- it's often aimed at the smallest common denominator (though not necessarily)
 
- it is a far more fixed interface that is far harder to evolve
 
best,
Eliot


Cheers,
 - Andreas


On the other hand, a VM providing a larger de facto immutable API:
- somehow is more secure (a guaranty we can run very old images in
very new OSes).
- can maintain the illusion that despite the efforts of OS and
hardware designers to make it ever more complex, a single person can
still understand (almost) the whole system.
- avoid the necessity to embed knowledge of dozens of different
variants of different OSes in your image.

Of course, the complexity still exists under the carpet... When I
contemplate all the unecessary complex knowledge from those beautiful
configure/cmake scripts and macros, I'm not convinced all this cruft
will be easier to modify in Smalltalk than it is in C world.

I perfectly understand too the desire of a VM maintainer to lighten
the burden ;) though.

Nicolas

2010/9/29 Eliot Miranda<[hidden email]>:



On Wed, Sep 29, 2010 at 10:22 AM, Andreas Raab<[hidden email]>  wrote:

On 9/29/2010 9:36 AM, Eliot Miranda wrote:

   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:

Thus losing any level of platform abstraction. A bad trade-off, IMO.

The platform abstraction merely moves from the VM to classes in the image.  But it does mean that one can properly implement Windows event semantics (things like query quit events) that the queue prevents.  And it means that the VM gets simpler and complexity is handled by better facilities (in Smalltalk with its many advantages for creating and maintaining abstractions with concrete variant implementations).
But you and I have had this discussion a number of times and I take your point about the VM maintaining a black-box abstraction boundary whereas the in-image implementation is in theory porous.  As I've said before this doesn't strike me as that important when Smalltalk has had boundary violators such as instVarAt:[put:] for ever and they are rarely abused.  If one were to implement a native GUI event interface in Smalltalk using callbacks one would have to police the abstraction boundary.  But that's easily done, and there are other benefits
- the VM, being simpler, gets more longevity since changing the event interface doesn't imply a VM change
- the system, having native interfaces, can support each platform's facilities in full instead of providing the lowest common denominator
So IMO it is a good trade-off.
best
Eliot

Cheers,
 - Andreas





Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Igor Stasenko
In reply to this post by Eliot Miranda-2

On 29 September 2010 19:36, Eliot Miranda <[hidden email]> wrote:

>
>
>
> On Wed, Sep 29, 2010 at 12:20 AM, Igor Stasenko <[hidden email]> wrote:
>>
>> On 29 September 2010 09:35, Eliot Miranda <[hidden email]> wrote:
>> >
>> > Hi Igor,
>> >
>> > On Tue, Sep 28, 2010 at 10:48 PM, Igor Stasenko <[hidden email]> 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
> )

Yep.. but for that, you should be able to give me a choice:
- how i can disable a default VM event handling , so then i can
install and use callbacks?

There are multiple things right now, which won't allow me to do that.
Not reentrant interpret(), no way to control why and when VM deciding
to interrupt and call ioHandleEvents().
And now way to install own ioHandleEvents(), in order to replace a default one.

My own idea was to have a function pointer, instead direct call to
ioProcessEvents(), and let plugins to install/replace this pointer
with anything we want.
This is similar to chaining, you made for hearbeat thread.


>>
>> > 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.
>
>
>



--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Igor Stasenko
In reply to this post by Bert Freudenberg

On 29 September 2010 22:40, Bert Freudenberg <[hidden email]> wrote:

>
> On 29.09.2010, at 20:53, Nicolas Cellier wrote:
>
>>  When I
>> contemplate all the unecessary complex knowledge from those beautiful
>> configure/cmake scripts and macros, I'm not convinced all this cruft
>> will be easier to modify in Smalltalk than it is in C world.
>
> You still have to know C and the C libraries to do anything at that level. Using FFI does not buy you anything in this regard.
>
> While other languages see themselves as C extensions / glue languages and happily expose C constructs directly, IMHO Squeak should not depend on FFI, but use proper VM abstractions. Supporting FFI is good, depending on it, not.
>

My intent is to make VM flexible. Sure thing, VM should provide a
default OS-specific layer.
The pity is, that i can't alter/replace it, when using FFI.


> - Bert -
>
>



--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Igor Stasenko
In reply to this post by Eliot Miranda-2

On 29 September 2010 23:03, Eliot Miranda <[hidden email]> wrote:

>
>
>
> On Wed, Sep 29, 2010 at 12:22 PM, Andreas Raab <[hidden email]> wrote:
>>
>> On 9/29/2010 11:53 AM, Nicolas Cellier wrote:
>>>
>>> Another aspect of the trade-off is releasing creativity.
>>> To change the VM you need advanced skills in both:
>>> - Smalltalk VM internals
>>> - and external libraries you want to use.
>>> That resticts dramatically the list of creators.
>>>
>>> Plus, the difficulties for sharing your creation, you shall distribute:
>>> - either a binary version, but this means users cannot have a mixture
>>> of different features if those require a core modification,
>>> - or VMMaker patches but your audience will shrink again.
>>
>> That's why we have plugins. Keeping the core of the VM as small as possible is most definitely a Very Good Thing and not what's being discussed here.
>
> I think it /is/, and you shouldn't allow your disinclination for the FFI approach blind you to the fact that one way of keeping the VM small is to produce a really strong flexible FFI that supports threading and callbacks and to implement interfaces above the line.  Do you seriously believe things like the ODBC connect should be implemented in plugins?
>>
>> What's being discussed here is if (from that point on) one should provide layers of abstractions via plugins or if one should just expose the image directly to all of the idiosyncrasies of the platform, handing it pointers and let it make FFI calls.
>
> In the case of event callbacks its a different issue.  The current event queue abstraction is broken in that it prevents Smalltalk code from answering questions asked through events such as WM_QUERYENDSESSION because the VM is forced to queue events, and hence can only provide a default answer in the window proc.  So there are areas where having proper callbacks is required to be able to integrate properly with the host operating system.
> I don't disagree with what you say about plugins, or about maintaining cross-platform abstractions in the VM for core functionality that is common across platforms, but I think its clear one needs true callbacks, and that at least for integrating with the GUI this is the best way to implement it.
>
>> It really is a matter of where you want to deal with certain aspects of the system. I prefer to deal with that level of stuff in a plugin via C because:
>> + it provides a way to do ensure memory safety
>
> there's nothing in plugins per-se to maintain memory safety.  A mistake in a plugin is as destructive as a mistake in an FFI call.  In either case a wrapper around a particular call can validate and provide safety.
>
>>
>> + it provides a way to provide abstractions
>
> - so does Smalltalk, and t least in SMalltalk we have inheritance to enable us to express cross-platform APIs in abstract classes and map these down onto particular platforms in concrete subclasses.  This is /far better/ than the sprawling mess that is the platforms tree in the VM.
>
>>
>> + the code is faster to write and debug in C
>
> this is debatable.  In the VW FFI with the ability to catch exceptions and pass them back up (doesn't always work, a bad emory corruption may crash the entire system) makes thing easier.  But low-level debugging is painful in general.
>
>>
>> + access to facilities (threads, interrupts, atomicity) not available otherwise
>
> Again, a strong FFI provides at least some of these facilities.  Not everything can be done through the FFI, but a lot can be done, and elegantly and extensibly, by Smalltalk programmers, not a few VM specialists.
>>
>> On the downside, there is:
>> - it's harder to modify for people who don't know C and are not set up to build a plugin
>> - it's often aimed at the smallest common denominator (though not necessarily)
>
>
> - it is a far more fixed interface that is far harder to evolve
>

Eliot, i don't know what to say in addition. I have same thoughts as you.

Its not a question, that VM should provide a default platform
abstraction layer(s).
But the question, how i can make part's of it optional, or easily
alter/replace them with own implementation (either plugin of ffi)
in case of need, without the need of shipping of own, custom built VM?

Where ends a VM's mandatory functionality and starts an optional one?
a) providing UI & event handling?
  Apparently not for those who wants to run VM as GUI-less
command-line tool or implement own GUI framework.
b) providing a network layer?
  Apparently not for those, who not using network in their
application(s), and instead want to make sure that no network
  activity possible. Or again, wants to provide own network layer.

FFI is not a silver bullet. But my point is not putting you before
choice: use C or FFI.
Its about making VM more flexible at run-time, not at compile time.

> best,
> Eliot


--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Derek O'Connell-3
 
  > it is a far more fixed interface that is far harder to evolve
...
 > Its about making VM more flexible at run-time, not at compile time.

These are exactly my recent thoughts and which led me to get
reacquainted with Forth as the basis for a "re-programmable" plug-in.
It's hard then not to consider a Forth based VM bootstrapped from the
image itself, although I'm not yet sure this is even a sane idea :-) I
wouldn't be surprised if someone has already considered and rejected it.

-D
Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Andreas.Raab
In reply to this post by Eliot Miranda-2
 
On 9/29/2010 1:03 PM, Eliot Miranda wrote:
> I think it /is/, and you shouldn't allow your disinclination for the FFI
> approach blind you to the fact that one way of keeping the VM small is
> to produce a really strong flexible FFI that supports threading and
> callbacks and to implement interfaces above the line.  Do you seriously
> believe things like the ODBC connect should be implemented in plugins?

Absolutely. Memory safety being the prime reason.

> In the case of event callbacks its a different issue.  The current event
> queue abstraction is broken in that it prevents Smalltalk code from
> answering questions asked through events such as WM_QUERYENDSESSION
> because the VM is forced to queue events, and hence can only provide a
> default answer in the window proc.  So there are areas where having
> proper callbacks is required to be able to integrate properly with the
> host operating system.

Please. The issue here is that our event mechanism is a bit simplistic
but the Android VM is a great example of how to deal with these issues
properly. Sure, callbacks could address this too, but claiming *only*
callbacks can address this is simply wrong.

> I don't disagree with what you say about plugins, or about maintaining
> cross-platform abstractions in the VM for core functionality that is
> common across platforms, but I think its clear one needs true callbacks,
> and that at least for integrating with the GUI this is the best way to
> implement it.

A solution that inherently implies exposure of raw pointers to users
isn't what I would call the "best" solution. That said, I'm not arguing
against callbacks - when you need them you need them. And there are
practical situations where it's incredibly handy to have them. And yet,
would I design the system so that it depends at its core on such
facilities? Hell, no, because in addition to being memory-unsafe,
porting an FFI is *much* harder than porting a bit of C support code.

>     It really is a matter of where you want to deal with certain aspects
>     of the system. I prefer to deal with that level of stuff in a plugin
>     via C because:
>     + it provides a way to do ensure memory safety
>
> there's nothing in plugins per-se to maintain memory safety.  A mistake
> in a plugin is as destructive as a mistake in an FFI call.  In either
> case a wrapper around a particular call can validate and provide safety.

In theory, yes. In practice such wrappers *do* exist in plugins and they
do *not* exist in FFI calls. Why? Good question. Probably because people
understand that in C land there are more constraints and they are
mentally "set up" to keep an eye on the constraints and to make sure the
incoming stuff is okay.

>     + it provides a way to provide abstractions
>
> - so does Smalltalk, and t least in SMalltalk we have inheritance to
> enable us to express cross-platform APIs in abstract classes and map
> these down onto particular platforms in concrete subclasses.  This is
> /far better/ than the sprawling mess that is the platforms tree in the VM.

In theory yes. In practice, who knows. Having looked at some Smalltalks
that expose all the platform details (like Dolphin) it seems to me that
the equation of "platform FFI code * number of platforms" will be /far
more/ of a sprawling mess. Which is probably why (unless I'm mistaken in
which case I'll appreciate a correction) precisely none of the
cross-platform Smalltalks do that.

>     + the code is faster to write and debug in C
>
> this is debatable.

Hardly. Let's start with "#include <windows.h>" (or whatever platform
stuff you happen to need). You're losing right there. The problem is
that the system isn't set up to seamlessly interact with C. Even if
you've got some auto-magic header file importer that creates structs and
defines and stuff, as long as it takes more than, i.e.,

winMessageBox: contents title: title
        <include: 'windows.h'>
        MessageBox(NULL, contents, title, MB_OK + MB_ICONWARNING).

you're going to lose because it takes so much longer to get to the point
of actually writing the code you're trying to write.

Secondly, you *really* need to try the latest Visual Studio and play
with its debugger - I was blown away while debugging SqueakSSL when I
hit a typical NULL pointer, fixed the code in my plugin DLL, continued
in VS and the underlying Squeak KEPT RUNNING! Holy crap. This stuff has
come a looooong way.

> In the VW FFI with the ability to catch exceptions
> and pass them back up (doesn't always work, a bad emory corruption may
> crash the entire system) makes thing easier.  But low-level debugging is
> painful in general.
>
>     + access to facilities (threads, interrupts, atomicity) not
>     available otherwise
>
> Again, a strong FFI provides at least some of these facilities.  Not
> everything can be done through the FFI, but a lot can be done, and
> elegantly and extensibly, by Smalltalk programmers, not a few VM
> specialists.

I call BS. The reality is that one needs to know three kinds of things,
only one of which would be helped by using the FFI:

1) The "mechanics" of writing a plugin, i.e., slang and compilation.
This is the part where the FFI would help, but so would better APIs for
marshaling. While it's "cool" that one can run slang plugins in Squeak
it is also completely and utterly *useless* when it comes to integrating
platform specific stuff and having to deal with Slang, VMMaker and the
awful build setups, and then -on top of that- the actual work you're
trying to do is just a bit too much.

2) Understanding the rules of interfacing the external world, i.e., when
can pointers be kept, what does GC do to your objects etc. None of this
is helped by using the FFI.

3) Understanding the actual domain code. Again, none of this is helped
by the FFI (to the contrary because nobody will find examples for the
weird Smalltalk selectors we use on the web and people will in turn not
know where to find the actual value for MB_OK or somesuch).

Basically, the assumption that *all* the difficulty is in writing the
marshaling code is nonsense. There is some of it, true, but that is
entirely our fault for providing poor integration APIs.

>     On the downside, there is:
>     - it's harder to modify for people who don't know C and are not set
>     up to build a plugin
>     - it's often aimed at the smallest common denominator (though not
>     necessarily)
>
> - it is a far more fixed interface that is far harder to evolve

Yes, but when you call it "stable" instead of "fixed" and "robust"
instead of "harder to evolve" it becomes a plus :-)

Cheers,
   - Andreas


>     Cheers,
>       - Andreas
>
>
>         On the other hand, a VM providing a larger de facto immutable API:
>         - somehow is more secure (a guaranty we can run very old images in
>         very new OSes).
>         - can maintain the illusion that despite the efforts of OS and
>         hardware designers to make it ever more complex, a single person can
>         still understand (almost) the whole system.
>         - avoid the necessity to embed knowledge of dozens of different
>         variants of different OSes in your image.
>
>         Of course, the complexity still exists under the carpet... When I
>         contemplate all the unecessary complex knowledge from those
>         beautiful
>         configure/cmake scripts and macros, I'm not convinced all this cruft
>         will be easier to modify in Smalltalk than it is in C world.
>
>         I perfectly understand too the desire of a VM maintainer to lighten
>         the burden ;) though.
>
>         Nicolas
>
>         2010/9/29 Eliot Miranda<[hidden email]
>         <mailto:[hidden email]>>:
>
>
>
>
>             On Wed, Sep 29, 2010 at 10:22 AM, Andreas
>             Raab<[hidden email] <mailto:[hidden email]>>  wrote:
>
>
>                 On 9/29/2010 9:36 AM, Eliot Miranda wrote:
>
>
>                         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:
>
>
>                 Thus losing any level of platform abstraction. A bad
>                 trade-off, IMO.
>
>
>             The platform abstraction merely moves from the VM to classes
>             in the image.  But it does mean that one can properly
>             implement Windows event semantics (things like query quit
>             events) that the queue prevents.  And it means that the VM
>             gets simpler and complexity is handled by better facilities
>             (in Smalltalk with its many advantages for creating and
>             maintaining abstractions with concrete variant implementations).
>             But you and I have had this discussion a number of times and
>             I take your point about the VM maintaining a black-box
>             abstraction boundary whereas the in-image implementation is
>             in theory porous.  As I've said before this doesn't strike
>             me as that important when Smalltalk has had boundary
>             violators such as instVarAt:[put:] for ever and they are
>             rarely abused.  If one were to implement a native GUI event
>             interface in Smalltalk using callbacks one would have to
>             police the abstraction boundary.  But that's easily done,
>             and there are other benefits
>             - the VM, being simpler, gets more longevity since changing
>             the event interface doesn't imply a VM change
>             - the system, having native interfaces, can support each
>             platform's facilities in full instead of providing the
>             lowest common denominator
>             So IMO it is a good trade-off.
>             best
>             Eliot
>
>
>                 Cheers,
>                   - Andreas
>
>
>
>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Igor Stasenko

On 30 September 2010 02:22, Andreas Raab <[hidden email]> wrote:

>
> On 9/29/2010 1:03 PM, Eliot Miranda wrote:
>>
>> I think it /is/, and you shouldn't allow your disinclination for the FFI
>> approach blind you to the fact that one way of keeping the VM small is
>> to produce a really strong flexible FFI that supports threading and
>> callbacks and to implement interfaces above the line.  Do you seriously
>> believe things like the ODBC connect should be implemented in plugins?
>
> Absolutely. Memory safety being the prime reason.
>
>> In the case of event callbacks its a different issue.  The current event
>> queue abstraction is broken in that it prevents Smalltalk code from
>> answering questions asked through events such as WM_QUERYENDSESSION
>> because the VM is forced to queue events, and hence can only provide a
>> default answer in the window proc.  So there are areas where having
>> proper callbacks is required to be able to integrate properly with the
>> host operating system.
>
> Please. The issue here is that our event mechanism is a bit simplistic but
> the Android VM is a great example of how to deal with these issues properly.
> Sure, callbacks could address this too, but claiming *only* callbacks can
> address this is simply wrong.
>
>> I don't disagree with what you say about plugins, or about maintaining
>> cross-platform abstractions in the VM for core functionality that is
>> common across platforms, but I think its clear one needs true callbacks,
>> and that at least for integrating with the GUI this is the best way to
>> implement it.
>
> A solution that inherently implies exposure of raw pointers to users isn't
> what I would call the "best" solution. That said, I'm not arguing against
> callbacks - when you need them you need them. And there are practical
> situations where it's incredibly handy to have them. And yet, would I design
> the system so that it depends at its core on such facilities? Hell, no,
> because in addition to being memory-unsafe, porting an FFI is *much* harder
> than porting a bit of C support code.
>
>>    It really is a matter of where you want to deal with certain aspects
>>    of the system. I prefer to deal with that level of stuff in a plugin
>>    via C because:
>>    + it provides a way to do ensure memory safety
>>
>> there's nothing in plugins per-se to maintain memory safety.  A mistake
>> in a plugin is as destructive as a mistake in an FFI call.  In either
>> case a wrapper around a particular call can validate and provide safety.
>
> In theory, yes. In practice such wrappers *do* exist in plugins and they do
> *not* exist in FFI calls. Why? Good question. Probably because people
> understand that in C land there are more constraints and they are mentally
> "set up" to keep an eye on the constraints and to make sure the incoming
> stuff is okay.
>
>>    + it provides a way to provide abstractions
>>
>> - so does Smalltalk, and t least in SMalltalk we have inheritance to
>> enable us to express cross-platform APIs in abstract classes and map
>> these down onto particular platforms in concrete subclasses.  This is
>> /far better/ than the sprawling mess that is the platforms tree in the VM.
>
> In theory yes. In practice, who knows. Having looked at some Smalltalks that
> expose all the platform details (like Dolphin) it seems to me that the
> equation of "platform FFI code * number of platforms" will be /far more/ of
> a sprawling mess. Which is probably why (unless I'm mistaken in which case
> I'll appreciate a correction) precisely none of the cross-platform
> Smalltalks do that.
>
>>    + the code is faster to write and debug in C
>>
>> this is debatable.
>
> Hardly. Let's start with "#include <windows.h>" (or whatever platform stuff
> you happen to need). You're losing right there. The problem is that the
> system isn't set up to seamlessly interact with C. Even if you've got some
> auto-magic header file importer that creates structs and defines and stuff,
> as long as it takes more than, i.e.,
>
> winMessageBox: contents title: title
>        <include: 'windows.h'>
>        MessageBox(NULL, contents, title, MB_OK + MB_ICONWARNING).
>
> you're going to lose because it takes so much longer to get to the point of
> actually writing the code you're trying to write.
>
> Secondly, you *really* need to try the latest Visual Studio and play with
> its debugger - I was blown away while debugging SqueakSSL when I hit a
> typical NULL pointer, fixed the code in my plugin DLL, continued in VS and
> the underlying Squeak KEPT RUNNING! Holy crap. This stuff has come a
> looooong way.
>
>> In the VW FFI with the ability to catch exceptions
>> and pass them back up (doesn't always work, a bad emory corruption may
>> crash the entire system) makes thing easier.  But low-level debugging is
>> painful in general.
>>
>>    + access to facilities (threads, interrupts, atomicity) not
>>    available otherwise
>>
>> Again, a strong FFI provides at least some of these facilities.  Not
>> everything can be done through the FFI, but a lot can be done, and
>> elegantly and extensibly, by Smalltalk programmers, not a few VM
>> specialists.
>
> I call BS. The reality is that one needs to know three kinds of things, only
> one of which would be helped by using the FFI:
>
> 1) The "mechanics" of writing a plugin, i.e., slang and compilation. This is
> the part where the FFI would help, but so would better APIs for marshaling.
> While it's "cool" that one can run slang plugins in Squeak it is also
> completely and utterly *useless* when it comes to integrating platform
> specific stuff and having to deal with Slang, VMMaker and the awful build
> setups, and then -on top of that- the actual work you're trying to do is
> just a bit too much.
>

And i am here looking for a way to make it less painful.
If one can make own stuff to work with OS via FFI,
why he needs to go into slang , VMMaker, cmake, gcc jungles?
Probably, when he consider that FFI is good, but have to use more
safer solution,
then he free to go and implement plugin or change VM, whatever.
But for prototyping and fast implementation, FFI much better.


> 2) Understanding the rules of interfacing the external world, i.e., when can
> pointers be kept, what does GC do to your objects etc. None of this is
> helped by using the FFI.
>
> 3) Understanding the actual domain code. Again, none of this is helped by
> the FFI (to the contrary because nobody will find examples for the weird
> Smalltalk selectors we use on the web and people will in turn not know where
> to find the actual value for MB_OK or somesuch).
>
> Basically, the assumption that *all* the difficulty is in writing the
> marshaling code is nonsense. There is some of it, true, but that is entirely
> our fault for providing poor integration APIs.
>
>>    On the downside, there is:
>>    - it's harder to modify for people who don't know C and are not set
>>    up to build a plugin
>>    - it's often aimed at the smallest common denominator (though not
>>    necessarily)
>>
>> - it is a far more fixed interface that is far harder to evolve
>
> Yes, but when you call it "stable" instead of "fixed" and "robust" instead
> of "harder to evolve" it becomes a plus :-)
>

Not in context of current discussion. VM has to evolve and improve
over a time. And we here to discuss what best path
to take to improve VM, not 'lets freeze it for ages'.
If you want to see something stable - feel free to browse the
SqueakMap and SqueakSource,
there you'll find many 'stable' stuff, which done once and then left
unattended and not working under
current VMs and images.

<sarcasm>
Why Croquet using FFI for OpenGL binding, why not writing a plugin? It
would be much more 'stable'
and 'robust' and secure.
</sarcasm>

> Cheers,
>  - Andreas
>
>
>>    Cheers,
>>      - Andreas
>>
>>
>>        On the other hand, a VM providing a larger de facto immutable API:
>>        - somehow is more secure (a guaranty we can run very old images in
>>        very new OSes).
>>        - can maintain the illusion that despite the efforts of OS and
>>        hardware designers to make it ever more complex, a single person
>> can
>>        still understand (almost) the whole system.
>>        - avoid the necessity to embed knowledge of dozens of different
>>        variants of different OSes in your image.
>>
>>        Of course, the complexity still exists under the carpet... When I
>>        contemplate all the unecessary complex knowledge from those
>>        beautiful
>>        configure/cmake scripts and macros, I'm not convinced all this
>> cruft
>>        will be easier to modify in Smalltalk than it is in C world.
>>
>>        I perfectly understand too the desire of a VM maintainer to lighten
>>        the burden ;) though.
>>
>>        Nicolas
>>
>>        2010/9/29 Eliot Miranda<[hidden email]
>>        <mailto:[hidden email]>>:
>>
>>
>>
>>
>>            On Wed, Sep 29, 2010 at 10:22 AM, Andreas
>>            Raab<[hidden email] <mailto:[hidden email]>>  wrote:
>>
>>
>>                On 9/29/2010 9:36 AM, Eliot Miranda wrote:
>>
>>
>>                        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:
>>
>>
>>                Thus losing any level of platform abstraction. A bad
>>                trade-off, IMO.
>>
>>
>>            The platform abstraction merely moves from the VM to classes
>>            in the image.  But it does mean that one can properly
>>            implement Windows event semantics (things like query quit
>>            events) that the queue prevents.  And it means that the VM
>>            gets simpler and complexity is handled by better facilities
>>            (in Smalltalk with its many advantages for creating and
>>            maintaining abstractions with concrete variant
>> implementations).
>>            But you and I have had this discussion a number of times and
>>            I take your point about the VM maintaining a black-box
>>            abstraction boundary whereas the in-image implementation is
>>            in theory porous.  As I've said before this doesn't strike
>>            me as that important when Smalltalk has had boundary
>>            violators such as instVarAt:[put:] for ever and they are
>>            rarely abused.  If one were to implement a native GUI event
>>            interface in Smalltalk using callbacks one would have to
>>            police the abstraction boundary.  But that's easily done,
>>            and there are other benefits
>>            - the VM, being simpler, gets more longevity since changing
>>            the event interface doesn't imply a VM change
>>            - the system, having native interfaces, can support each
>>            platform's facilities in full instead of providing the
>>            lowest common denominator
>>            So IMO it is a good trade-off.
>>            best
>>            Eliot
>>
>>
>>                Cheers,
>>                  - Andreas
>>
>>
>>
>>
>>
>>
>



--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Andreas.Raab
 
[Side note: Please don't quote entire posts if you're going to reply
2/3rds of the way down. I had to scroll three times through this post to
even find what you replied to]

On 9/29/2010 5:50 PM, Igor Stasenko wrote:

>> 1) The "mechanics" of writing a plugin, i.e., slang and compilation. This is
>> the part where the FFI would help, but so would better APIs for marshaling.
>> While it's "cool" that one can run slang plugins in Squeak it is also
>> completely and utterly *useless* when it comes to integrating platform
>> specific stuff and having to deal with Slang, VMMaker and the awful build
>> setups, and then -on top of that- the actual work you're trying to do is
>> just a bit too much.
>
> And i am here looking for a way to make it less painful.
> If one can make own stuff to work with OS via FFI,
> why he needs to go into slang , VMMaker, cmake, gcc jungles?

One word: Memory safety. Oh, that's two :-)

> Probably, when he consider that FFI is good, but have to use more
> safer solution,
> then he free to go and implement plugin or change VM, whatever.
> But for prototyping and fast implementation, FFI much better.

See, in my experience that claim is simply wrong. How can you say that
(for example) a little test program like the one that I just wrote to
experiment with a Windows function would be faster to write using the FFI?

------------------------------ CredTest.cpp ----------------------------

// CredTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>
#include <wincred.h>

LPTSTR readCredential(LPTSTR targetName) {
        CREDENTIAL *cred;

        if(CredRead(targetName, CRED_TYPE_GENERIC, 0, &cred)) {
                LPTSTR result = (LPTSTR) calloc(cred->CredentialBlobSize+1,
sizeof(TCHAR));
                memcpy(result, cred->CredentialBlob, cred->CredentialBlobSize);
                return result;
        }
        printf("CredRead failed: %d\n", GetLastError());
        return NULL;
}

int _tmain(int argc, _TCHAR* argv[])
{
        LPTSTR credential = readCredential(L"TERMSRV/devmsapps01");
        printf("Credential: %s\n", credential);
        return 0;
}
----------------------------------------------------------------------

You can imagine that it took me some ten minutes or so (incl. firing up
Visual Studio, creating a new project etc) to write this. Now do that in
Squeak and keep in mind how much of your time you're wasting in the
overhead of declaring the types, functions, defines. That's why I'm
saying that unless you can get the equivalent of #include <windows.h>
you're not even in the same ballpark.

> <sarcasm>
> Why Croquet using FFI for OpenGL binding, why not writing a plugin? It
> would be much more 'stable'
> and 'robust' and secure.
> </sarcasm>

Only one reason: The poor integration APIs. I couldn't figure out how to
generate proper plugin glue (and later I had lost the source for
generating this stufF). And we *paid* for it. Weeks and weeks of obscure
crash reports that we couldn't figure out until *finally* we realized
that when using client state operations a GC may occur if the rendering
is interrupted "just so". We fixed this by (guess what) moving these
operations into a plugin.

Cheers,
   - Andreas
Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Igor Stasenko

On 30 September 2010 04:30, Andreas Raab <[hidden email]> wrote:

>
> [Side note: Please don't quote entire posts if you're going to reply 2/3rds
> of the way down. I had to scroll three times through this post to even find
> what you replied to]
>
> On 9/29/2010 5:50 PM, Igor Stasenko wrote:
>>>
>>> 1) The "mechanics" of writing a plugin, i.e., slang and compilation. This
>>> is
>>> the part where the FFI would help, but so would better APIs for
>>> marshaling.
>>> While it's "cool" that one can run slang plugins in Squeak it is also
>>> completely and utterly *useless* when it comes to integrating platform
>>> specific stuff and having to deal with Slang, VMMaker and the awful build
>>> setups, and then -on top of that- the actual work you're trying to do is
>>> just a bit too much.
>>
>> And i am here looking for a way to make it less painful.
>> If one can make own stuff to work with OS via FFI,
>> why he needs to go into slang , VMMaker, cmake, gcc jungles?
>
> One word: Memory safety. Oh, that's two :-)
>
>> Probably, when he consider that FFI is good, but have to use more
>> safer solution,
>> then he free to go and implement plugin or change VM, whatever.
>> But for prototyping and fast implementation, FFI much better.
>
> See, in my experience that claim is simply wrong. How can you say that (for
> example) a little test program like the one that I just wrote to experiment
> with a Windows function would be faster to write using the FFI?
>
> ------------------------------ CredTest.cpp ----------------------------
>
> // CredTest.cpp : Defines the entry point for the console application.
> //
>
> #include "stdafx.h"
> #include <Windows.h>
> #include <wincred.h>
>
> LPTSTR readCredential(LPTSTR targetName) {
>        CREDENTIAL *cred;
>
>        if(CredRead(targetName, CRED_TYPE_GENERIC, 0, &cred)) {
>                LPTSTR result = (LPTSTR) calloc(cred->CredentialBlobSize+1,
> sizeof(TCHAR));
>                memcpy(result, cred->CredentialBlob,
> cred->CredentialBlobSize);
>                return result;
>        }
>        printf("CredRead failed: %d\n", GetLastError());
>        return NULL;
> }
>
> int _tmain(int argc, _TCHAR* argv[])
> {
>        LPTSTR credential = readCredential(L"TERMSRV/devmsapps01");
>        printf("Credential: %s\n", credential);
>        return 0;
> }
> ----------------------------------------------------------------------
>
> You can imagine that it took me some ten minutes or so (incl. firing up
> Visual Studio, creating a new project etc) to write this. Now do that in
> Squeak and keep in mind how much of your time you're wasting in the overhead
> of declaring the types, functions, defines. That's why I'm saying that
> unless you can get the equivalent of #include <windows.h> you're not even in
> the same ballpark.

Wait, in the above you forgot to show me the glue code which exposing
this function
via some primitive. And you forgot to write the list of steps (in
addition to opening Visual studio),
how you rebuilding VM using VMMaker , compiling and linking, and
finally deploying VM with new plugin,
and then telling others that they can download new version of VM, so
they could try your new stuff.
Now i doubt if you do that, it will take ten minutes or so.


>
>> <sarcasm>
>> Why Croquet using FFI for OpenGL binding, why not writing a plugin? It
>> would be much more 'stable'
>> and 'robust' and secure.
>> </sarcasm>
>
> Only one reason: The poor integration APIs. I couldn't figure out how to
> generate proper plugin glue (and later I had lost the source for generating
> this stufF). And we *paid* for it. Weeks and weeks of obscure crash reports
> that we couldn't figure out until *finally* we realized that when using
> client state operations a GC may occur if the rendering is interrupted "just
> so". We fixed this by (guess what) moving these operations into a plugin.
>

No objections here. Shit happens. And its really don't matters where:
either in language/FFI
or in C. You still have to fix that.

> Cheers,
>  - Andreas
>



--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Andreas.Raab
 
On 9/29/2010 6:48 PM, Igor Stasenko wrote:

> On 30 September 2010 04:30, Andreas Raab<[hidden email]>  wrote:
>> See, in my experience that claim is simply wrong. How can you say that (for
>> example) a little test program like the one that I just wrote to experiment
>> with a Windows function would be faster to write using the FFI?
>>
>> ------------------------------ CredTest.cpp ----------------------------
>>
>> // CredTest.cpp : Defines the entry point for the console application.
>> //
>>
>> #include "stdafx.h"
>> #include<Windows.h>
>> #include<wincred.h>
>>
>> LPTSTR readCredential(LPTSTR targetName) {
>>         CREDENTIAL *cred;
>>
>>         if(CredRead(targetName, CRED_TYPE_GENERIC, 0,&cred)) {
>>                 LPTSTR result = (LPTSTR) calloc(cred->CredentialBlobSize+1,
>> sizeof(TCHAR));
>>                 memcpy(result, cred->CredentialBlob,
>> cred->CredentialBlobSize);
>>                 return result;
>>         }
>>         printf("CredRead failed: %d\n", GetLastError());
>>         return NULL;
>> }
>>
>> int _tmain(int argc, _TCHAR* argv[])
>> {
>>         LPTSTR credential = readCredential(L"TERMSRV/devmsapps01");
>>         printf("Credential: %s\n", credential);
>>         return 0;
>> }
>> ----------------------------------------------------------------------
>>
>> You can imagine that it took me some ten minutes or so (incl. firing up
>> Visual Studio, creating a new project etc) to write this. Now do that in
>> Squeak and keep in mind how much of your time you're wasting in the overhead
>> of declaring the types, functions, defines. That's why I'm saying that
>> unless you can get the equivalent of #include<windows.h>  you're not even in
>> the same ballpark.
>
> Wait, in the above you forgot to show me the glue code which exposing
> this function
> via some primitive. And you forgot to write the list of steps (in
> addition to opening Visual studio),
> how you rebuilding VM using VMMaker , compiling and linking, and
> finally deploying VM with new plugin,
> and then telling others that they can download new version of VM, so
> they could try your new stuff.
> Now i doubt if you do that, it will take ten minutes or so.

But now you're complaining about the integration APIs (with which I
agree). But there is stuff we can do to make this easier, *much* easier.
If you've ever looked at how Python deals with this stuff you'll get an
idea about how easy that can be - no slang, no VMMaker, no build files
other than what is already in Visual Studio. In effect, we should be
providing a squeak.h and a squeak.lib and the primitives should look
like this:

#include <windows.h>
#include <wincred.h>
#include "squeak.h"

/* Read a credential from the Windows credential store */
OOP primitiveCredRead(VM *vm, OOP rcvr, OOP args) {
        Credentials *cred;
        char *target;

        vm->parseArgs(1, "%s", &target);
        if(!CredRead(targetName, CRED_TYPE_GENERIC, 0,&cred)) return vm->fail();
        return vm->stringWithLength(cred->CredentialBlobSize+1,
cred->CredentialBlob);
}

Voila, done.

>>> <sarcasm>
>>> Why Croquet using FFI for OpenGL binding, why not writing a plugin? It
>>> would be much more 'stable'
>>> and 'robust' and secure.
>>> </sarcasm>
>>
>> Only one reason: The poor integration APIs. I couldn't figure out how to
>> generate proper plugin glue (and later I had lost the source for generating
>> this stufF). And we *paid* for it. Weeks and weeks of obscure crash reports
>> that we couldn't figure out until *finally* we realized that when using
>> client state operations a GC may occur if the rendering is interrupted "just
>> so". We fixed this by (guess what) moving these operations into a plugin.
>
> No objections here. Shit happens. And its really don't matters where:
> either in language/FFI or in C. You still have to fix that.

It's not so much that shit happens but rather that your sarcastic
comment is *completely* wrong and (I think) goes to show how little
exposure to the resulting problems you (and pretty much everybody else
arguing for that kind of stuff) really have.

Cheers,
   - Andreas
Reply | Threaded
Open this post in threaded view
|

Re: Cog: A question about: setInterruptCheckChain()

Igor Stasenko

On 30 September 2010 11:24, Andreas Raab <[hidden email]> wrote:

>
> On 9/29/2010 6:48 PM, Igor Stasenko wrote:
>>
>> On 30 September 2010 04:30, Andreas Raab<[hidden email]>  wrote:
>>>
>>> See, in my experience that claim is simply wrong. How can you say that
>>> (for
>>> example) a little test program like the one that I just wrote to
>>> experiment
>>> with a Windows function would be faster to write using the FFI?
>>>
>>> ------------------------------ CredTest.cpp ----------------------------
>>>
>>> // CredTest.cpp : Defines the entry point for the console application.
>>> //
>>>
>>> #include "stdafx.h"
>>> #include<Windows.h>
>>> #include<wincred.h>
>>>
>>> LPTSTR readCredential(LPTSTR targetName) {
>>>        CREDENTIAL *cred;
>>>
>>>        if(CredRead(targetName, CRED_TYPE_GENERIC, 0,&cred)) {
>>>                LPTSTR result = (LPTSTR)
>>> calloc(cred->CredentialBlobSize+1,
>>> sizeof(TCHAR));
>>>                memcpy(result, cred->CredentialBlob,
>>> cred->CredentialBlobSize);
>>>                return result;
>>>        }
>>>        printf("CredRead failed: %d\n", GetLastError());
>>>        return NULL;
>>> }
>>>
>>> int _tmain(int argc, _TCHAR* argv[])
>>> {
>>>        LPTSTR credential = readCredential(L"TERMSRV/devmsapps01");
>>>        printf("Credential: %s\n", credential);
>>>        return 0;
>>> }
>>> ----------------------------------------------------------------------
>>>
>>> You can imagine that it took me some ten minutes or so (incl. firing up
>>> Visual Studio, creating a new project etc) to write this. Now do that in
>>> Squeak and keep in mind how much of your time you're wasting in the
>>> overhead
>>> of declaring the types, functions, defines. That's why I'm saying that
>>> unless you can get the equivalent of #include<windows.h>  you're not even
>>> in
>>> the same ballpark.
>>
>> Wait, in the above you forgot to show me the glue code which exposing
>> this function
>> via some primitive. And you forgot to write the list of steps (in
>> addition to opening Visual studio),
>> how you rebuilding VM using VMMaker , compiling and linking, and
>> finally deploying VM with new plugin,
>> and then telling others that they can download new version of VM, so
>> they could try your new stuff.
>> Now i doubt if you do that, it will take ten minutes or so.
>
> But now you're complaining about the integration APIs (with which I agree).
> But there is stuff we can do to make this easier, *much* easier. If you've
> ever looked at how Python deals with this stuff you'll get an idea about how
> easy that can be - no slang, no VMMaker, no build files other than what is
> already in Visual Studio. In effect, we should be providing a squeak.h and a
> squeak.lib and the primitives should look like this:
>
> #include <windows.h>
> #include <wincred.h>
> #include "squeak.h"
>
> /* Read a credential from the Windows credential store */
> OOP primitiveCredRead(VM *vm, OOP rcvr, OOP args) {
>        Credentials *cred;
>        char *target;
>
>        vm->parseArgs(1, "%s", &target);
>        if(!CredRead(targetName, CRED_TYPE_GENERIC, 0,&cred)) return
> vm->fail();
>        return vm->stringWithLength(cred->CredentialBlobSize+1,
> cred->CredentialBlob);
> }
>
> Voila, done.
>

Yep. Been there , did that :)
I had implemented own automatic code generator which generated
bindings for my abandoned smalltalk interpreter.
I used SWIG C++ compiler by writing own plugin to it.
So, what is stopping us from either use SWIG, or write own C/C++
parser/compiler for automatic
generation of external library bindings?


>>>> <sarcasm>
>>>> Why Croquet using FFI for OpenGL binding, why not writing a plugin? It
>>>> would be much more 'stable'
>>>> and 'robust' and secure.
>>>> </sarcasm>
>>>
>>> Only one reason: The poor integration APIs. I couldn't figure out how to
>>> generate proper plugin glue (and later I had lost the source for
>>> generating
>>> this stufF). And we *paid* for it. Weeks and weeks of obscure crash
>>> reports
>>> that we couldn't figure out until *finally* we realized that when using
>>> client state operations a GC may occur if the rendering is interrupted
>>> "just
>>> so". We fixed this by (guess what) moving these operations into a plugin.
>>
>> No objections here. Shit happens. And its really don't matters where:
>> either in language/FFI or in C. You still have to fix that.
>
> It's not so much that shit happens but rather that your sarcastic comment is
> *completely* wrong and (I think) goes to show how little exposure to the
> resulting problems you (and pretty much everybody else arguing for that kind
> of stuff) really have.
>

Oh, please. I worked more than 2 years on single big C++ project, in
Visual Studio.
STL, templates, threads, 10 minutes of compilation time, incredibly
hard to move ahead,
incredibly hard to reproduce errors (since after 'fix' you were always
had to restart program and
repeat all steps which may possibly triggered bug). I am sick of C, really sick.
If it would be so easy to develop in C, then no one (including me)
would even look into smalltalk direction.


> Cheers,
>  - Andreas
>



--
Best regards,
Igor Stasenko AKA sig.
12