diff options
Diffstat (limited to 'gnuradio-core/src/lib/general')
-rw-r--r-- | gnuradio-core/src/lib/general/gr_math.h | 44 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gri_fft.cc | 27 |
2 files changed, 62 insertions, 9 deletions
diff --git a/gnuradio-core/src/lib/general/gr_math.h b/gnuradio-core/src/lib/general/gr_math.h index 957a0e12a..f1bd208b8 100644 --- a/gnuradio-core/src/lib/general/gr_math.h +++ b/gnuradio-core/src/lib/general/gr_math.h @@ -174,4 +174,48 @@ static inline unsigned int gr_branchless_quad_45deg_slicer(gr_complex x) return gr_branchless_quad_45deg_slicer(x.real(), x.imag()); } +/*! + * \param x any value + * \param pow2 must be a power of 2 + * \returns \p x rounded down to a multiple of \p pow2. + */ +static inline size_t +gr_p2_round_down(size_t x, size_t pow2) +{ + return x & -pow2; +} + +/*! + * \param x any value + * \param pow2 must be a power of 2 + * \returns \p x rounded up to a multiple of \p pow2. + */ +static inline size_t +gr_p2_round_up(size_t x, size_t pow2) +{ + return gr_p2_round_down(x + pow2 - 1, pow2); +} + +/*! + * \param x any value + * \param pow2 must be a power of 2 + * \returns \p x modulo \p pow2. + */ +static inline size_t +gr_p2_modulo(size_t x, size_t pow2) +{ + return x & (pow2 - 1); +} + +/*! + * \param x any value + * \param pow2 must be a power of 2 + * \returns \p pow2 - (\p x modulo \p pow2). + */ +static inline size_t +gr_p2_modulo_neg(size_t x, size_t pow2) +{ + return pow2 - gr_p2_modulo(x, pow2); +} + #endif /* _GR_MATH_H_ */ diff --git a/gnuradio-core/src/lib/general/gri_fft.cc b/gnuradio-core/src/lib/general/gri_fft.cc index 17ea89e13..f6e28e1d1 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 * @@ -28,6 +28,11 @@ #include <stdio.h> #include <cassert> #include <stdexcept> +#include <boost/thread.hpp> + +typedef boost::mutex::scoped_lock scoped_lock; +static boost::mutex s_planning_mutex; + static char * wisdom_filename () @@ -80,6 +85,9 @@ gri_fftw_export_wisdom () gri_fft_complex::gri_fft_complex (int fft_size, bool forward) { + // Hold global mutex during plan construction and destruction. + scoped_lock lock(s_planning_mutex); + assert (sizeof (fftwf_complex) == sizeof (gr_complex)); if (fft_size <= 0) @@ -96,10 +104,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<fftwf_complex *>(d_inbuf), @@ -116,6 +120,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. + scoped_lock lock(s_planning_mutex); + fftwf_destroy_plan ((fftwf_plan) d_plan); fftwf_free (d_inbuf); fftwf_free (d_outbuf); @@ -131,6 +138,9 @@ gri_fft_complex::execute () gri_fft_real_fwd::gri_fft_real_fwd (int fft_size) { + // Hold global mutex during plan construction and destruction. + scoped_lock lock(s_planning_mutex); + assert (sizeof (fftwf_complex) == sizeof (gr_complex)); if (fft_size <= 0) @@ -147,10 +157,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 +172,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. + scoped_lock lock(s_planning_mutex); + fftwf_destroy_plan ((fftwf_plan) d_plan); fftwf_free (d_inbuf); fftwf_free (d_outbuf); |