Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. Domains: forum.doom9.org / forum.doom9.net / forum.doom9.se |
|
|
#1 | Link |
|
Registered User
Join Date: Jul 2003
Location: India
Posts: 913
|
Global lock for fftwf
I understand that all functions of fftwf dll excepting execute are not thread safe and so need to introduce global guard. avisynth+ has introduced an env-> function that facilitates this. When I google c++ about the Guard lock and mutex it mentioned that these are old and execution takes time. It recommends heap functions. I need help in coding as I do not have that expertise. Also vapourSynth may provide a mechanism for this purpose.
|
|
|
|
|
|
#2 | Link | ||
|
Software Developer
![]() Join Date: Jun 2005
Location: Last House on Slunk Street
Posts: 13,275
|
Quote:
But, for as long as you do have shared buffers, and if threads may need to modify the buffer contents, then proper synchronization is required! The standard synchronization primitive to protect (serialize) access to a shared buffer is a mutex. In C++, this is implemented by the std::mutex class. Furthermore, the C++ (RAII) way to lock/unlock a mutex is std::lock_guard. Now, the FFTW documentation is pretty clear, that all functions, except for fftw_execute(), are not thread-safe and therefore do need explicit synchronization, if you want to access them for different threads: Quote:
You can not change how FFTW works internally, or that most of its functions are not thread-safe. So, there is no way around proper synchronization, in a multi-threaded application. The general pattern would be as follows: Code:
std::mutex g_mutex; // <-- global mutex that must be used (locked) by any thread that wants to call some FFTW function, except for fftw_execute()
void my_thread_safe_wrapper_function()
{
// Locks the mutex here
std::lock_guard<std::mutex> guard(g_mutex);
// Now we can safely call the FFTW function that is *not* thread-safe
fftw_whatever();
// Mutex is automatically unlocked when `guard` goes out of scope
}
Of course, this will only work properly if every call to any of the "problematic" FFTW functions from any thread is protected (synchronized) by such a wrapper function.
__________________
Go to https://standforukraine.com/ to find legitimate Ukrainian Charities 🇺🇦✊ Last edited by LoRd_MuldeR; 17th December 2025 at 00:08. |
||
|
|
|
|
|
#3 | Link |
|
Registered User
Join Date: Jul 2003
Location: India
Posts: 913
|
Many thanks @LoRd_Mulder. I will try. In avisynth+ there is a globl lock code for version 12 and legacy mutex code for earlier versions. for ver 12 IScriptEnvironment pointer env provides a way for global lock. But earlier versions do not. I am therefore confused about the locking process. If you have time can you look into it?
|
|
|
|
|
|
#4 | Link |
|
Registered User
Join Date: Dec 2020
Posts: 100
|
Yu can:
1. use mutex inside getFrame. 2. allocate needed temp buff for each thread: https://github.com/HomeOfVapourSynth....cpp#L335-L393 3. use fmUnordered (vsapi->createVideoFilter): https://www.vapoursynth.com/doc/api/...m-vsfiltermode |
|
|
|
|
|
#5 | Link |
|
Software Developer
![]() Join Date: Jun 2005
Location: Last House on Slunk Street
Posts: 13,275
|
Looking at the example plugin code here:
https://github.com/vapoursynth/vapou...ter_skeleton.c The function VapourSynthPluginInit2() will be called once per plug-in DLL, whereas the function filterCreate() will be called once for each filter instance that is created. To my understanding, filterCreate() could be called multiple times in parallel, e.g., if multiple instances of the filter are created: https://www.vapoursynth.com/doc/apir...e.html#plugins Consequently, even inside your filterCreate() function, you would have to synchronize every access to any FFTW function! (except for fftw_execute(), but this one probably is not used in filterCreate() anyway) Meanwhile, I would assume that your filterGetFrame() function will only need to use one FFTW function, which is fftw_execute(). If that holds true, then no synchronization is needed there. In other words, you create all your FFTW plans once in your filterCreate() function, which must be properly synchronized, but in your actual filterGetFrame() function you just use (via fftw_execute()) the plans that you have already created, so no further synchronization is needed. And, since filterCreate() only happens very rarely (once per instance), you probably do not need to worry about the "performance" of the synchronization primitive (e.g mutex) ![]() ________ Now, which mutex should you use to synchronize on? At the very least, you need to create a single "global" mutex in your plugin DLL, which will be used (locked) by all the filter instances that are created – probably needed only inside the filterCreate() function. But, of course, this will not help, if some other plugin DLL may also call into the FFTW library
__________________
Go to https://standforukraine.com/ to find legitimate Ukrainian Charities 🇺🇦✊ Last edited by LoRd_MuldeR; 19th December 2025 at 17:48. |
|
|
|
|
|
#7 | Link |
|
Registered User
Join Date: Jul 2018
Posts: 594
|
Next time, provide more context so others can understand the problem better - https://github.com/AviSynth/AviSynthPlus/issues/444
|
|
|
|
|
|
#8 | Link | |
|
Registered User
Join Date: Jul 2003
Location: India
Posts: 913
|
Quote:
But in the script one can include in the process two or more such functions. Worried whether I will have any interference between functions. May be I should restrict fftwf to single thread only? |
|
|
|
|
|
|
#9 | Link | |
|
Registered User
Join Date: Oct 2024
Posts: 20
|
Quote:
When all functions (and multiple instances in the script) are called, they are all accessing the same global mutex variable in memory. Therefore, even if different threads run them simultaneously, they will wait for each other. Last edited by yuygfgg; 20th December 2025 at 16:11. |
|
|
|
|
|
|
#10 | Link |
|
Registered User
Join Date: Jul 2003
Location: India
Posts: 913
|
Many thanks @YUYgfgg. In the script its possible that some user may call one function from my plugin that uses mutex for fftwf and another function from a different plugin also using fftwf . The mutexes can be different unless vapourSynth itself provides that global mutex and insists developers to use it for fftwf dll usage. Is my understanding correct?
|
|
|
|
|
|
#11 | Link | |
|
Software Developer
![]() Join Date: Jun 2005
Location: Last House on Slunk Street
Posts: 13,275
|
Quote:
In other words, other plugins don't have a clue about "your" mutex, and they may call into FFTW independently whenever they want ![]() If you synchronize on a mutex that is provided by VapourSynth, then this may work to synchronize with other plugins - but only if all the other plugins happen to synchronize all of their relevant actions (e.g. calls to FFTW functions) on that very same mutex. I don't know if there is some sort of "best practice" that says that all VapourSynth plugins should be doing this. But, in general, you must not make any assumptions about what other plugins might do (or not).
__________________
Go to https://standforukraine.com/ to find legitimate Ukrainian Charities 🇺🇦✊ Last edited by LoRd_MuldeR; 21st December 2025 at 16:55. |
|
|
|
|
|
|
#12 | Link |
|
Professional Code Monkey
Join Date: Jun 2003
Location: Kinnarps Chair
Posts: 2,647
|
What you more or less have to do here is keep your own copy of the fftw library loaded so you can guard things with your own global mutex. Either by simply using static linking or if you use dynamic linking by renaming the dll to a distinct name no one else uses.
Not all solutions are elegant.
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet |
|
|
|
|
|
#13 | Link |
|
Registered User
Join Date: Jul 2003
Location: India
Posts: 913
|
Thanks for explaining and suggestions, if I keep FFTW dlls in my own folder and remove from windows system dll folders, then at runtime it will not work for others as I do dynamic linking. I will define my global mutex as static so that it will ensure that all functionn that plugin run without interfering with each other, In documenttation I will put a cautionary note. If vapourSynth provides a specific mutex for fftw dll then it solves most of the problems.
|
|
|
|
|
|
#14 | Link | |
|
Professional Code Monkey
Join Date: Jun 2003
Location: Kinnarps Chair
Posts: 2,647
|
Quote:
It's a fun quirk you rarely encounter but you have to know about to make this work.
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet |
|
|
|
|
|
|
#15 | Link | |
|
Fighting spam with a fish
Join Date: Sep 2005
Posts: 2,754
|
It would seem that recent versions of FFTW3 may have a solution to this problem: https://www.fftw.org/fftw3_doc/Thread-safety.html
Quote:
|
|
|
|
|
|
|
#16 | Link |
|
Registered User
Join Date: Jul 2003
Location: India
Posts: 913
|
Many thanks @Adub. I will check it. fftw still prefers buffer creation through its malloc. There are other functions of fftw which are also used. All these need to be thread safe. Request @LoRd_MuldeR and @Myrslok also to look into this.
|
|
|
|
|
|
#17 | Link | ||
|
Professional Code Monkey
Join Date: Jun 2003
Location: Kinnarps Chair
Posts: 2,647
|
Quote:
Quote:
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet |
||
|
|
|
![]() |
| Tags |
| c++, fftwf, global lock |
| Thread Tools | Search this Thread |
| Display Modes | |
|
|