From: John W. E. <jw...@be...> - 2002-11-27 19:38:52
|
On 26-Nov-2002, Nix <ni...@es...> wrote: | On Mon, 25 Nov 2002, Paul Kienzle yowled: | | > If this works, I can push out a new octave-forge very soon, | > but Ctrl-C will not be responsive within superLU. | > | > For Ctrl-C we need to put OCTAVE_QUIT in all the inner loops of *.{cc,h} | | No need :) Why not? I think they do need to be in the Octave interface glue code. | > and wrap calls to superLU with BEGIN/END_INTERRUPT_WITH_EXCEPTIONS. | > At least I think that's what we are supposed to do. Yes. I updated my copy of the octave-forge code from CVS and it looks like Paul has done the right thing, though it could probably be improved to handle freeing resources in more places in the Octave glue code. But, as Paul mentioned, whether we should actually do that work depends on whether we are going to actually integrate the SuperLU code in Octave. I think the SuperLU code is now at least as good as it was with the previous interrupt handling model (which was generally very bad because of the jump out of the signal handler). | No need for any of that; the _IMMEDIATELY_ variants of those macros set | up a setjmp() / throw layer. The Octave signal handlers in | src/sighandlers.cc spot that we're inside an _IMMEDIATELY_ wrapper | (because `octave_interrupt_immediately' is nonzero) and (sig)longjmp | there for us. | | > It's not clear how we can clean up a superLU malloc which was interrupted | > during initialization. I believe that's why garbage collection was | > invented. | | You can't clean that up, but then we've *never* been able to clean that | up. At least this way destructors for C++ objects get called :) | | (Hell, there's a worse case than that: the SIGINT is asynchronous, so it | can arrive in the middle of a malloc(). If it does that, we're | completely screwed and the heap is fubared. But this, too, has always | been the case, and there don't seem to be many bug reports that can be | traced to screwed heaps. So I guess this is rare enough to ignore.) Right. This is one of the reasons it is bad to jump out of a signal handler. If instead the signal handler sets some flag indicating that it has been called and returns so that the jump only happens when it is safe, we are OK. But unless SuperLU is written with signal handling in mind, then this will require some changes. The "jump from the signal handler" model is generally OK for the old Fortran 77 numerical code because in most cases that code doesn't acquire any resources. All memory allocations are handled outside of the call to the Fortran 77 subroutine and most of the old Fortran numerical code doesn't open files or even modify global variables. | I got stalled by wondering how best to wrap *all* calls into SuperLU. I | guess that a thin C++ wrapper around SuperLU is indicated, each of which | does careful BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE / | END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE calls. | | --- oh, this is only needed in computationally expensive stuff. In cheap | calls we can just ignore it and leave the calls undecorated, because the | user won't interrupt in there and won't notice the delay even if he | does. (Decorating such calls is probably a bad idea, actually, because | the setup and teardown for the _INTERRUPT_IMMEDIATELY_ stuff isn't | free.) Right. This is the same as the choice we have with calls to Fortran code. We either use F77_XFCN (sets up for a potential longjmp call, so should be used for expensive calls, or ones where we can't easily determine how long they will take) or F77_FUNC (no longjmp setup, so we expect it to return quickly). jwe |