Hi, It turns out that function fftw_plan_dft(..) from libfftw is non-reentrant, and I need to guard its call with a mutex. I didn't discover this until I wanted to add the ability to draw the quantum wavefunction in momentum representation. Doing this involves calling FFT transform from the GLDrawing thread, while at the same time (when the simulation is running) the FFT transform is being called thousand times per second from the calculation thread. I had numerous crashes until I added this mutex.
Now with the mutex I have no crashes, and I can look at the running simulation in momentum representation, FFT being called simultaneously from both threads. However I got an extra crash upon yade exit: boost::mutex::~mutex(): Assertion `!posix::pthread_mutex_destroy(&m)' failed. This crash happens even when OpenGL window is closed. A mere presence of this mutex caused it. Even though it was more or less not needed (no OpenGL drawing going on). Most helpful here was http://stackoverflow.com/questions/7817161/boostmutexmutex-assertion-pthread-mutex-destroym-failed and the last comment: "... the mutex was being torn down before it could be unlocked" I think that this was the case: the extra mutex that I added had no chance to close, because the simulation thread was being killed off during the exit. I could not find the right place in code to add a call to .join(); to solve this problem. Instead I changed the Omega::cleanupTemps() by adding stop() call: void Omega::cleanupTemps(){ stop(); boost::filesystem::path tmpPath(tmpFileDir); boost::filesystem::remove_all(tmpPath); } and now I don't have this crash anymore. I am not sure if that's the best way to do this. Another option that solved this problem was not introducing a new mutex, but using the existing one from Omega: Omega::instance().renderMutex But this solution although works, is particularly dirty for me, since that would require adding to Omega some kind of libFFTWMutex, which is kind of stupid. I am not sure how to deal with this, so I wanted to ask for your comments. IMHO ideal solution would be to put a .join() somewhere, but I am not sure where it is - maybe somewhere inside python wrappings. This solution with stop() has just one drawback - if a single iteration is particularly slow, one will have to wait for it to end, before exiting yade. Apart from that I think it's a pretty good solution, and we could decide that calling stop() was simply missing in cleanupTemps() function and this function should be renamed to cleanup(). Interesting thing - adding this call inside yadeFinalize() instead - didn't fix the crash! void yadeFinalize(){ Omega::instance().stop(); // doesn't help! Omega::instance().cleanupTemps(); } best regards -- Janek Kozicki http://janek.kozicki.pl/ | _______________________________________________ Mailing list: https://launchpad.net/~yade-dev Post to : [email protected] Unsubscribe : https://launchpad.net/~yade-dev More help : https://help.launchpad.net/ListHelp

