If you're writing an external library to be called from Maple, then you have the following problem. The user wants to interrupt your code. They are valiantly pressing control-C or the stop button in the Maple GUI, as your code grinds their machine to a halt. What do you do ?
The OpenMaple C API (see ?OpenMaple,C,API) has a function called MapleCheckInterrupt, which checks for interrupt requests. You can use it in your code as follows:
#include <maplec.h>
ALGEB test(MKernelVector kv, ALGEB *args)
{
M_INT i, n = 10000000;
for (i=0; i < n; i++) {
MapleCheckInterrupt(kv);
}
return (ALGEB)1;
}
However when an interrupt occurs, MapleCheckInterrupt never returns. It passes control back to the Maple kernel. This is a problem if you have allocated memory using malloc. You need the kernel to return control to you so that you can free memory and clean up. Here is the solution that I use:
#include <maplec.h>
M_BOOL check_interrupt(MKernelVector kv)
{
M_BOOL e;
kv->traperror((void *)kv->checkInterrupt, NULL, &e);
return e;
}
ALGEB test(MKernelVector kv, ALGEB *args)
{
M_INT i, *x, n = 10000000;
x = malloc(n*sizeof(M_INT));
for (i=0; i < n; i++) {
if (check_interrupt(kv)) {
free(x);
kv->error("Interrupted");
}
}
free(x);
return (ALGEB)1;
}
The check_interrupt function uses the kernel to trap it's own error. It's not fast or pretty, but it works.
Comments
interrupt / related question
1. Do you have a similar suggestion, if calling an external DLL (which does not know of Maple)?
2. If I want to interrupt Maple execution for conventional code within a classical sheet on Win there is often no reaction even after long waiting (so I shut down the task)
1. Do you have a similar
1. Do you have a similar suggestion, if calling an external DLL (which does not know of Maple)?
Operating systems install an interrupt handler, so you could essentially to do the same thing. I have no idea how to do that. You would need to read up on operating systems.
2. If I want to interrupt Maple execution for conventional code within a classical sheet on Win there is often no reaction even after long waiting (so I shut down the task)
I have no ideas. Control-C in Linux and Mac terminals has always worked for me.
traperror + interrupt not safe
traperror was not meant to be able to catch user interrupts. The fact that this works at all is a bug, which aught to be fixed, so this code may not work in future versions. As is, it isn't safe. I wouldn't recommend using this code. Maplesoft is considering adding to the external API to provide a function to do this in a safe way.
welcome improvement
That functionality would be welcome :) If possible, it would be nice to make it really fast, like 10 cycles, so that developers can poll in a tight loop. The hack uses 700 cycles, which means I can only afford to poll every once and a while.
Good idea
It would have been nice if the developers of existing packages which use external code (e.g. LinearAlgebra and Optimization) had made use of this mechanism. Perhaps they could be encouraged to put it in...
interruptible during callback or garbage collection?
Aren't the Optimization, GlobalOptimization, and evalf/Int external processes already interruptible during callbacks to Maple proper? They make "eval" and "evalhf" callbacks to evaluate objectives and integrands.
Isn't external software precision LinearAlgebra interruptible during garbage collection?
acer
Interruptible?
Maybe, but these interruption opportunities may be few and far between, as I've had many frustrating experiences with the Stop button.
Try this, for example (a rather difficult knapsack problem):
> with(Optimization): c := [seq(rand(), i=1..100)]: v:= add(c[j],j=combinat[randcomb]([$1..100],50)): Maximize(x[1],{add(c[j]*x[j], j=1..100)=v}, assume=binary);Let it go for, say, 10 seconds, then press the Stop button. How long does it take before you get "Warning, computation interrupted"?