How to analyse ProcessBlock for locks & mutex?

How can I check, if processBlock is running completely lock free?
I’m not any using locks or mutex’ directly. But I don’t know, what’s happing in all the framework/library-code.
Is it possible to profile processBlock an search especiallialy for locks?
I’m working on Win10 and VS2019.

PluginVal can check for allocations on the audio thread. not sure about locking. maybe check it out?

Since you’re probably using JUCE, just add a breakpoint inside the ScopedLock constructor and see if it gets triggered and if the call stack shows that you’re on the Audio Thread.

1 Like

I built some half-ready cross-platform solution to catch allocations on the audio thread with the help of various allocation hook facilities each operating system out there has and I wanted to do some research if catching locks is possible in a similar way. However due to other priorities I haven’t found any spare time to do so in the last months.

For me, the motivation was to investigate if some third party closed source libraries I used in a project do some real-time-critical stuff.

Now what are your exact motivations, do you want to check your own code, the JUCE Framework code, some open source third party JUCE based code, some open source third party code that is not JUCE-based or some closed source third party code? Depending on this there would be different options how to approach your goal.

One other thought, locks play a role if multiple threads are involved. If you are dealing with a third party library, you could check if it spawns new threads at runtime. If it doesn’t and you are only calling the library functions from the audio thread there is very little chance that any locks should slow your audio thread down. But this is more a general thought as I don’t know the context you are in…

Just to be clear, pluginval only checks for allocations via ::new. It doesn’t check for malloc.

There’s other, platform specific tricks that can be used for system calls etc. but I’ve not personally looked in to them in detail.

Interesting – how do you check for new calls in a platform-independent way? However, if you want to catch all allocations, a malloc hook like I used here works great, especially on Windows and MacOS and catches all things that allocate on the lowest possible level, including new, containers like std::vector and of course direct malloc usage and is quite easy to implement – maybe a nice addition to pluginval?

1 Like

If you look at AllocatorInteceptor here: https://github.com/Tracktion/pluginval/blob/master/Source/TestUtilities.h (and in the corresponding cpp file) you can see it’s not too dissimilar from your idea.
There’s two main differences:

  1. I simply override void* operator new (std::size_t) et. al. to catch calls to the default allocator
  2. I use threadlocals in a similar way to your thread ID checking

I have been meaning to check out your tools and see if I can adapt my AllocatorInterceptor to use them as that would certainly catch more misuses of allocations. It’s a fair bit of work though and I’d need Linux support to make it worth while.

Nice ideas though!

Yes, I’m using JUCE. I have tested the breakpoint-solution. It worked, but it’s a little bit of pain in the a**, because the constructor is called very frequently from the message-thread / AudioProcessorValueTree. Is it possible to create a solution, that only stops, when the call comes from the audio-thread?

This seems like a very useful tool to test specific code-portions for allocations. I tested it on the whole audio thread to see if anything is allocated without my knowledge. It gave me a lot of confidence, that I have created “clean” code. It will become part of my pre-release validation routine. thanks for the advice!

I have recognized, that the tool crashes in debug mode with access violation, when allocations take place on other threads, like the message/ui-thread, while testing on the audiothread. Is this normal? When I compile in release, everything works fine.

PluginVal looks like an very interesting and usefull tool. But to be honest, I don’t know exactly what it does. I see it loading my plugin and moving all the parameters. Does it test the plugin in every possible parameter constellation? I’m wondering how to use it to specifically test processBlock. In my case, code only is executed if transport information from a host/daw is available. If there is no transport information available, the plugin stays “passive”.

No this is no intended behaviour… as I said, it still needs a bit of work to implement all Features I want to implement and create a good documentation, however it never crashed this way when I used it. I’d be glad if you could give me some more information, like a call stack of the crash or maybe a PIP recreating the crash to fix it. I’m working mainly on MacOS so my Windows test might not have been exhaustive enough

Sure. I can send you the call-stack when the problem occurs next time. Creating a PIP would be very hard, because the problem seem to occur unmotivated at diffrent places. Should I post here or do you want the data via private message?