How to do locking (with priority inheritance?)?

Hi everyone!

I do not have much experience with locking, and basically zero experience with locking in the JUCE framework, so I was hoping for some advice here. In my situation, there are two threads; the first thread is the Rendering-thread, which of course has a high priority (real-time) and the second thread is the Updating-thread, currently being the JUCE GUI-thread, which has a lower priority.

Now there is a data-structure, which is altered by the Updating-thread and read several times a second by the Rendering-thread. Updates are very fast (sub-microsecond), so what I’d like to have is that the Rendering-thread waits for the Updating-thread to complete it’s update. In this case, a spinlock seems ideal (right?) but I’m afraid that I might run into some priority inversion issues here (where the Updating-thread holds the lock but is never run due to the lower priority). Obviously I would like to stop the Updating-thread from starting new updates while the Rendering-thread is doing its’ thing too.

What would be the ideal solution/lock to fix this? Priority inheritance (temporarily upping the priority of the Updating-thread while it holds the lock) seems ideal here, but is this supported across all operating systems?

Currently I only have one Updating-threads, but I might have several in the future, would this solution be easily extendable?

I think you need to think very carefully about how your data is shared between threads. Your real-time thread should never be waiting on another thread to complete.

Priority inheritance also can’t be relied upon, it’s often disabled in real-time threads.

It sounds like you need either a FIFO or a farbot::NonRealTimeMutatableObject.
Have a watch through this talk by me and @fabian where we go through the real-time problem maze and solutions;
Part 1: https://youtu.be/Q0vrQFyAdWI
Part 2: https://youtu.be/PoZAo2Vikbo

2 Likes

Thanks for your quick reply! A quick response before I’ll have time to watch the videos during the weekend.

I realize that a lock-free implementation would be the ideal situation (in fact, my current implementation is more or less lock-free). But in the current problem I’m facing, my life would be made so much easier if the Rendering-thread would simply wait for the Updating-thread to finish to finish it’s current update. The updates are really small (changing several floats), so the micro or nano-seconds spend there should not be problematic. So is there really not a way to enable the thread inheritance for the real-time thread? Or are there other issues that might come up (e.g. something to do with caching between different cores)?

Oops, I wanted to see the introduction real quick and now I’ve already watched the first one, almost in it’s entirety. Very interesting talk!

I’m doing some visual stuff atm using JUCE. Currently this is still within the GUI thread (as real-time isn’t the biggest issue right now), but of course I’d like to move this to a separate rendering thread at one point. I see that the audio thread is the only real-time thread in JUCE, do you know if it’s possible to start a second real-time thread? Thread::setPriority() says it can only have a priority between 0-10, while the real-time thread has -1.

Do you actually need a real-time thread?
Why can’t you either:
a) Do your processing in the audio thread and hand off the display data to the message thread
b) Hand off the data coming in via the audio thread to another thread (probably via a FIFO) and process there?

You should think of the RT thread as continuously running and being able to complete without ever waiting for anything else.

The good news is scientists, and probably many Tesla shareholders, are predicting that powerful quantum computers will soon be able to pause greenwich mean time. This will allow an infinite calculation to complete without interruption to audio. Assuming you aren’t using daylight saving anyway…

1 Like

Well, my program creates visuals based on music, so I’d say real-time is definitely necessary. One real-time thread would be used to analyze the incoming music, while the other real-time thread would need to be called for every frame (to send necessary commands to the GPU). Seeing that both are time-critical, but are running at a different frequencies, I think having two real-time threads would be the most logical solution. (on multi-cores they could even run at the same time, right?).

In addition, there is another thread that handles user inputs (which would alter small details in the visuals), but that could have a way lower priority. Although it would be nice if it could finish it’s current update before the visual thread would start to read all the values. A FIFO queue has crossed my mind, but for several reasons a lock-based solution would be preferred (if that would be possible of course).