octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Working patch for FFTW 3.0.x and Nd FFT's


From: John W. Eaton
Subject: Re: Working patch for FFTW 3.0.x and Nd FFT's
Date: Wed, 18 Feb 2004 22:30:50 -0600

On 18-Feb-2004, Paul Kienzle <address@hidden> wrote:

| When I was reading up on it before, I understood that
| you should not be doing blocking operations in a
| signal handler.   At the very least, you should be
| minimizing them.
| 
| How about:
| 
|       if (octave_interrupt_state == 2 && interactive) {
|               std::cerr << "Press Ctrl-C again to abort" << std::endl;
|       }
|       if (octave_interrupt_state >= 3) {
|               my_friendly_exit(sys_siglist[sig],sig,true);
|       }

That might be OK too.  I picked up the idea for printing a message and
reading a response from what I recall Emacs doing.  I've just looked
at the Emacs code, and what it does is actually

  flush stdout (subsequent messages are printed to stdout, so this
  might help)

  suspend Emacs

  if Emacs is resumed:

    offer to autosave (read response)

    offer to abort and dump core or continue (read response)

All of this happens inside a signal handler.  There is some protection
for not doing certain things if GC is happening.  It may not be the
best solution, but it has a fairly long history...

| With ulimit, I don't see any reason not to save the workspace.

OK.

| I would still be tempted to do something less drastic,
| such as put a set jump before each binary function and
| warn the user that the system may have leaked resources
| and may be unstable.

We already have something similar for F77 calls (which are assumed to
not open files or allocate memory).  The macros that F77_XFCN is based
on can also be used for C code that we don't control and that may not
handle interrupts.  So another possibility is to do what we have
around the readline code.  All it really requires is doing something
like

  BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;

  fftw_plan plan = fftw_planner.create_plan (FFTW_FORWARD, 1, dv, nsamples,
                                             stride, dist, in, out);

  fftw_execute_dft (plan, 
        reinterpret_cast<fftw_complex *> (const_cast<Complex *>(in)),
        reinterpret_cast<fftw_complex *> (out));

  END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;

The definitions of the macros from libcruft/misc/quit.h:

  #define BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE \
    BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_1; \
    octave_throw_interrupt_exception (); \
    BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_2

  #define BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_1 \
    do \
      { \
        octave_jmp_buf saved_context; \
   \
        octave_save_current_context ((char *) saved_context); \
   \
        if (octave_set_current_context) \
          { \
            octave_restore_current_context ((char *) saved_context)

  #define BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_2 \
          } \
        else \
          { \
            octave_interrupt_immediately++

  #define END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE \
            octave_interrupt_immediately--; \
            octave_restore_current_context ((char *) saved_context); \
          } \
      } \
    while (0)


So the basic idea is what you suggested, to save a location and set up
for the signal handler to jump back to this location, then restore any
previous location that may have been saved, so if we are inside some
nested calls we can keep jumping back up the stack of saved
locations (to get this right, you also need to use the macros

  BEGIN_INTERRUPT_WITH_EXCEPTIONS

and

  END_INTERRUPT_WITH_EXCEPTIONS

also defined in quit.h.  For examples of their usage, look at any of
the functions in Octave that call user-supplied functions (in
liboctave, LSODE.cc, DASSL.cc, etc.)

So, should we also surround the FFTW code with these immediate
interrupt enabling macros?

jwe



reply via email to

[Prev in Thread] Current Thread [Next in Thread]