Communicating between threads

BlitzMax Forums/BlitzMax Programming/Communicating between threads

Who was John Galt?(Posted 2010) [#1]
Can somebody give me an idea how to communicate information between separate threads?

I have one function that I am using as a callback from another program (fmod, to be precise). I need to communicate variables from my main application to modify the output it produces.

The problem is that the callback can't see any of my program's global variables. I have tried enabling the threaded build but haven't specifically done anything with the thread.

In short,
1) Is what I'm seeing wrt global variables what you expect?
2) How to get around it.

Thanks


ima747(Posted 2010) [#2]
What exactly do you mean by it can't see any of your program's global variables? do they have null values, does it not compile?


_Skully(Posted 2010) [#3]
I recall that you have to pass objects only...

implementation I'm clueless about ;)


Rozek(Posted 2010) [#4]
Hmmm,

my problem is that I don't exactly know what "fmod" is...but, in principle, threads share the same memory context, thus, you should be able to access global variables from within every thread (btw., that's the reason why you have to "synchronize" accesses to these "shared variables"). Otherwise, I would not understand, why your BlitzMAX function can be invoked, but can't handle it's own variables (and globals) (despite the differences between link space, heap and stack)

Just as a side note: do not mix up "threads" and "callbacks" - you may use "callbacks" without using threads! (but, of course, "fmod" might spawn threads internally)

I am using lots of BlitzMAX callbacks from within Lua and accessing all types of data from within them without the slightest problem!


Who was John Galt?(Posted 2010) [#5]
ima747- Sorry, I hadn't investigated fully. It appears that the callback function effectively takes a copy of any global variables at the time it is first called from the external API. After that, it sticks with those values even if I modify my global.

Skully... any links? I'm not sure how to apply what you're saying.


Brucey(Posted 2010) [#6]
Just as a side note: do not mix up "threads" and "callbacks" - you may use "callbacks" without using threads! (but, of course, "fmod" might spawn threads internally)

Right, and in a single-threaded app, callbacks and the default GC work perfectly.

For something like FMOD, to use the callback system, you can't really do so with the default GC.

However, sharing variable values should "just work". Just be careful about accessing those values from different threads if the value is likely to change from a different thread.


Who was John Galt?(Posted 2010) [#7]
@Rozek-
Only saw your reply after my second post. FMOD is a sound API. I only mentioned that in passing in case it would help anyone who has used it. My working assumption is that fmod is using a separate thread and that's causing the problem. As I said, I have enabled threading in the build. I have not done anything to synchronise accesses to shared variables. What commands should I be looking at?

@Brucey-
Thanks. It's definitely attempts to change the shared variable that cause the problem.


Rozek(Posted 2010) [#8]
John,

before offering "solutions" based on assumptions, let's check your assumption first!

Within your callback, add the following (untested!) code:
global ThreadDetected:int = false
if (not ThreadDetected and (currentThread() <> mainThread())) then
  debuglog("**** Callback was called from outside the MainStack! ****")
  ThreadDetected = true
end if
You may also have to
import brl.Threads
at the beginning of your program.

Now run your code and watch out for any output from your callback - this will show you if FMOD is *really* spawning threads (and invokes your callback from within one of them)


Who was John Galt?(Posted 2010) [#9]
Thanks Rozek...

Stranger and stranger... the callback is reporting that is is NOT a separate thread. Now I am seriously stumped. I know for a fact that after the function has been called from the external API, it ignores any changes to global variables made externally.

I have zero clue what could be causing the problem now. Any more ideas?


Rozek(Posted 2010) [#10]
John,

try "debuglog" or similar to check the value of your globals before and after trying to set them - and check the values they should be set to!

Good luck hunting! (I know how difficult that may be!)


Who was John Galt?(Posted 2010) [#11]
Thanks, Rozek. Please look back occasionally. I'm out of my depth here.


Who was John Galt?(Posted 2010) [#12]
Well, one step forward, two steps back...

I was accidentally kicking fmod off in the wrong mode so the buffer was being looped but my callback was only being called once at startup to fill the buffer, hence all the issues about 'not seeing modified variables'. This would have been obvious if debuglog was working from in the callback.

Once I got past that, the program would keep crashing with SIGSEV or 'membit not set' errors, which smell of a GC issue, despite everything being in one thread and trying all the tricks suggested such as using GC enter and GC leave. The only working solution in the end was to not only write the callback in C, but also compile the application as multi-threaded.

It works now, but for some reason there is a latency of 2-3 seconds even though I have cut the streaming buffer length down to 0.25s.