From 9bc91123c6a290c75f1acb3b30d7c3336b8ed8f3 Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Wed, 13 Nov 2013 11:12:06 +0100 Subject: [PATCH] fixed thread safety issue in FFT-based Bitmap::convolve --- src/libcore/bitmap.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/libcore/bitmap.cpp b/src/libcore/bitmap.cpp index 4cac5795..633a33aa 100644 --- a/src/libcore/bitmap.cpp +++ b/src/libcore/bitmap.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #if defined(__WINDOWS__) #undef _CRT_SECURE_NO_WARNINGS @@ -591,6 +592,10 @@ void Bitmap::accumulate(const Bitmap *bitmap, Point2i sourceOffset, } } +#if defined(MTS_HAS_FFTW) +static boost::mutex __fftw_lock; +#endif + void Bitmap::convolve(const Bitmap *_kernel) { if (_kernel->getWidth() != _kernel->getHeight()) Log(EError, "Bitmap::convolve(): convolution kernel must be square!"); @@ -617,17 +622,21 @@ void Bitmap::convolve(const Bitmap *_kernel) { paddedHeight = height + hKernelSize, paddedSize = paddedWidth*paddedHeight; + __fftw_lock.lock(); complex *kernel = (complex *) fftw_malloc(sizeof(complex) * paddedSize), *kernelS = (complex *) fftw_malloc(sizeof(complex) * paddedSize), *data = (complex *) fftw_malloc(sizeof(complex) * paddedSize), *dataS = (complex *) fftw_malloc(sizeof(complex) * paddedSize); - if (!kernel || !kernelS || !data || !dataS) + if (!kernel || !kernelS || !data || !dataS) { + __fftw_lock.unlock(); SLog(EError, "Bitmap::convolve(): Unable to allocate temporary memory!"); + } /* Create a FFTW plan for a 2D DFT of this size */ fftw_plan p = fftw_plan_dft_2d((int) paddedHeight, (int) paddedWidth, (fftw_complex *) kernel, (fftw_complex *) kernelS, FFTW_FORWARD, FFTW_ESTIMATE); + __fftw_lock.unlock(); memset(kernel, 0, sizeof(complex)*paddedSize); @@ -730,11 +739,13 @@ void Bitmap::convolve(const Bitmap *_kernel) { Log(EError, "Unsupported component format!"); } } + __fftw_lock.lock(); fftw_destroy_plan(p); fftw_free(kernel); fftw_free(kernelS); fftw_free(data); fftw_free(dataS); + __fftw_lock.unlock(); #else /* Brute force fallback version */ uint8_t *output_ = static_cast(allocAligned(getBufferSize()));