summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/lib/general
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-core/src/lib/general')
-rw-r--r--gnuradio-core/src/lib/general/gr_math.h44
-rw-r--r--gnuradio-core/src/lib/general/gri_fft.cc27
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);