FFI pinning examples?

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

FFI pinning examples?

Phil B
I remember reading a while back that Spur added memory pinning and was curious if any Squeak packages has made use of it yet? (Looking for an example or two to get me started)


Reply | Threaded
Open this post in threaded view
|

Re: FFI pinning examples?

Eliot Miranda-2
Hi Phil,

On Thu, Aug 24, 2017 at 1:36 PM, Phil B <[hidden email]> wrote:
I remember reading a while back that Spur added memory pinning and was curious if any Squeak packages has made use of it yet? (Looking for an example or two to get me started)

The protocol i in Object, with the selectors pin, unpin and isPinned.  You can send any of these to any non-immediate object.  It is your responsibility to avoid calling unpin until external code no longer holds references to any pinned object.  It is your responsibility to arrange that the objects are still accessible within the system so that they are not GCed while external code holds onto them.  Pinning is orthogonal to GC.  It prevents the GC from moving objects, but does not prevent them from being GCed if no references to them exist in the Smalltalk system.  Note that also pinning may cause an object to move from newSpace to oldSpace, as objects are only pinball in oldSpace.  Pinning a new object causes it to become a copy of the object in oldSpace, so do not pass an object to external code and then pin it; it may move.

 So the idea is
- create some objects you want to share with external code and pin them
- pass them to that external code through the FFI
- allow that external code to run (e.g spawn a thread in the external code, or make subsequent call though the FFI exercise the code)
- shut down the external code
- unpin your objects, or merely allow them to be GCed.

Alternatively external code can pin the objects it is given, providing it updates their location afterwards.  See pinObject:.

Note that you should use the interpreterProxy accessors firstIndexableField: and firstFixedField: to find out the start of the body of an object (pinned or otherwise).  byteSizeOf:, instanceSizeOf:, slotSizeOf: and stSizeOf: can all be used to find out various sizes.  See platforms/Cross/vm/sqVirtualMachine.h, which also provides pinObject: and unpinObject:.

Clearly some work is needed to add documentation in the right places.  LMK where you looked, where you would expect to find such information, etc.
--
_,,,^..^,,,_
best, Eliot


Reply | Threaded
Open this post in threaded view
|

Re: FFI pinning examples?

Phil B
Eliot,

That sounds very straightforward and logical.  I had only taken a quick glance in a recent image and didn't notice anything obvious in FFI so I thought I'd just ask before going further.

Thanks for the tip re: making sure to keep a reference in the image to avoid gc as I'm sure that would have bitten me at some point since my plan is to try creating some reusable buffers see if I can speed up some things re: text and image processing. (i.e. I might not have thought to hang onto it once it had been passed to FFI which I'm sure would not have been fun to track down)

Also just FYI, I'm also looking forward to your threaded FFI work as I'm hoping to be able to create a persistent rendering thread for OpenGL (this could be a performance gain of up to 80-90% for heavy rendering code) which should also benefit from pinning.

Thanks,
Phil


On Aug 24, 2017 6:06 PM, "Eliot Miranda" <[hidden email]> wrote:
Hi Phil,

On Thu, Aug 24, 2017 at 1:36 PM, Phil B <[hidden email]> wrote:
I remember reading a while back that Spur added memory pinning and was curious if any Squeak packages has made use of it yet? (Looking for an example or two to get me started)

The protocol i in Object, with the selectors pin, unpin and isPinned.  You can send any of these to any non-immediate object.  It is your responsibility to avoid calling unpin until external code no longer holds references to any pinned object.  It is your responsibility to arrange that the objects are still accessible within the system so that they are not GCed while external code holds onto them.  Pinning is orthogonal to GC.  It prevents the GC from moving objects, but does not prevent them from being GCed if no references to them exist in the Smalltalk system.  Note that also pinning may cause an object to move from newSpace to oldSpace, as objects are only pinball in oldSpace.  Pinning a new object causes it to become a copy of the object in oldSpace, so do not pass an object to external code and then pin it; it may move.

 So the idea is
- create some objects you want to share with external code and pin them
- pass them to that external code through the FFI
- allow that external code to run (e.g spawn a thread in the external code, or make subsequent call though the FFI exercise the code)
- shut down the external code
- unpin your objects, or merely allow them to be GCed.

Alternatively external code can pin the objects it is given, providing it updates their location afterwards.  See pinObject:.

Note that you should use the interpreterProxy accessors firstIndexableField: and firstFixedField: to find out the start of the body of an object (pinned or otherwise).  byteSizeOf:, instanceSizeOf:, slotSizeOf: and stSizeOf: can all be used to find out various sizes.  See platforms/Cross/vm/sqVirtualMachine.h, which also provides pinObject: and unpinObject:.

Clearly some work is needed to add documentation in the right places.  LMK where you looked, where you would expect to find such information, etc.
--
_,,,^..^,,,_
best, Eliot






Reply | Threaded
Open this post in threaded view
|

Re: FFI pinning examples?

Ben Coman
In reply to this post by Eliot Miranda-2


On Fri, Aug 25, 2017 at 6:06 AM, Eliot Miranda <[hidden email]> wrote:
Hi Phil,

On Thu, Aug 24, 2017 at 1:36 PM, Phil B <[hidden email]> wrote:
I remember reading a while back that Spur added memory pinning and was curious if any Squeak packages has made use of it yet? (Looking for an example or two to get me started)

The protocol i in Object, with the selectors pin, unpin and isPinned.  You can send any of these to any non-immediate object.  It is your responsibility to avoid calling unpin until external code no longer holds references to any pinned object.  It is your responsibility to arrange that the objects are still accessible within the system so that they are not GCed while external code holds onto them.  Pinning is orthogonal to GC.  It prevents the GC from moving objects, but does not prevent them from being GCed if no references to them exist in the Smalltalk system.  Note that also pinning may cause an object to move from newSpace to oldSpace, as objects are only pinball in oldSpace.  Pinning a new object causes it to become a copy of the object in oldSpace, so do not pass an object to external code and then pin it; it may move.

 So the idea is
- create some objects you want to share with external code and pin them
- pass them to that external code through the FFI
- allow that external code to run (e.g spawn a thread in the external code, or make subsequent call though the FFI exercise the code)
- shut down the external code
- unpin your objects, or merely allow them to be GCed.

Alternatively external code can pin the objects it is given, providing it updates their location afterwards.  See pinObject:.

Sorry I haven't looked at the implementation (and no Image near me right now) but a random query crosses my mind,
does/can the function called externally return the new location, rather than having to do this in two steps.
This might help ensure people are aware the new address should be dealt with.

cheers -ben
 

Note that you should use the interpreterProxy accessors firstIndexableField: and firstFixedField: to find out the start of the body of an object (pinned or otherwise).  byteSizeOf:, instanceSizeOf:, slotSizeOf: and stSizeOf: can all be used to find out various sizes.  See platforms/Cross/vm/sqVirtualMachine.h, which also provides pinObject: and unpinObject:.

Clearly some work is needed to add documentation in the right places.  LMK where you looked, where you would expect to find such information, etc.
--
_,,,^..^,,,_
best, Eliot






Reply | Threaded
Open this post in threaded view
|

Re: FFI pinning examples?

Hannes Hirzel
What is memory pinning and when would I want to use it?

--Hannes

On 8/25/17, Ben Coman <[hidden email]> wrote:

> On Fri, Aug 25, 2017 at 6:06 AM, Eliot Miranda <[hidden email]>
> wrote:
>
>> Hi Phil,
>>
>> On Thu, Aug 24, 2017 at 1:36 PM, Phil B <[hidden email]> wrote:
>>
>>> I remember reading a while back that Spur added memory pinning and was
>>> curious if any Squeak packages has made use of it yet? (Looking for an
>>> example or two to get me started)
>>>
>>
>> The protocol i in Object, with the selectors pin, unpin and isPinned.
>> You
>> can send any of these to any non-immediate object.  It is your
>> responsibility to avoid calling unpin until external code no longer holds
>> references to any pinned object.  It is your responsibility to arrange
>> that
>> the objects are still accessible within the system so that they are not
>> GCed while external code holds onto them.  Pinning is orthogonal to GC.
>> It
>> prevents the GC from moving objects, but does not prevent them from being
>> GCed if no references to them exist in the Smalltalk system.  Note that
>> also pinning may cause an object to move from newSpace to oldSpace, as
>> objects are only pinball in oldSpace.  Pinning a new object causes it to
>> become a copy of the object in oldSpace, so do not pass an object to
>> external code and then pin it; it may move.
>>
>>  So the idea is
>> - create some objects you want to share with external code and pin them
>> - pass them to that external code through the FFI
>> - allow that external code to run (e.g spawn a thread in the external
>> code, or make subsequent call though the FFI exercise the code)
>> - shut down the external code
>> - unpin your objects, or merely allow them to be GCed.
>>
>> Alternatively external code can pin the objects it is given, providing it
>> updates their location afterwards.  See pinObject:.
>>
>
> Sorry I haven't looked at the implementation (and no Image near me right
> now) but a random query crosses my mind,
> does/can the function called externally return the new location, rather
> than having to do this in two steps.
> This might help ensure people are aware the new address should be dealt
> with.
>
> cheers -ben
>
>
>>
>> Note that you should use the interpreterProxy accessors
>> firstIndexableField: and firstFixedField: to find out the start of the
>> body
>> of an object (pinned or otherwise).  byteSizeOf:, instanceSizeOf:,
>> slotSizeOf: and stSizeOf: can all be used to find out various sizes.  See
>> platforms/Cross/vm/sqVirtualMachine.h, which also provides pinObject: and
>> unpinObject:.
>>
>> Clearly some work is needed to add documentation in the right places.
>> LMK
>> where you looked, where you would expect to find such information, etc.
>> --
>> _,,,^..^,,,_
>> best, Eliot
>>
>>
>>
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: FFI pinning examples?

Eliot Miranda-2
In reply to this post by Ben Coman
Hi Ben,



_,,,^..^,,,_ (phone)
On Aug 24, 2017, at 9:53 PM, Ben Coman <[hidden email]> wrote:



On Fri, Aug 25, 2017 at 6:06 AM, Eliot Miranda <[hidden email]> wrote:
Hi Phil,

On Thu, Aug 24, 2017 at 1:36 PM, Phil B <[hidden email]> wrote:
I remember reading a while back that Spur added memory pinning and was curious if any Squeak packages has made use of it yet? (Looking for an example or two to get me started)

The protocol i in Object, with the selectors pin, unpin and isPinned.  You can send any of these to any non-immediate object.  It is your responsibility to avoid calling unpin until external code no longer holds references to any pinned object.  It is your responsibility to arrange that the objects are still accessible within the system so that they are not GCed while external code holds onto them.  Pinning is orthogonal to GC.  It prevents the GC from moving objects, but does not prevent them from being GCed if no references to them exist in the Smalltalk system.  Note that also pinning may cause an object to move from newSpace to oldSpace, as objects are only pinball in oldSpace.  Pinning a new object causes it to become a copy of the object in oldSpace, so do not pass an object to external code and then pin it; it may move.

 So the idea is
- create some objects you want to share with external code and pin them
- pass them to that external code through the FFI
- allow that external code to run (e.g spawn a thread in the external code, or make subsequent call though the FFI exercise the code)
- shut down the external code
- unpin your objects, or merely allow them to be GCed.

Alternatively external code can pin the objects it is given, providing it updates their location afterwards.  See pinObject:.

Sorry I haven't looked at the implementation (and no Image near me right now) but a random query crosses my mind,
does/can the function called externally return the new location, rather than having to do this in two steps.
This might help ensure people are aware the new address should be dealt with.

Right.  pinObject: either answers the possibly moved oop of the pinned object or answers 0 if the pinning attempt failed.  So one can indeed do things in one step. 


cheers -ben
 

Note that you should use the interpreterProxy accessors firstIndexableField: and firstFixedField: to find out the start of the body of an object (pinned or otherwise).  byteSizeOf:, instanceSizeOf:, slotSizeOf: and stSizeOf: can all be used to find out various sizes.  See platforms/Cross/vm/sqVirtualMachine.h, which also provides pinObject: and unpinObject:.

Clearly some work is needed to add documentation in the right places.  LMK where you looked, where you would expect to find such information, etc.
--
_,,,^..^,,,_
best, Eliot







Reply | Threaded
Open this post in threaded view
|

Re: FFI pinning examples?

Eliot Miranda-2
In reply to this post by Hannes Hirzel
Hi Hannes,

> On Aug 25, 2017, at 1:47 AM, H. Hirzel <[hidden email]> wrote:
>
> What is memory pinning and when would I want to use it?

Pinning is the ability to tell the garbage collector not to move a specific object.  The GC moves objects when it scavenges surviving objects in new space (garbageCollectMost) and when it compacts old space as part of a "full GC" (garbageCollect).  If an object is pinned the GC arranges that the object is in old space, using a become if required, and sets the pinned flag bit in the object's header. The compactor then moves only unpinned objects, leaving pinned objects where they are.

Pinning is useful for passing objects to external code, for example to use as a buffer for copying data between Smalltalk and external code.  Since pinned objects don't move the external code can simply hold onto the address of the start of the object's body and write into the object, instead of having to track the object via a handle that points to a possibly moving object.

>
> --Hannes
>
>> On 8/25/17, Ben Coman <[hidden email]> wrote:
>> On Fri, Aug 25, 2017 at 6:06 AM, Eliot Miranda <[hidden email]>
>> wrote:
>>
>>> Hi Phil,
>>>
>>>> On Thu, Aug 24, 2017 at 1:36 PM, Phil B <[hidden email]> wrote:
>>>>
>>>> I remember reading a while back that Spur added memory pinning and was
>>>> curious if any Squeak packages has made use of it yet? (Looking for an
>>>> example or two to get me started)
>>>>
>>>
>>> The protocol i in Object, with the selectors pin, unpin and isPinned.
>>> You
>>> can send any of these to any non-immediate object.  It is your
>>> responsibility to avoid calling unpin until external code no longer holds
>>> references to any pinned object.  It is your responsibility to arrange
>>> that
>>> the objects are still accessible within the system so that they are not
>>> GCed while external code holds onto them.  Pinning is orthogonal to GC.
>>> It
>>> prevents the GC from moving objects, but does not prevent them from being
>>> GCed if no references to them exist in the Smalltalk system.  Note that
>>> also pinning may cause an object to move from newSpace to oldSpace, as
>>> objects are only pinball in oldSpace.  Pinning a new object causes it to
>>> become a copy of the object in oldSpace, so do not pass an object to
>>> external code and then pin it; it may move.
>>>
>>> So the idea is
>>> - create some objects you want to share with external code and pin them
>>> - pass them to that external code through the FFI
>>> - allow that external code to run (e.g spawn a thread in the external
>>> code, or make subsequent call though the FFI exercise the code)
>>> - shut down the external code
>>> - unpin your objects, or merely allow them to be GCed.
>>>
>>> Alternatively external code can pin the objects it is given, providing it
>>> updates their location afterwards.  See pinObject:.
>>>
>>
>> Sorry I haven't looked at the implementation (and no Image near me right
>> now) but a random query crosses my mind,
>> does/can the function called externally return the new location, rather
>> than having to do this in two steps.
>> This might help ensure people are aware the new address should be dealt
>> with.
>>
>> cheers -ben
>>
>>
>>>
>>> Note that you should use the interpreterProxy accessors
>>> firstIndexableField: and firstFixedField: to find out the start of the
>>> body
>>> of an object (pinned or otherwise).  byteSizeOf:, instanceSizeOf:,
>>> slotSizeOf: and stSizeOf: can all be used to find out various sizes.  See
>>> platforms/Cross/vm/sqVirtualMachine.h, which also provides pinObject: and
>>> unpinObject:.
>>>
>>> Clearly some work is needed to add documentation in the right places.
>>> LMK
>>> where you looked, where you would expect to find such information, etc.
>>> --
>>> _,,,^..^,,,_
>>> best, Eliot
>>>
>>>
>>>
>>>
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: FFI pinning examples?

Hannes Hirzel
Thank you, Eliot, for the explanation.

I understand that 'memory pinning' was introduced with the 'Spur VM'

Squeak 5.0 Release Notes, 17th August 2015
http://wiki.squeak.org/squeak/6207

On 8/25/17, Eliot Miranda <[hidden email]> wrote:

> Hi Hannes,
>
>> On Aug 25, 2017, at 1:47 AM, H. Hirzel <[hidden email]> wrote:
>>
>> What is memory pinning and when would I want to use it?
>
> Pinning is the ability to tell the garbage collector not to move a specific
> object.  The GC moves objects when it scavenges surviving objects in new
> space (garbageCollectMost) and when it compacts old space as part of a "full
> GC" (garbageCollect).  If an object is pinned the GC arranges that the
> object is in old space, using a become if required, and sets the pinned flag
> bit in the object's header. The compactor then moves only unpinned objects,
> leaving pinned objects where they are.
>
> Pinning is useful for passing objects to external code, for example to use
> as a buffer for copying data between Smalltalk and external code.  Since
> pinned objects don't move the external code can simply hold onto the address
> of the start of the object's body and write into the object, instead of
> having to track the object via a handle that points to a possibly moving
> object.
>
>>
>> --Hannes
>>
>>> On 8/25/17, Ben Coman <[hidden email]> wrote:
>>> On Fri, Aug 25, 2017 at 6:06 AM, Eliot Miranda <[hidden email]>
>>> wrote:
>>>
>>>> Hi Phil,
>>>>
>>>>> On Thu, Aug 24, 2017 at 1:36 PM, Phil B <[hidden email]> wrote:
>>>>>
>>>>> I remember reading a while back that Spur added memory pinning and was
>>>>> curious if any Squeak packages has made use of it yet? (Looking for an
>>>>> example or two to get me started)
>>>>>
>>>>
>>>> The protocol i in Object, with the selectors pin, unpin and isPinned.
>>>> You
>>>> can send any of these to any non-immediate object.  It is your
>>>> responsibility to avoid calling unpin until external code no longer
>>>> holds
>>>> references to any pinned object.  It is your responsibility to arrange
>>>> that
>>>> the objects are still accessible within the system so that they are not
>>>> GCed while external code holds onto them.  Pinning is orthogonal to GC.
>>>> It
>>>> prevents the GC from moving objects, but does not prevent them from
>>>> being
>>>> GCed if no references to them exist in the Smalltalk system.  Note that
>>>> also pinning may cause an object to move from newSpace to oldSpace, as
>>>> objects are only pinball in oldSpace.  Pinning a new object causes it to
>>>> become a copy of the object in oldSpace, so do not pass an object to
>>>> external code and then pin it; it may move.
>>>>
>>>> So the idea is
>>>> - create some objects you want to share with external code and pin them
>>>> - pass them to that external code through the FFI
>>>> - allow that external code to run (e.g spawn a thread in the external
>>>> code, or make subsequent call though the FFI exercise the code)
>>>> - shut down the external code
>>>> - unpin your objects, or merely allow them to be GCed.
>>>>
>>>> Alternatively external code can pin the objects it is given, providing
>>>> it
>>>> updates their location afterwards.  See pinObject:.
>>>>
>>>
>>> Sorry I haven't looked at the implementation (and no Image near me right
>>> now) but a random query crosses my mind,
>>> does/can the function called externally return the new location, rather
>>> than having to do this in two steps.
>>> This might help ensure people are aware the new address should be dealt
>>> with.
>>>
>>> cheers -ben
>>>
>>>
>>>>
>>>> Note that you should use the interpreterProxy accessors
>>>> firstIndexableField: and firstFixedField: to find out the start of the
>>>> body
>>>> of an object (pinned or otherwise).  byteSizeOf:, instanceSizeOf:,
>>>> slotSizeOf: and stSizeOf: can all be used to find out various sizes.
>>>> See
>>>> platforms/Cross/vm/sqVirtualMachine.h, which also provides pinObject:
>>>> and
>>>> unpinObject:.
>>>>
>>>> Clearly some work is needed to add documentation in the right places.
>>>> LMK
>>>> where you looked, where you would expect to find such information, etc.
>>>> --
>>>> _,,,^..^,,,_
>>>> best, Eliot
>>>>
>>>>
>>>>
>>>>
>>>
>>
>
>