From: Alan R. <ala...@gm...> - 2006-05-12 19:01:44
|
There are many cases were I can't seem to interrupt evaluation of a form in the slime repl. I've taken to starting to put in (sleep 0.002) in some loops to make sure there will be a chance to interrupt. There's probably a better way... Suggestions? Ideally a bullet proof way of interrupting code even if it is in some java library, though I don't know if Java lets you do that. I've had a couple of cases where I've been stuck in a regex match that goes awry, and I have to kill and restart the lisp :( -Alan |
From: Peter G. <pe...@ar...> - 2006-05-16 18:46:44
|
On Fri, 12 May 2006 at 15:01:32 -0400, Alan Ruttenberg wrote: > There are many cases were I can't seem to interrupt evaluation of a > form in the slime repl. I've taken to starting to put in (sleep > 0.002) in some loops to make sure there will be a chance to interrupt. > > There's probably a better way... Suggestions? Ideally a bullet proof > way of interrupting code even if it is in some java library, though I > don't know if Java lets you do that. I've had a couple of cases where > I've been stuck in a regex match that goes awry, and I have to kill > and restart the lisp :( > > -Alan You know about the native code control-c handler for Linux, right? Or maybe you're not on Linux... -Peter |
From: Alan R. <ala...@gm...> - 2006-05-16 19:27:35
|
OS X. -Alan On May 16, 2006, at 2:46 PM, Peter Graves wrote: > On Fri, 12 May 2006 at 15:01:32 -0400, Alan Ruttenberg wrote: >> There are many cases were I can't seem to interrupt evaluation of a >> form in the slime repl. I've taken to starting to put in (sleep >> 0.002) in some loops to make sure there will be a chance to >> interrupt. >> >> There's probably a better way... Suggestions? Ideally a bullet proof >> way of interrupting code even if it is in some java library, though I >> don't know if Java lets you do that. I've had a couple of cases where >> I've been stuck in a regex match that goes awry, and I have to kill >> and restart the lisp :( >> >> -Alan > > You know about the native code control-c handler for Linux, right? > > Or maybe you're not on Linux... > > -Peter |
From: Alan R. <ala...@gm...> - 2006-05-20 05:28:51
|
OK. To compile this for OS X, In native.c we need JNIEnv *_env = 0; jclass _cls = 0; jmethodID _mid = 0; and the command line is gcc -dynamiclib -o libabcl.jnilib -O -D_REENTRANT -fPIC -I/System/ Library/Frameworks/JavaVM.framework/Home/include native.c -framework JAVAVM I copied it to /Library/Java/Extensions/ Unfortunately, I get a bus error when I try to use it. getCurrentThreadUserTime work though. OTOH, Slime tries to use (ext:interrupt-thread), and by tracing it, I can see that it is called when I hit control-c, and that it is apparently being called right away. But the break doesn't happen until the loop ends. CL-USER> (CURRENT-THREAD) #<THREAD "new-repl-thread" {1909CB}> CL-USER> (dotimes (i 10000000)) 0: (INTERRUPT-THREAD #<THREAD "new-repl-thread" {1909CB}> #<FUNCTION SWANK:SIMPLE-BREAK {5B1698}>) 0: INTERRUPT-THREAD returned T <wait until the dotimes finishes> break happens now And the computation continues. When it finally finishes, I get the break. The way I read the code, it depends on Thread.interrupt being called, which should generate a InterruptedException in the thread being interrupted, which you catch and use to call processInterrupts. InterruptedException says "Thrown when a thread is waiting, sleeping, or otherwise paused for a long time and another thread interrupts it using the interrupt method in class Thread.". This apparently doesn't happen in a timely manner. For the control-c handler, in any case, in a situation where there are multiple threads, who's to guarantee that the right thread notices Lisp.Interrupted. Since you already have the infrastructure for Lisp.interrupted, would the following work? Change Lisp.interrupted to be an Object. In handleInterrupt, if Lisp.Interrupt is True or False, then handle the way you do now. If not, check if it is equal to the current thread and if not, do nothing. That way you can call setInterrupted with a specific thread and know that it will pick it up. -Alan On May 16, 2006, at 2:46 PM, Peter Graves wrote: > On Fri, 12 May 2006 at 15:01:32 -0400, Alan Ruttenberg wrote: >> There are many cases were I can't seem to interrupt evaluation of a >> form in the slime repl. I've taken to starting to put in (sleep >> 0.002) in some loops to make sure there will be a chance to >> interrupt. >> >> There's probably a better way... Suggestions? Ideally a bullet proof >> way of interrupting code even if it is in some java library, though I >> don't know if Java lets you do that. I've had a couple of cases where >> I've been stuck in a regex match that goes awry, and I have to kill >> and restart the lisp :( >> >> -Alan > > You know about the native code control-c handler for Linux, right? > > Or maybe you're not on Linux... > > -Peter |
From: Peter G. <pe...@ar...> - 2006-05-20 12:49:54
|
On Sat, 20 May 2006 at 01:28:46 -0400, Alan Ruttenberg wrote: > OK. To compile this for OS X, In native.c we need > > JNIEnv *_env = 0; > jclass _cls = 0; > jmethodID _mid = 0; > > and the command line is > > gcc -dynamiclib -o libabcl.jnilib -O -D_REENTRANT -fPIC -I/System/ > Library/Frameworks/JavaVM.framework/Home/include native.c -framework > JAVAVM > > I copied it to /Library/Java/Extensions/ > > Unfortunately, I get a bus error when I try to use it. > getCurrentThreadUserTime work though. > > OTOH, Slime tries to use (ext:interrupt-thread), and by tracing it, I > can see that it is called when I hit control-c, and that it is > apparently being called right away. But the break doesn't happen > until the loop ends. > > CL-USER> (CURRENT-THREAD) > #<THREAD "new-repl-thread" {1909CB}> > CL-USER> (dotimes (i 10000000)) > 0: (INTERRUPT-THREAD #<THREAD "new-repl-thread" {1909CB}> > #<FUNCTION SWANK:SIMPLE-BREAK {5B1698}>) > 0: INTERRUPT-THREAD returned T > <wait until the dotimes finishes> > break happens now > > And the computation continues. When it finally finishes, I get the > break. The way I read the code, it depends on Thread.interrupt being > called, which should generate a InterruptedException in the thread > being interrupted, which you catch and use to call processInterrupts. > InterruptedException says "Thrown when a thread is waiting, sleeping, > or otherwise paused for a long time and another thread interrupts it > using the interrupt method in class Thread.". This apparently doesn't > happen in a timely manner. Yeah, I think this is a Java issue. There may be a workaround, but the workaround is likely to depend on what platform you're on and what version of Java you're using. I'm not too optimistic about a general solution. > For the control-c handler, in any case, in a situation where there > are multiple threads, who's to guarantee that the right thread > notices Lisp.Interrupted. Good point. The original idea of the control c handler was to be able to break out of situations where there was only one Lisp thread and that thread was stuck in a loop, which sometimes happened with Paul Dietz's random tester in the early days of ABCL's compiler. Using control c in that sort of situation works more often than not, in my experience, although sometimes it just crashes Java. I never really expected the control c handler to handle multithreaded situations. If you want to interrupt a background thread, presumably you know which thread that is, and, in theory, you can use INTERRUPT- THREAD. It seems like this is what slime is doing. The problem is that INTERRUPT-THREAD doesn't really work, but, as mentioned, I think that's probably a Java issue. > Since you already have the infrastructure for Lisp.interrupted, would > the following work? Change Lisp.interrupted to be an Object. In > handleInterrupt, if Lisp.Interrupt is True or False, then handle the > way you do now. If not, check if it is equal to the current thread > and if not, do nothing. That way you can call setInterrupted with a > specific thread and know that it will pick it up. It might be worth a try, but if the stuck thread doesn't respond to Thread.interrupt(), I doubt that it's going to notice Lisp.interrupted either. Note, by the way, that handleInterrupt() only gets called in interpreted Lisp code or in Lisp code compiled with safety >= speed; code in pure-Java libraries will never see Lisp.interrupted at all. -Peter |
From: Alan R. <ala...@gm...> - 2006-05-20 15:37:15
|
On May 20, 2006, at 8:49 AM, Peter Graves wrote: >> Since you already have the infrastructure for Lisp.interrupted, would >> the following work? Change Lisp.interrupted to be an Object. In >> handleInterrupt, if Lisp.Interrupt is True or False, then handle the >> way you do now. If not, check if it is equal to the current thread >> and if not, do nothing. That way you can call setInterrupted with a >> specific thread and know that it will pick it up. > > It might be worth a try, but if the stuck thread doesn't respond to > Thread.interrupt(), I doubt that it's going to notice Lisp.interrupted > either. It will sometimes notice. The example I gave was a loop typed at the repl prompt, so it was evaluated. Personally, I think it is worth it, but then I'm not quite brave enough to modify the abcl source and try it yet. > Note, by the way, that handleInterrupt() only gets called in > interpreted Lisp code or in Lisp code compiled with safety >= speed; > code in pure-Java libraries will never see Lisp.interrupted at all. Right. So having both is probably desirable. When I'm regularly developing with regular expressions occasionally it goes into an uninterruptable loop inside the library. Very irritating. An triggering example, courtesy of http://discuss.fogcreek.com/joelonsoftware5/default.asp? cmd=show&ixPost=154057&ixReplies=14 "((a*)(a*))+b" applied to aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac I had hoped that gnu.regex might fair better, but it doesn't accept the regular expression and on the similar "((a*)(a+))+b" it doesn't seem to terminate at all, whereas the java regular expression does. I suppose that I should submit a bug report to sun, since the end result of these even if they are programmer errors, is that the whole session is hosed. -Alan |