How to ensure D code that interoperates with external libraries will work when a moving gc is eventually used with D? Will i need to add lots of pinning/unpinning code? extern(C) external(Foo* foo); struct Foo { } class Bar { Foo foo; } main() { Foo* foo = new Foo(); // Should foo be pinned before the call? external(foo); Bar bar = new Bar(); // Should bar be pinned before the call? external(&bar.foo); } btw, ares seems to provides a moving gc and does have a gc.pin method. Should i consider looking closer at ares? Thanks
Max Samuha wrote: How to ensure D code that interoperates with external libraries will work when a moving gc is eventually used with D? Will i need to add lots of pinning/unpinning code? extern(C) external(Foo* foo); struct Foo { } class Bar { Foo foo; } main() { Foo* foo = new Foo(); // Should foo be pinned before the call? external(foo); Bar bar = new Bar(); // Should bar be pinned before the call? external(&bar.foo); } btw, ares seems to provides a moving gc and does have a gc.pin method. Should i consider looking closer at ares? Thanks The GC in Ares is currently the same as the one in Phobos, but the interface in Ares should make it possible to easier switch between other types of GC's. -- Lars Ivar Igesund blog at http://larsivi.net DSource & #D: larsivi
Typically, garbage collectors run only on memory allocation/deallocation/similar. They won't run in the middle of a foreign program... unless it's threaded, then all bets are off. -[Unknown] How to ensure D code that interoperates with external libraries will work when a moving gc is eventually used with D? Will i need to add lots of pinning/unpinning code? extern(C) external(Foo* foo); struct Foo { } class Bar { Foo foo; } main() { Foo* foo = new Foo(); // Should foo be pinned before the call? external(foo); Bar bar = new Bar(); // Should bar be pinned before the call? external(&bar.foo); } btw, ares seems to provides a moving gc and does have a gc.pin method. Should i consider looking closer at ares? Thanks
On 2006年6月03日 11:09:56 -0700, "Unknown W. Brackets" <unknown simplemachines.org> wrote: Typically, garbage collectors run only on memory allocation/deallocation/similar. They won't run in the middle of a foreign program... unless it's threaded, then all bets are off. -[Unknown] Thank you for prompt replies. Most programs will run more than one thread, so it is not guaranteed that garbage collection will not be triggered when control is in external code. What's the best way to ensure that the pointers are valid until control is returned to D code? version (MovingGC/Ares/whatever) { gc.pin(foo); } external(foo); version (MovingGC/Ares/whatever) { gc.unpin(foo); } that's no good. D claims it is compatible with C code but it cannot be true unless either the specs require that D use only non-moving garbage collector or there is a standard way to ensure that pointers to garbage collected memory passed to external functions remain valid while control is in external code. please correct me if i missed something. sorry for my poor English
Typically, garbage collectors run only on memory allocation/deallocation/similar. They won't run in the middle of a foreign program... unless it's threaded, then all bets are off. -[Unknown]
Well, you are correct that you need to do this for threaded code interfacing with C functions via pointers. That doesn't mean D can't interface with C code properly, just that it might not properly do it, necessarily, under this circumstance. The truth of the matter is, D is still in development, and so is the standard library. This is something that has not yet been provided for, you are right. But, as yet, no D implementation uses a compacting GC. I would suggest that a compiler that adds a compacting GC in could, theoretically, detect the passing of a pointer to a C function, and automatically "pin" it before the call. Unpinning it afterward does not seem practical. Another option would be to declare the variable which holds the pointer as extern (C). This could be a clear indication to the compiler that this pointer should not be moved. However, the above solutions may indeed be impractical. More thought will be needed, and this thought will no doubt come from Walter. This is why, as I said, D is still in an alpha stage. Even so, I would personally just make a note near the affected area, e.g.: // !!! Passing a pointer to C. Or however you prefer to make such notes in your convention; possibly noting this specifically as something to check on whenever a new compiler is used. It may very well be that gc.pin() and gc.unpin() functions will be added to Phobos, in which case you will need to go through these areas and make the changes - just as I had to do with my code when on_scope_success was changed to scope (success), and when === was changed to is. It may seem like a pain, but the changes are typically minor, and the benefits I see from programming in D vs. C/C++ still far outweigh these problems. I cannot predict if it's the same for you, of course. I'm American, so I may have to ask you to forgive me my poor English as well. Yours is as good as mine, whether that's a compliment or an insult. -[Unknown] Thank you for prompt replies. Most programs will run more than one thread, so it is not guaranteed that garbage collection will not be triggered when control is in external code. What's the best way to ensure that the pointers are valid until control is returned to D code? version (MovingGC/Ares/whatever) { gc.pin(foo); } external(foo); version (MovingGC/Ares/whatever) { gc.unpin(foo); } that's no good. D claims it is compatible with C code but it cannot be true unless either the specs require that D use only non-moving garbage collector or there is a standard way to ensure that pointers to garbage collected memory passed to external functions remain valid while control is in external code. please correct me if i missed something. sorry for my poor English
Thank you for prompt replies. Most programs will run more than one thread, so it is not guaranteed that garbage collection will not be triggered when control is in external code. What's the best way to ensure that the pointers are valid until control is returned to D code? version (MovingGC/Ares/whatever) { gc.pin(foo); } external(foo); version (MovingGC/Ares/whatever) { gc.unpin(foo); } that's no good. D claims it is compatible with C code but it cannot be true unless either the specs require that D use only non-moving garbage collector or there is a standard way to ensure that pointers to garbage collected memory passed to external functions remain valid while control is in external code. please correct me if i missed something. sorry for my poor English
On 2006年6月03日 17:06:03 -0700, "Unknown W. Brackets" <unknown simplemachines.org> wrote: Well, you are correct that you need to do this for threaded code interfacing with C functions via pointers. That doesn't mean D can't interface with C code properly, just that it might not properly do it, necessarily, under this circumstance. The truth of the matter is, D is still in development, and so is the standard library. This is something that has not yet been provided for, you are right. But, as yet, no D implementation uses a compacting GC. I would suggest that a compiler that adds a compacting GC in could, theoretically, detect the passing of a pointer to a C function, and automatically "pin" it before the call. Unpinning it afterward does not seem practical. Another option would be to declare the variable which holds the pointer as extern (C). This could be a clear indication to the compiler that this pointer should not be moved. However, the above solutions may indeed be impractical. More thought will be needed, and this thought will no doubt come from Walter. This is why, as I said, D is still in an alpha stage. Even so, I would personally just make a note near the affected area, e.g.: // !!! Passing a pointer to C. Or however you prefer to make such notes in your convention; possibly noting this specifically as something to check on whenever a new compiler is used. It may very well be that gc.pin() and gc.unpin() functions will be added to Phobos, in which case you will need to go through these areas and make the changes - just as I had to do with my code when on_scope_success was changed to scope (success), and when === was changed to is. It may seem like a pain, but the changes are typically minor, and the benefits I see from programming in D vs. C/C++ still far outweigh these problems. I cannot predict if it's the same for you, of course. I'm American, so I may have to ask you to forgive me my poor English as well. Yours is as good as mine, whether that's a compliment or an insult. -[Unknown] Thank you for the extensive explanation! Marking my code with '// !!! Passing a pointer to C.' is what i've been doing recently:) and it seems the best solution for now until ares is mature or phobos has pin/unpin, or pointers passed to C are pinned implicitly.
Well, you are correct that you need to do this for threaded code interfacing with C functions via pointers. That doesn't mean D can't interface with C code properly, just that it might not properly do it, necessarily, under this circumstance. The truth of the matter is, D is still in development, and so is the standard library. This is something that has not yet been provided for, you are right. But, as yet, no D implementation uses a compacting GC. I would suggest that a compiler that adds a compacting GC in could, theoretically, detect the passing of a pointer to a C function, and automatically "pin" it before the call. Unpinning it afterward does not seem practical. Another option would be to declare the variable which holds the pointer as extern (C). This could be a clear indication to the compiler that this pointer should not be moved. However, the above solutions may indeed be impractical. More thought will be needed, and this thought will no doubt come from Walter. This is why, as I said, D is still in an alpha stage. Even so, I would personally just make a note near the affected area, e.g.: // !!! Passing a pointer to C. Or however you prefer to make such notes in your convention; possibly noting this specifically as something to check on whenever a new compiler is used. It may very well be that gc.pin() and gc.unpin() functions will be added to Phobos, in which case you will need to go through these areas and make the changes - just as I had to do with my code when on_scope_success was changed to scope (success), and when === was changed to is. It may seem like a pain, but the changes are typically minor, and the benefits I see from programming in D vs. C/C++ still far outweigh these problems. I cannot predict if it's the same for you, of course. I'm American, so I may have to ask you to forgive me my poor English as well. Yours is as good as mine, whether that's a compliment or an insult. -[Unknown]
Max Samuha wrote: Thank you for the extensive explanation! Marking my code with '// !!! Passing a pointer to C.' is what i've been doing recently:) and it seems the best solution for now until ares is mature or phobos has pin/unpin, or pointers passed to C are pinned implicitly. They will be pinned implicitly, no need to call pin/unpin. The only time you're going to have a problem is if the C routine hides the pointer in a malloc'd buffer where the gc won't see it. The gc *will* see pointers on the C stack.
Thank you for the extensive explanation! Marking my code with '// !!! Passing a pointer to C.' is what i've been doing recently:) and it seems the best solution for now until ares is mature or phobos has pin/unpin, or pointers passed to C are pinned implicitly.
Walter Bright wrote: Max Samuha wrote: Thank you for the extensive explanation! Marking my code with '// !!! Passing a pointer to C.' is what i've been doing recently:) and it seems the best solution for now until ares is mature or phobos has pin/unpin, or pointers passed to C are pinned implicitly. They will be pinned implicitly, no need to call pin/unpin. The only time you're going to have a problem is if the C routine hides the pointer in a malloc'd buffer where the gc won't see it. The gc *will* see pointers on the C stack. Would it remain pinned indefinitely, until the C function exits, or until the program explicitly unpins it by some means? Stewart.
Stewart Gordon wrote: Walter Bright wrote: Max Samuha wrote: Thank you for the extensive explanation! Marking my code with '// !!! Passing a pointer to C.' is what i've been doing recently:) and it seems the best solution for now until ares is mature or phobos has pin/unpin, or pointers passed to C are pinned implicitly. They will be pinned implicitly, no need to call pin/unpin. The only time you're going to have a problem is if the C routine hides the pointer in a malloc'd buffer where the gc won't see it. The gc *will* see pointers on the C stack. Would it remain pinned indefinitely, until the C function exits, or until the program explicitly unpins it by some means? It's pinned because it's on the stack, just like pointers on the stack for your D functions. The gc doesn't know the difference.
Walter Bright wrote: Max Samuha wrote: Thank you for the extensive explanation! Marking my code with '// !!! Passing a pointer to C.' is what i've been doing recently:) and it seems the best solution for now until ares is mature or phobos has pin/unpin, or pointers passed to C are pinned implicitly. They will be pinned implicitly, no need to call pin/unpin. The only time you're going to have a problem is if the C routine hides the pointer in a malloc'd buffer where the gc won't see it. The gc *will* see pointers on the C stack. Would it remain pinned indefinitely, until the C function exits, or until the program explicitly unpins it by some means?
Of course, how foolish of me - so there's no worry about the garbage collector killing that in a threaded program either. Duh. -[Unknown] In article <e679ot7ドルe31ドル digitaldaemon.com>, Walter Bright says... Stewart Gordon wrote: Would it remain pinned indefinitely, until the C function exits, or until the program explicitly unpins it by some means? It's pinned because it's on the stack, just like pointers on the stack for your D functions. The gc doesn't know the difference.
Stewart Gordon wrote: Would it remain pinned indefinitely, until the C function exits, or until the program explicitly unpins it by some means? It's pinned because it's on the stack, just like pointers on the stack for your D functions. The gc doesn't know the difference.
Would it remain pinned indefinitely, until the C function exits, or until the program explicitly unpins it by some means?
On Wed, 7 Jun 2006 22:11:52 +0000 (UTC), Unknown W. Brackets <Unknown_member pathlink.com> wrote: Of course, how foolish of me - so there's no worry about the garbage collector killing that in a threaded program either. Duh. -[Unknown] In article <e679ot7ドルe31ドル digitaldaemon.com>, Walter Bright says... Stewart Gordon wrote: Would it remain pinned indefinitely, until the C function exits, or until the program explicitly unpins it by some means? It's pinned because it's on the stack, just like pointers on the stack for your D functions. The gc doesn't know the difference. Thanks. It seems I can live with that for now. i can't help saying D is very addictive. imho, the best C-like language i've had a chance to try.
Walter Bright wrote: Stewart Gordon wrote: <snip> Would it remain pinned indefinitely, until the C function exits, or until the program explicitly unpins it by some means? It's pinned because it's on the stack, just like pointers on the stack for your D functions. The gc doesn't know the difference. But what if the foreign code needs to hold onto the pointer for longer than it can remain on the stack? Stewart.
Stewart Gordon wrote:
Would it remain pinned indefinitely, until the C function exits, or until the program explicitly unpins it by some means? It's pinned because it's on the stack, just like pointers on the stack for your D functions. The gc doesn't know the difference.
Stewart Gordon wrote: Walter Bright wrote: Stewart Gordon wrote: <snip> Would it remain pinned indefinitely, until the C function exits, or until the program explicitly unpins it by some means? It's pinned because it's on the stack, just like pointers on the stack for your D functions. The gc doesn't know the difference. But what if the foreign code needs to hold onto the pointer for longer than it can remain on the stack? Have the D caller code keep a copy, or use addRoots to tell the gc where the foreign code is holding it.
Walter Bright wrote: Stewart Gordon wrote: <snip> Would it remain pinned indefinitely, until the C function exits, or until the program explicitly unpins it by some means? It's pinned because it's on the stack, just like pointers on the stack for your D functions. The gc doesn't know the difference. But what if the foreign code needs to hold onto the pointer for longer than it can remain on the stack?
But the question is for a "moving" GC, which might not consider a local reference to mean "don't move it"...? -[Unknown] In article <e6abmn1ドルiaj1ドル digitaldaemon.com>, Walter Bright says... Stewart Gordon wrote: But what if the foreign code needs to hold onto the pointer for longer than it can remain on the stack? Have the D caller code keep a copy, or use addRoots to tell the gc where the foreign code is holding it.
Stewart Gordon wrote: But what if the foreign code needs to hold onto the pointer for longer than it can remain on the stack? Have the D caller code keep a copy, or use addRoots to tell the gc where the foreign code is holding it.
But what if the foreign code needs to hold onto the pointer for longer than it can remain on the stack?
Unknown W. Brackets wrote: But the question is for a "moving" GC, which might not consider a local reference to mean "don't move it"...? addroots will work with that.
But the question is for a "moving" GC, which might not consider a local reference to mean "don't move it"...?
But what if I don't know where the foreign code is holding it? The C library might not expose this, and then I'm out of luck... unless I can modify it, which I probably can't. But, this is all theoretical anyway. I can't even think of a library that keeps a pointer I give it. -[Unknown] Unknown W. Brackets wrote: But the question is for a "moving" GC, which might not consider a local reference to mean "don't move it"...? addroots will work with that.
Walter Bright wrote: Stewart Gordon wrote: <snip> But what if the foreign code needs to hold onto the pointer for longer than it can remain on the stack? Have the D caller code keep a copy, or use addRoots What is addRoot_s_? to tell the gc where the foreign code is holding it. How will I know where the foreign code is holding the pointer? Surely it makes more sense to add the pointer itself as a root. Moreover, the pinning methods'll need to be documented. So at the moment, I'm guessing that the following will implicitly pin a GC-allocated block: - storing a pointer to it in a union - having a pointer to it on the stack - adding it as a root Stewart.
But what if the foreign code needs to hold onto the pointer for longer than it can remain on the stack? Have the D caller code keep a copy, or use addRoots
to tell the gc where the foreign code is holding it.
Stewart Gordon wrote: Walter Bright wrote: Stewart Gordon wrote: <snip> But what if the foreign code needs to hold onto the pointer for longer than it can remain on the stack? Have the D caller code keep a copy, or use addRoots What is addRoot_s_? http://www.digitalmars.com/d/phobos/std_gc.html to tell the gc where the foreign code is holding it. How will I know where the foreign code is holding the pointer? First of all, the foreign code documentation ought to make some mention of what it does with the pointer - after all, it must even if you malloc'd it so you know when and if you can ever free it. Have the D code caller call addRoot.
Walter Bright wrote: Stewart Gordon wrote: <snip> But what if the foreign code needs to hold onto the pointer for longer than it can remain on the stack? Have the D caller code keep a copy, or use addRoots What is addRoot_s_?
to tell the gc where the foreign code is holding it. How will I know where the foreign code is holding the pointer?
Walter Bright wrote: Stewart Gordon wrote: Walter Bright wrote: Max Samuha wrote: Thank you for the extensive explanation! Marking my code with '// !!! Passing a pointer to C.' is what i've been doing recently:) and it seems the best solution for now until ares is mature or phobos has pin/unpin, or pointers passed to C are pinned implicitly. They will be pinned implicitly, no need to call pin/unpin. The only time you're going to have a problem is if the C routine hides the pointer in a malloc'd buffer where the gc won't see it. The gc *will* see pointers on the C stack. Would it remain pinned indefinitely, until the C function exits, or until the program explicitly unpins it by some means? It's pinned because it's on the stack, just like pointers on the stack for your D functions. The gc doesn't know the difference. Whoa, I got a bit confused here. Is any reference that is held in the stack automatically pinned (i.e., the referred data doesn't move) ? If so, why is that, why wouldn't a moving collector move it? -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Bruno Medeiros wrote: Whoa, I got a bit confused here. Is any reference that is held in the stack automatically pinned (i.e., the referred data doesn't move) ? Yes. If so, why is that, why wouldn't a moving collector move it? Because then you'd have to track all the register contents instruction by instruction.
Whoa, I got a bit confused here. Is any reference that is held in the stack automatically pinned (i.e., the referred data doesn't move) ?
If so, why is that, why wouldn't a moving collector move it?
Walter Bright wrote: Bruno Medeiros wrote: Whoa, I got a bit confused here. Is any reference that is held in the stack automatically pinned (i.e., the referred data doesn't move) ? Yes. If so, why is that, why wouldn't a moving collector move it? Because then you'd have to track all the register contents instruction by instruction. :/ I'm lost, I didn't understand that at all. "track all the register contents instruction by instruction" ? -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Bruno Medeiros wrote: Walter Bright wrote: Bruno Medeiros wrote: Whoa, I got a bit confused here. Is any reference that is held in the stack automatically pinned (i.e., the referred data doesn't move) ? Yes. If so, why is that, why wouldn't a moving collector move it? Because then you'd have to track all the register contents instruction by instruction. :/ I'm lost, I didn't understand that at all. "track all the register contents instruction by instruction" ? DISCLAIMER: /me is not an x86 assembler expert. Take with the requisite grain of salt. Think about it like this: say you want to dereference a pointer. Let's assume you've got something like this: Now, you move this into the ESI pointer to dereference it. And then HOLD IT! Moving garbage collector coming through! Hmm, this "foo" thing could be moved to be more efficient; let's move it! Now, go back to your business. What happen? Someone set up us the access violation! That damned moving GC preempted us and moved our data before we could get to it! Even if you're not multi-threaded, this is still a problem: there's nothing to preclude a pointer being stored in a register, calling new, causing a moving collect, and then attempting to dereference it. Isn't memory management fun? :P -- Daniel -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
Walter Bright wrote: Bruno Medeiros wrote: Whoa, I got a bit confused here. Is any reference that is held in the stack automatically pinned (i.e., the referred data doesn't move) ? Yes. If so, why is that, why wouldn't a moving collector move it? Because then you'd have to track all the register contents instruction by instruction. :/ I'm lost, I didn't understand that at all. "track all the register contents instruction by instruction" ?
Daniel Keep wrote: Bruno Medeiros wrote: Walter Bright wrote: Bruno Medeiros wrote: Whoa, I got a bit confused here. Is any reference that is held in the stack automatically pinned (i.e., the referred data doesn't move) ? Yes. If so, why is that, why wouldn't a moving collector move it? Because then you'd have to track all the register contents instruction by instruction. :/ I'm lost, I didn't understand that at all. "track all the register contents instruction by instruction" ? DISCLAIMER: /me is not an x86 assembler expert. Take with the requisite grain of salt. Think about it like this: say you want to dereference a pointer. Let's assume you've got something like this: Now, you move this into the ESI pointer to dereference it. And then HOLD IT! Moving garbage collector coming through! Hmm, this "foo" thing could be moved to be more efficient; let's move it! Now, go back to your business. What happen? Someone set up us the access violation! That damned moving GC preempted us and moved our data before we could get to it! The very same thing can happen with references stored in the heap or the static segment (i.e. globals). That is, with *any* reference. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Bruno Medeiros wrote: Walter Bright wrote: Bruno Medeiros wrote: Whoa, I got a bit confused here. Is any reference that is held in the stack automatically pinned (i.e., the referred data doesn't move) ? Yes. If so, why is that, why wouldn't a moving collector move it? Because then you'd have to track all the register contents instruction by instruction. :/ I'm lost, I didn't understand that at all. "track all the register contents instruction by instruction" ? DISCLAIMER: /me is not an x86 assembler expert. Take with the requisite grain of salt. Think about it like this: say you want to dereference a pointer. Let's assume you've got something like this: Now, you move this into the ESI pointer to dereference it. And then HOLD IT! Moving garbage collector coming through! Hmm, this "foo" thing could be moved to be more efficient; let's move it! Now, go back to your business. What happen? Someone set up us the access violation! That damned moving GC preempted us and moved our data before we could get to it!
Max Samuha wrote: How to ensure D code that interoperates with external libraries will work when a moving gc is eventually used with D? Will i need to add lots of pinning/unpinning code? <snip> Pinning has been requested a few times on these 'groups. There has also been a discussion before on issues that still need to be addressed before a GC that moves stuff around will work: http://www.digitalmars.com/d/archives/26273.html Stewart.
How to ensure D code that interoperates with external libraries will work when a moving gc is eventually used with D? Will i need to add lots of pinning/unpinning code?
On 2006年6月06日 14:27:22 +0100, Stewart Gordon <smjg_1998 yahoo.com> wrote: Pinning has been requested a few times on these 'groups. There has also been a discussion before on issues that still need to be addressed before a GC that moves stuff around will work: http://www.digitalmars.com/d/archives/26273.html Stewart. Yes, the thread you mention was posted two years ago. It would be really nice to hear a word from Walter on this issue.
Pinning has been requested a few times on these 'groups. There has also been a discussion before on issues that still need to be addressed before a GC that moves stuff around will work: http://www.digitalmars.com/d/archives/26273.html Stewart.
AltStyle によって変換されたページ (->オリジナル) / アドレス: モード: デフォルト 音声ブラウザ ルビ付き 配色反転 文字拡大 モバイル