Project

General

Profile

Feature #714

Interrupt mechanism

Added by John Abbott almost 9 years ago. Updated almost 9 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
New Function
Start date:
19 May 2015
Due date:
% Done:

100%

Estimated time:
4.51 h
Spent time:

Description

Add an interrupt mechanism to CoCoALib.


Related issues

Related to CoCoA-5 - Bug #713: External libs: interrupting not easyClosed2015-05-18

Related to CoCoALib - Feature #718: Insert calls to CheckForInterruptResolved2015-05-21

Related to CoCoA-5 - Bug #345: Interpreter interrupt delayed confusinglyClosed2013-04-24

Related to CoCoALib - Feature #385: Design new errors using inheritanceIn Progress2013-07-08

Related to CoCoALib - Feature #638: Time limit: let user specify time limit for a computationClosed2014-10-27

Related to CoCoALib - Bug #971: CheckForInterrupt does not work in the expected wayClosed2016-11-14

Related to CoCoALib - Bug #1458: Redesign interrupt mechanism?Rejected2020-05-10

History

#1 Updated by John Abbott almost 9 years ago

As far as CoCoA-5 is concerned CoCoALib is "external software", and the problem noted in #713 applies as much to CoCoALib as to other external libraries.

I suggest the following design:
  • there is a global flag CoCoA::InterruptFlag which is normally false
  • there is a function CoCoA::SignalInterrupt which sets the flag
  • there is a function CoCoA::CheckForInterrupt which tests the flag; if false, the function simply returns; otherwise it resets the flag, and throws a CoCoA::interrupted exception

CoCoALib authors would then be obliged to call CheckForInterrupt every so often, so that an interrupt will actually take effect within a reasonable time.

#2 Updated by John Abbott almost 9 years ago

There is a slight risk in my proposal above. If SignalInterrupt is called asynchronously while CheckForInterrupt is running, and has just reset the flag but not yet thrown the exception, then the flag will be set while the exception is thrown. This could be rather unexpected.

I suggest that a new class CoCoA::InterruptException be the type thrown. Its destructor could reset the interrupt flag. This should ensure that the flag is reset once the (interrupt) exception handler exits scope. This should have the effect of ignoring any further signals while the exception is propagating and being handled.

Maybe even: the ctor for CoCoA::InterruptException could block all signals (and then reset the flag), and the dtor unblocks them. This fits in well with ctor-dtor corresponding to resource acquisition-release.

#3 Updated by John Abbott almost 9 years ago

Here is a further complication: how to handle several libraries together?
Let us suppose that CoCoALib has a mechanism similar to that outlined above, and that libnormaliz has an analogous system.

Suppose we have CoCoALib+libnormaliz working on a problem, and we want to interrupt the computation. From outside we do not know whether the currently running code is part of CoCoALib or part of libnormaliz; so we want to set both flags to be certain that the running code will see the interrupt.

We must also make sure that all flags are reset when the interrupt is handled. Perhaps the simplest solution is to have a single shared flag; this implies that CoCoALib and libnormaliz must work with references to some common global flag. How to tell them where this flag is? In CoCoALib, this could probably be done via GlobalManager.

#4 Updated by John Abbott almost 9 years ago

  • Status changed from New to In Progress
  • % Done changed from 0 to 20

I have implemented a first version following the outlines given above.

It seems to pass a quick test -- I have made RingBase::mySequentialPower interruptible, and have verified that it works.

Matters still to resolve:
  • (A) check that the new catch statement in the interpreter (Interpreter.C:2678) is all that is needed
  • (B) print out some message about being interrupted
  • (C) is there some way to put in context information? (e.g. convert CoCoA::InterruptReceived into InterruptException with context info)
  • (D) insert numerous calls to CheckForInterrupt() throughout CoCoALib

(D) will be long and tedious, but probably not too hard -- make a new issue?
(C) requires studying the interpreter; maybe Giovanni can help?
(B) probably becomes irrelevant if (C) can be done well
(A) again Giovanni's help would be a boon!

#5 Updated by John Abbott almost 9 years ago

Also seems to work with the C5 GUI now :-)

#6 Updated by John Abbott almost 9 years ago

I am undecided about which ways to offer for telling the GlobalManager which interrupt flag to watch:
  • (A) specify the flag in GlobalSettings which is passed as ctor param to GlobalManager
  • (B) specify the flag by calling a mem fn of GlobalManager

Approach (B) is more powerful than approach (A) in that approach (A) can always be replaced by approach (B) but not vice versa (as I discovered when modifying src/CoCoA-5/Main.C)

Is there any sense in offering approach (A)? Perhaps it is best to offer just (B), and add approach (A) later if there is good justification?

#7 Updated by Anna Maria Bigatti almost 9 years ago

John Abbott wrote:

Is there any sense in offering approach (A)? Perhaps it is best to offer just (B), and add approach (A) later if there is good justification?

(I admit I'm not understanding all the implications) my preference was for (B) even before reading John's last comment ;-)

#8 Updated by John Abbott almost 9 years ago

  • Status changed from In Progress to Resolved
  • Assignee set to John Abbott
  • % Done changed from 20 to 80

I have checked in the impl with both (A) and (B).
Then I deleted (A) and checked in again. This way I hope (A) might still be recoverable from CVS if we should ever want it.

I'll discuss the design with Christof; and if all goes well, we can proceed to feedback status.

PS I'm hoping Christof will add a similar feature to libnormaliz.

#9 Updated by John Abbott almost 9 years ago

  • Status changed from Resolved to Feedback
  • % Done changed from 80 to 90

I've been using the current code for a little while (not really proper testing), and no problems have come up. So changing status to feedback.

I am just slightly uneasy about the "clever trick" of making InterruptReceived dtor reset the interrupt flag... but I cannot see how it can be harmful.

#10 Updated by Anna Maria Bigatti almost 9 years ago

  • Status changed from Feedback to Closed
  • % Done changed from 90 to 100
  • Estimated time set to 4.51 h

Tested on my computer: pending interrupt and caught interrupt, they both work! Closing

#11 Updated by John Abbott almost 9 years ago

  • Target version changed from CoCoALib-0.99540 Feb 2016 to CoCoALib-0.99536 June 2015

#12 Updated by John Abbott over 7 years ago

  • Related to Bug #971: CheckForInterrupt does not work in the expected way added

#13 Updated by John Abbott almost 4 years ago

  • Related to Bug #1458: Redesign interrupt mechanism? added

Also available in: Atom PDF