X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=gnuradio-core%2Fsrc%2Flib%2Fgeneral%2Fgri_fft.cc;h=e535f28c75ea15aecdc66f0f2caa23b9a3a36aaa;hb=ea29b08aeb54227e6628f655ccfdb96fe4d8c378;hp=17ea89e1324f7061d12ba840bfaec123bfcdbd6f;hpb=09a1e803a9e6587c78d20cdf16891e5295874668;p=debian%2Fgnuradio diff --git a/gnuradio-core/src/lib/general/gri_fft.cc b/gnuradio-core/src/lib/general/gri_fft.cc index 17ea89e1..e535f28c 100644 --- a/gnuradio-core/src/lib/general/gri_fft.cc +++ b/gnuradio-core/src/lib/general/gri_fft.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2003 Free Software Foundation, Inc. + * Copyright 2003,2008 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -29,10 +29,19 @@ #include #include + +boost::mutex & +gri_fft_planner::mutex() +{ + static boost::mutex s_planning_mutex; + + return s_planning_mutex; +} + static char * wisdom_filename () { - static char *filename = ".gr_fftw_wisdom"; + static const char *filename = ".gr_fftw_wisdom"; char *home = getenv ("HOME"); if (home){ @@ -80,6 +89,9 @@ gri_fftw_export_wisdom () gri_fft_complex::gri_fft_complex (int fft_size, bool forward) { + // Hold global mutex during plan construction and destruction. + gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex()); + assert (sizeof (fftwf_complex) == sizeof (gr_complex)); if (fft_size <= 0) @@ -96,10 +108,6 @@ gri_fft_complex::gri_fft_complex (int fft_size, bool forward) throw std::runtime_error ("fftwf_malloc"); } - // FIXME If there's ever a chance that the planning functions - // will be called in multiple threads, we've got to ensure single - // threaded access. They are not thread-safe. - gri_fftw_import_wisdom (); // load prior wisdom from disk d_plan = fftwf_plan_dft_1d (fft_size, reinterpret_cast(d_inbuf), @@ -116,6 +124,9 @@ gri_fft_complex::gri_fft_complex (int fft_size, bool forward) gri_fft_complex::~gri_fft_complex () { + // Hold global mutex during plan construction and destruction. + gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex()); + fftwf_destroy_plan ((fftwf_plan) d_plan); fftwf_free (d_inbuf); fftwf_free (d_outbuf); @@ -131,6 +142,9 @@ gri_fft_complex::execute () gri_fft_real_fwd::gri_fft_real_fwd (int fft_size) { + // Hold global mutex during plan construction and destruction. + gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex()); + assert (sizeof (fftwf_complex) == sizeof (gr_complex)); if (fft_size <= 0) @@ -147,10 +161,6 @@ gri_fft_real_fwd::gri_fft_real_fwd (int fft_size) throw std::runtime_error ("fftwf_malloc"); } - // FIXME If there's ever a chance that the planning functions - // will be called in multiple threads, we've got to ensure single - // threaded access. They are not thread-safe. - gri_fftw_import_wisdom (); // load prior wisdom from disk d_plan = fftwf_plan_dft_r2c_1d (fft_size, d_inbuf, @@ -166,6 +176,9 @@ gri_fft_real_fwd::gri_fft_real_fwd (int fft_size) gri_fft_real_fwd::~gri_fft_real_fwd () { + // Hold global mutex during plan construction and destruction. + gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex()); + fftwf_destroy_plan ((fftwf_plan) d_plan); fftwf_free (d_inbuf); fftwf_free (d_outbuf); @@ -181,6 +194,9 @@ gri_fft_real_fwd::execute () gri_fft_real_rev::gri_fft_real_rev (int fft_size) { + // Hold global mutex during plan construction and destruction. + gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex()); + assert (sizeof (fftwf_complex) == sizeof (gr_complex)); if (fft_size <= 0)