C embedding interface called from multiple threads

question

#1

I’ve spent a few days playing with embedding Julia into C++ signal processing code. My aim is to be able to quickly write prototype code in Julia that is then executed in a real-time audio host.

The problem that I have now encountered is that the real-time audio rendering callback runs in a different thread than the other setup code. So after I have initialized everything that I require for interfacing with the julia code and have disabled garbage collection, I receive the actual real-time thread callback that I’m relaying to julia, which crashes with an access violation in jl_enter_handler.

It turns out that julia tries to access information from the thread local storage. With the audio real-time thread unknown to julia, it does not find an associate local storage and the walks right into accessing uninitialised memory.

Unfortunately, I cannot move my initialisation code to the real-time thread, so I’m not sure how I can proceed. Is there any way to inform julia of the existence of the other thread so that it can allocate the TLS properly? Are there any other options that would allow me to call julia functions from this thread?


#2

Some time ago, I had toyed some code to solve that. Maybe it can be useful to you: https://gist.github.com/cdsousa/473463e9b4e4f57c5b598e6966ca6a21


#3

Also, it may be possible that the parallel task runtime WIP https://github.com/JuliaLang/julia/pull/22631 will help with making Julia embedding interface available from multiple threads. But about that, I’m not sure.


#4

Thank you very much for your response. Unfortunately using a single worker thread to dispatch Julia calls is not an option for me, or at least it would be an option that I would like to avoid if possible.

I would like to stay in the context of the audio thread which runs with real-time priority (which I cannot set for my worker thread, if I used one, because I don’t have the necessary privileges) and blocking the audio thread while I wait for the worker wouldn’t be good because the audio thread might lose the attention of the scheduler. And a spinning lock is probably wasting a lot of CPU time.

I’ll have a look at the parallel task runtime you have referred to. And I will inspect the Julia sources and try to find a way to handle TLS manually, if possible.

Thanks!
Andreas


#5

Maybe you already knew this, but you can call uv_async_send from any thread in C and receive it via AsyncCondition in Julia: https://docs.julialang.org/en/v1.1-dev/manual/calling-c-and-fortran-code/#Thread-safety-1 This handles audio thread-to-Julia part but you would still need to code up Julia-to-audio thread communication. It probably become similar to @cdsousa’s solution in the end but I thought I’d mention uv_async_send anyway.


#6

I don’t think that PR changes anything for non-Julia threads, there is however issue #17573 that is relevant here I think.