Log in

View Full Version : Multithreading, CriticalSection & Mutex


jpsdr
5th October 2016, 18:28
Does some people have feedback/master in use of CriticalSection and Mutex ?
From what i've understood on MSDN support on net, CriticalSection and Mutex are the same, except that CriticalSection is "faster". But i'm begining to wonder if they are realy the same.
I've "experienced", and other people also, some "deadlock" which shouldn't occur. Of course, i still think of the possibility of a bug on my side, but the more i look at it, the more i'm also in a deadlock, and don't see why things occurs, unless... there is a misunderstood from my part.
Unless CriticalSection and Mutex are not so exactly the same than i thought.
So, if someone who master them can tell me if there is some kind of subtle difference between them ?
A case where you can still enter when i thought you can't.
:confused:

Myrsloik
5th October 2016, 19:49
Show me the code and I'll take a look at it. And yes, CriticalSection and Mutex should work the same when only used inside one process.

Also this (https://blogs.msdn.microsoft.com/oldnewthing/20050412-47/?p=35923).

jpsdr
5th October 2016, 19:58
The code are on my github, you can see if you want for exemple the NNEDI3 here (https://github.com/jpsdr/NNEDI3).
I don't use the MT version and didn't have time to make experiments for now, but some report deadlock when using prefetch with more than one thread.
My first guest would be the request of the threadpool which is a shared resource which create the deadlock, except that... theoricaly, it shouldn't... I don't see what i'm missing...

Myrsloik
5th October 2016, 20:12
Let me guess... the deadlock only happens with multiple instances of nnedi3 in the same script? (or an MT mode that'll create multiple instances implicitly)

jpsdr
5th October 2016, 20:30
Multiple instance is not an issue, but the MT mode is it seems. This occured since i've created a common/shared threadpool. Before, each instance created its own threadpool, and in this case there was no issue. But with a CPU with a lot of cores, it created an explosion of threads, i've wanted to reduce, and so use a shared resource.
I've made (or at least i thought) all safety to prevent deadlock, but i may still have missed something, or use something not properly.

Myrsloik
6th October 2016, 18:51
Multiple instance is not an issue, but the MT mode is it seems. This occured since i've created a common/shared threadpool. Before, each instance created its own threadpool, and in this case there was no issue. But with a CPU with a lot of cores, it created an explosion of threads, i've wanted to reduce, and so use a shared resource.
I've made (or at least i thought) all safety to prevent deadlock, but i may still have missed something, or use something not properly.

I'm far from an expert at the finer points of avisynth's multithreading but I think this is the general idea of what's happening. You set the filter to be MT multi instance which means something like Prefetch(n) instances of your filter will be created automatically. Since the threadpool is at file scope it'll be shared between all instances so effectively the CriticalSection here (https://github.com/jpsdr/NNEDI3/blob/master/nnedi3/nnedi3.cpp#L711) will not guard a single operation that happens on the threadpool. Since no other data is shared you can simply remove it. Won't ever be needed.

So it's obviously something wrong inside the threadpool. If I'm not mistaken UserId is always 0 which seems to make the pool simply ignore a lot of stuff. Why is RequestThreadPool called at all? it doesn't do anything in your case?

I simply can't follow your code at all. Too many features in your pool and too many code paths. In many places things are checked 3 times before actual operations. You may think you're clever checking things outside the lock and then inside again but this is just a waste of time unless you intend to feed it with invalid data all day at an amazing speed.

You really should try listing the features you need and do nothing else if you really want to write your own solution. Or at least use RAII (http://en.cppreference.com/w/cpp/language/raii) around locks because this stuff becomes unmanagable very quickly.

jpsdr
6th October 2016, 19:17
I think maybe i found something...