Making a callback thread safe
BlitzMax Forums/BlitzMax Programming/Making a callback thread safe
| ||
I am working with a multi-threaded physics library that uses callbacks during the physics update routine. GCSuspend() is called before the physics update, and GCResume() is called after. The callbacks use the "c" calling convention. With a single core the program runs perfectly. A crash results when the physics use more than one thread. How can I make the callbacks thread-safe? As I understand it, all the function variables are "up for grabs" at any time. Each callback has a parameter indicating which thread is in use. So would I do something like this?: Current code: Function Callback( threadIndex:Int ) "C" Local a:Int a = 3 EndFunction Thread-safe code: Function Callback( threadIndex:Int ) "C" Local a:Int[ 2 ] a[ threadindex ] = 3 EndFunction |
| ||
I don't think it's possible, TBH. What error is Blitz throwing? I had a problem with an FMOD callback a while ago. Kept throwing a 'scope stack underflow' and no-one seemed able to come up with a solution, even BRL. |
| ||
I am not using objects or doing anything crazy. Just using some local variables. If I write to anything global, I lock the threads while writing. Local variables should be fine, right? Those should not interfere with each other on separate threads. |
| ||
Sorry mate, I'm not totally sure, but I can't see how local variables could cause a problem. I do know that I tried removing anything that I thought could create garbage from my callback and did the nogc thing and I was still getting errors. How are you locking the threads? This one REALLY needs a response from BRL. |
| ||
Try this mate... (no promises)Function Callback( threadIndex:Int ) "C" NoDebug Global a:Int[ 2 ] a[ threadindex ] = 3 EndFunction IMHO thats about as safe as it gets ATM, if that still causes problems then you could try adding a critical section. but if you're only going to be doing a bit of math in the callback I'd suggest writing it in C. |
| ||
Local variables should not need to be protected like that in an array. Does NoDebug have any effect when the code is compiled in release mode? |
| ||
Does NoDebug have any effect when the code is compiled in release mode? No. Why would you expect it to? The point of NoDebug is to turn off *debugging* in a given function, e.g. something you call many times per loop that you know works and want to avoid the performance hit in debug. (I think it's also used in the blitzmax source a bit too). |
| ||
I don't. It did not make sense that this was suggested as a solution to the problem. |
| ||
Josh, the only solution is to code the callback in C, there is some sync functions available if you look in brl.system for the callback to communicate with your blitz app but I would look at a simple PostMessage type solution first. You can NOT use BlitzMax functions in the context of other threads. |
| ||
Thank you for the information. |
| ||
It did not make sense that this was suggested as a solution to the problem. of course it does but only when you run in debug mode, as debug mode adds a load of stuff to your code to track whats going on, stuff that would probably mess up threading. The main change was to *try* it with a global array, so the GC wouldnt get involved, as you used a local array in your original attempt that would have to be created and GCed every time the function was called. anyway I assume it didnt work, so its time to crack out a bit of C ;) |