RE: Safely implementing Thread.Abort
"Thong (Tum) Nguyen" <tum-x2aT3/[email protected]>
| Newsgroups | gmane.comp.gnu.dotgnu.developer |
|---|---|
| Message-ID | <[email protected]> |
> -----Original Message----- > From: Russell Stuart [mailto:[email protected]] > Sent: Thursday, 20 May 2004 2:18 p.m. > To: Thong (Tum) Nguyen > Cc: DotGnu-Develop > Subject: Re: [DotGNU]Safely implementing Thread.Abort > > On Thu, 2004-05-20 at 07:36, Rhys Weatherley wrote: > > Outputting abort check instructions on every backward > > branch is OK with me, as long as you only do it in > > programs that use Thread.Abort. This can be detected > > by the loader (any assembly with a MemberRef to > > Thread.Abort is a candidate). > > This relies on knowing whether any code calls > Thread.Abort(). There are two issues with that. First > of all, how are you going to know? Scan every assembly > referenced when you first start up? Some of these > assemblies might use Thread.Abort(), and yet it may > never be called. > > Secondly, what about programs that do a > System.Reflection.Assembly.Load? You might discover > the loaded assembly might calls Thread.Abort() after > you have generated some code. A variation on the theme > is Remoting. A remote procedure may call Thread.Abort(). > I see how you could know that. > > On Thu, 2004-05-20 at 08:47, Rhys Weatherley wrote: > > For now, implement the check on backwards jump as-is. > > This will always work, but you have generate equivalent > code for the JIT. Will you be able to bring yourself > to do that? It won't be just an instruction or two. > The "tst" op-code will overwrite the CPU's condition > flags, which will have to be restored if you are > doing a conditional backward jump. In any decently > optimised code most of them are conditional. > > On Thu, 2004-05-20 at 08:18, Rhys Weatherley wrote: > > How exactly are you going to do that? The CVM instruction > > pointer is probably going to be in a register (esi on x86). > > You cannot guarantee that the CVM instruction pointer is in > > "thread->pc" when an abort occurs. > > This is true. In fact even in a Unix Signal you will have > no idea of the "true" value of thread->pc - because you don't > in general know what register it is in. > > Thus my original suggestion was modify every backward jump > in the current method. > > That won't catch every case - the thread being aborted may > be in the middle of constructing/destroying a frame. The > only way I can see around that is the Abort() method hanging > around until it sees the aborted thread has processed the > abort, or until its the stack frame changes - in which case > it has another go at stopping it. > > On Thu, 2004-05-20 at 07:36, Rhys Weatherley wrote: > > You cannot use any approach that requires the method code > > to be modified after it is first generated. It isn't thread safe: > > I am not convinced of that. Firstly, no matter what you do, > you have set a thread->aborted flag, and you have to force > the thread to see it, ie you have to force it into the > cache of the CPU it is executing on. I think all operating > systems that support multiple CPU's provide a means of doing > that, as tum has noted. Forcing the CPU to see modifications > you have made to its instruction stream is essentially the > same problem. > > Secondly, on all multi CPU architectures I know of writes to > a word are atomic. By this I mean a if a single instruction > writes some bytes that do not cross a word boundary, no CPU > will see some bytes written and some not. Either they will > see the entire write, or none of it. Here "word" means > the width of the narrowest memory bus - typically the one > to main memory. With DIMM's this is 64 bits. > > With CVM, where we have control over the op-codes, life is > very simple. All you need to do is have two versions of the > "backward jump" opcode. The one normally generated doesn't > check for Abort()'s. When Abort()'s is executed, you > replace it with one that does. This can't possibly be > non-thread safe. > > With the JIT life gets harder, because you can't typically > just modify one byte. You have to insert some sort of > "call" instruction. It could be a "call", or it could > generate a software interrupt (like the ia32 int3). > Whatever you do, providing you can make the modification > with just one write to a word aligned value, you can > get away with it. This means the JIT would have to word > align the backward jumps and returns. > > I don't really think its a question of whether its possible > to implement Thread.Abort() with zero overhead to programs > that don't use it - it is. With CVM its not even that hard > to do. With the JIT - well it sounds like an awful lot of > effort to me, but I can't think of a simpler solution ATM. > > > _______________________________________________ > Developers mailing list > [email protected] > http://dotgnu.org/mailman/listinfo/developers