On Tue, 27 Feb 2007, Ernest Turro wrote: > > On 27 Feb 2007, at 17:45, Luke Tierney wrote: > >> On Tue, 27 Feb 2007, Ernest Turro wrote: >> >>> Hi Ross, >>> >>> On 26 Feb 2007, at 22:34, Ross Boylan wrote: >>> >>>> On Mon, 2007-02-26 at 16:08 +0000, Ernest Turro wrote: >>>>> Thanks for your comments Ross. A couple more comments/queries below: >>>>> >>>>> On 26 Feb 2007, at 06:43, Ross Boylan wrote: >>>>> >>>>>> [details snipped] >>>>>> >>>>>> The use of the R api can be confined to a wrapper function. But >>>>>> I can >>>>>> think of no reason that a change to the alternate approach I >>>>>> outlined >>>>>> would solve the apparent leaking you describe. >>>>>> >>>>> >>>>> I'm not sure I see how a wrapper function using the R API would >>>>> suffice. Example: >>>> It doesn't sound as if it would suffice. I was responding to your >>>> original remark that >>>> >>>>> Since this is a standalone C++ program too, I'd rather use the R API >>>>> as little as possible... But I will look at your solution if I find >>>>> it is really necessary.. Thanks >>>> >>>> I thought that was expressing a concern about using the alternate >>>> approach I outlined because it would use the R API. If you need to >>>> use >>>> that API for other reasons, you're still stuck with it :) >>>>> >>>>> During heavy computation in the C++ function I need to allow >>>>> interrupts from R. This means that R_CheckUserInterrupt needs to be >>>>> called during the computation. Therefore, use of the R API can't be >>>>> confined to just the wrapper function. >>>>> >>>>> In fact, I'm worried that some of the libraries I'm using are failing >>>>> to release memory after interrupt and that that is the problem. I >>>>> can't see what I could do about that... E.g. >>>>> >>>>> #include <valarray> >>>>> >>>>> valarray<double> foo; // I don't know 100% that the foo object hasn't >>>>> allocated some memory. if the program is interrupted it wouldn't be >>>>> released.... >>>> That's certainly possible, but you seem to be overlooking the >>>> possibility that all the code is releasing memory appropriately, >>>> but the >>>> process's memory footprint isn't going down correspondingly. In my >>>> experience that's fairly typical behavior. >>>> >>> >>> OK, but does this still explain why the footprint keeps increasing >>> indefinitely when i do run, interrupt, run, interrupt, run, >>> interrupt......? >>> >>> >>>> In that case, depending on your point of view, you either don't have a >>>> problem or you have a hard problem. If you really want the memory >>>> released back to the system, it's a hard problem. If you don't >>>> care, as >>>> long as you have no leaks, all's well. >>>> >>>>> >>>>> I find it's very unfortunate that R_CheckUserInterrupt doesn't return >>>>> a value. If it did (e.g. if it returned true if an interrupt has >>>>> occurred), I could just branch off somewhere, clean up properly and >>>>> return to R. >>>>> >>>>> Any ideas on how this could be achieved? >>>> I can't tell from the info page what function gets called in R if >>>> there >>>> is an interrupt, but it sounds as you could do the following hack: >>>> The R interrupt handler gets a function that calls a C function of >>>> your >>>> devising. The C function sets a flag meaning "interrupt requested". >>>> Then in your main code, you periodically call R_CheckUserInterrupt. >>>> When it returns you check the flag; if it's set, you cleanup and exit. >>>> Ross >>>> >>> >>> If this is feasible, it's by far the best solution. >>> >>> in error.c: >>> >>> void R_CheckUserInterrupt(void) >>> { >>> R_CheckStack(); >>> /* This is the point where GUI systems need to do enough event >>> processing to determine whether there is a user interrupt event >>> pending. Need to be careful not to do too much event >>> processing though: if event handlers written in R are allowed >>> to run at this point then we end up with concurrent R >>> evaluations and that can cause problems until we have proper >>> concurrency support. LT */ >>> #if ( defined(HAVE_AQUA) || defined(Win32) ) >>> R_ProcessEvents(); >>> #else >>> if (R_interrupts_pending) >>> onintr(); >>> #endif /* Win32 */ >>> } >>> >>> Leaving aside the HAVE_AQUA and Win32 cases, I would like to write a >>> new function: >> >> Unfortunately we can't leave those aside. If standard unix where >> interrupts arrive as signals is all you care about then you can just >> save, replace and restore the R SIGINT handler around your code with >> one that sets a flag of your own. Things are not so simple on GUI >> systems where detecting a user interrupt action requires event >> processing, which might result in errors and non-local exits in >> response to those. >> >> There is an internal mechanism for registering C level on.exit >> routines but this is not in a form that can be made public as it would >> tie down implementation decisions too much. It is principle possible >> to build something around R_ToplevelExec, but that is not at this >> point part of the public API and so is subject to change. We might >> consider providing a variant of R_CheckInterrupts that either just >> checks or that executes cleanup code sometime after 2.5 is released. >> > > Yes, I think it would be great if you added a variant of > R_CheckUserInterrupt() that actually returned something (e.g. a boolean) to > the R API. > > So in your view, is the best solution to pass a memory cleanup C function to > on.exit() before the call? What about memory allocated in some of the > external libraries that I use? E.g. as I mentioned above:
Depends on the cleanup actions you have to take. Best, luke > >>>>> >>>>> #include <valarray> >>>>> // ... >>>>> valarray<double> foo; // I don't know 100% that the foo object hasn't >>>>> allocated some memory. if the program is interrupted it wouldn't be >>>>> released.... > > > Thanks for your help, > > Ernest > > >> Best, >> >> luke >> >>> >>> int R_CheckInterruptsPending(void) >>> { >>> R_CheckStack(); >>> return R_interrupts_pending; >>> } >>> >>> and then in my C++ code: >>> >>> if(R_checkInterruptsPending) { >>> // clean up >>> // ... >>> R_CheckInterruptsPending(); >>> } >>> >>> R_CheckStack() is declared in R_ext/Utils.h but the variable >>> R_interrupts_pending isn't, so how could I access it? In other words, >>> how can I extend error.c ..... >>> >>> >>> Thanks, >>> >>> E >>> >>> ______________________________________________ >>> R-devel@r-project.org mailing list >>> https://stat.ethz.ch/mailman/listinfo/r-devel >>> >> >> -- >> Luke Tierney >> Chair, Statistics and Actuarial Science >> Ralph E. Wareham Professor of Mathematical Sciences >> University of Iowa Phone: 319-335-3386 >> Department of Statistics and Fax: 319-335-3017 >> Actuarial Science >> 241 Schaeffer Hall email: [EMAIL PROTECTED] >> Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu > -- Luke Tierney Chair, Statistics and Actuarial Science Ralph E. Wareham Professor of Mathematical Sciences University of Iowa Phone: 319-335-3386 Department of Statistics and Fax: 319-335-3017 Actuarial Science 241 Schaeffer Hall email: [EMAIL PROTECTED] Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel