Skip to content

Commit

Permalink
Fix: Make fft3w plans threadsafe
Browse files Browse the repository at this point in the history
  • Loading branch information
pinterf committed Mar 23, 2020
1 parent c95dac2 commit ebd4167
Showing 1 changed file with 33 additions and 14 deletions.
47 changes: 33 additions & 14 deletions dfttest/dfttest.cpp
Expand Up @@ -22,6 +22,9 @@

/*
Modifications:
2020.03.23 - pinterf
- make fft3w plans thread safe
2018.10.14 - DJATOM
- Fixed one nasty bug, causing crash on non-AVX CPUs.
Expand Down Expand Up @@ -73,6 +76,11 @@
#include "dfttest.h"
#include "dfttest_avx.h"
#include <cassert>
#include <mutex>

// FFTW is not thread-safe, need to guard around its functions (except fftw_execute).
// http://www.fftw.org/fftw3_doc/Thread-safety.html#Thread-safety
static std::mutex fftw_mutex; // defined as static

PVideoFrame __stdcall dfttest::GetFrame(int n, IScriptEnvironment* env)
{
Expand Down Expand Up @@ -1430,12 +1438,18 @@ dfttest::dfttest(PClip _child, bool _Y, bool _U, bool _V, int _ftype, float _sig
createWindow(hw, tmode, tbsize, tosize, twin, tbeta, smode, sbsize, sosize, swin, sbeta);
float* dftgr = (float*)_aligned_malloc(bvolume * sizeof(float), 16);
dftgc = (fftwf_complex*)_aligned_malloc(sizeof(fftwf_complex) * (ccnt + 11), 16);
if (tbsize > 1)
ftg = fftwf_plan_dft_r2c_3d(tbsize, sbsize, sbsize, dftgr, dftgc,
FFTW_PATIENT | FFTW_DESTROY_INPUT);
else
ftg = fftwf_plan_dft_r2c_2d(sbsize, sbsize, dftgr, dftgc,
FFTW_PATIENT | FFTW_DESTROY_INPUT);

// FFTW plan construction and destruction are not thread-safe.
{
std::lock_guard<std::mutex> lock(fftw_mutex);

if (tbsize > 1)
ftg = fftwf_plan_dft_r2c_3d(tbsize, sbsize, sbsize, dftgr, dftgc,
FFTW_PATIENT | FFTW_DESTROY_INPUT);
else
ftg = fftwf_plan_dft_r2c_2d(sbsize, sbsize, dftgr, dftgc,
FFTW_PATIENT | FFTW_DESTROY_INPUT);
}
float wscale = 0.0f;
const float* hwT = hw;
float* dftgrT = dftgr;
Expand Down Expand Up @@ -1493,15 +1507,20 @@ dfttest::dfttest(PClip _child, bool _Y, bool _U, bool _V, int _ftype, float _sig
pmaxs[i] = pmax / wscale;
}
fftwf_complex* ta = (fftwf_complex*)_aligned_malloc(sizeof(fftwf_complex) * (ccnt + 3), 16);
if (tbsize > 1)
// FFTW plan construction and destruction are not thread-safe.
// http://www.fftw.org/fftw3_doc/Thread-safety.html#Thread-safety
{
ft = fftwf_plan_dft_r2c_3d(tbsize, sbsize, sbsize, dftgr, ta, FFTW_PATIENT | FFTW_DESTROY_INPUT);
fti = fftwf_plan_dft_c2r_3d(tbsize, sbsize, sbsize, ta, dftgr, FFTW_PATIENT | FFTW_DESTROY_INPUT);
}
else
{
ft = fftwf_plan_dft_r2c_2d(sbsize, sbsize, dftgr, ta, FFTW_PATIENT | FFTW_DESTROY_INPUT);
fti = fftwf_plan_dft_c2r_2d(sbsize, sbsize, ta, dftgr, FFTW_PATIENT | FFTW_DESTROY_INPUT);
std::lock_guard<std::mutex> lock(fftw_mutex);
if (tbsize > 1)
{
ft = fftwf_plan_dft_r2c_3d(tbsize, sbsize, sbsize, dftgr, ta, FFTW_PATIENT | FFTW_DESTROY_INPUT);
fti = fftwf_plan_dft_c2r_3d(tbsize, sbsize, sbsize, ta, dftgr, FFTW_PATIENT | FFTW_DESTROY_INPUT);
}
else
{
ft = fftwf_plan_dft_r2c_2d(sbsize, sbsize, dftgr, ta, FFTW_PATIENT | FFTW_DESTROY_INPUT);
fti = fftwf_plan_dft_c2r_2d(sbsize, sbsize, ta, dftgr, FFTW_PATIENT | FFTW_DESTROY_INPUT);
}
}
_aligned_free(ta);
_aligned_free(dftgr);
Expand Down

0 comments on commit ebd4167

Please sign in to comment.