summaryrefslogtreecommitdiff
path: root/gnuradio-runtime
diff options
context:
space:
mode:
authorMarcus Müller <marcus.mueller@ettus.com>2018-03-30 20:50:04 +0200
committerMarcus Müller <marcus.mueller@ettus.com>2018-03-30 20:50:04 +0200
commit61c0382eb2935a6da6c81bd93c8b9c8ef2893df2 (patch)
tree5e67df4059f5522ccc62cd85f33100ee96bb7988 /gnuradio-runtime
parent9a6bf484394f5954483477856f6a6712331b9ee6 (diff)
parent20d463d138782fd56397f5324be6e34af156b239 (diff)
Merge branch 'maint' through 'last_merge_to_master'
This is the last time we're merging 'maint' to 'master'. The 'maint' branch will cease to exist shortly; we'll have a 'maint-3.7' branch. For further information on the new development model: http://lists.gnu.org/archive/html/discuss-gnuradio/2018-02/msg00133.html
Diffstat (limited to 'gnuradio-runtime')
-rw-r--r--gnuradio-runtime/include/gnuradio/py_feval.h1
-rw-r--r--gnuradio-runtime/include/gnuradio/sys_pri.h10
-rw-r--r--gnuradio-runtime/include/gnuradio/xoroshiro128p.h103
-rw-r--r--gnuradio-runtime/lib/math/random.cc18
-rw-r--r--gnuradio-runtime/lib/pmt/pmt.cc8
-rw-r--r--gnuradio-runtime/python/gnuradio/eng_notation.py23
6 files changed, 136 insertions, 27 deletions
diff --git a/gnuradio-runtime/include/gnuradio/py_feval.h b/gnuradio-runtime/include/gnuradio/py_feval.h
index cef168c8f0..89491af0b4 100644
--- a/gnuradio-runtime/include/gnuradio/py_feval.h
+++ b/gnuradio-runtime/include/gnuradio/py_feval.h
@@ -23,6 +23,7 @@
#ifndef INCLUDED_GR_PY_FEVAL_H
#define INCLUDED_GR_PY_FEVAL_H
+#include <Python.h>
#include <pmt/pmt.h>
#include <gnuradio/feval.h>
diff --git a/gnuradio-runtime/include/gnuradio/sys_pri.h b/gnuradio-runtime/include/gnuradio/sys_pri.h
index adceb91b9d..d251455a11 100644
--- a/gnuradio-runtime/include/gnuradio/sys_pri.h
+++ b/gnuradio-runtime/include/gnuradio/sys_pri.h
@@ -23,7 +23,7 @@
#define INCLUDED_GNURADIO_SYS_PRI_H
#include <gnuradio/api.h>
-#include <realtime.h>
+#include <gnuradio/realtime.h>
/*
* A single place to define real-time priorities used by the system itself
@@ -31,10 +31,10 @@
namespace gr {
struct GR_RUNTIME_API sys_pri {
- static rt_sched_param python(); // python code
- static rt_sched_param normal(); // normal blocks
- static rt_sched_param gcell_event_handler();
- static rt_sched_param usrp2_backend(); // thread that services the ethernet
+ static struct GR_RUNTIME_API rt_sched_param python(); // python code
+ static struct GR_RUNTIME_API rt_sched_param normal(); // normal blocks
+ static struct GR_RUNTIME_API rt_sched_param gcell_event_handler();
+ static struct GR_RUNTIME_API rt_sched_param usrp2_backend(); // thread that services the ethernet
};
} /* namespace gr */
diff --git a/gnuradio-runtime/include/gnuradio/xoroshiro128p.h b/gnuradio-runtime/include/gnuradio/xoroshiro128p.h
new file mode 100644
index 0000000000..b3e6dcb12d
--- /dev/null
+++ b/gnuradio-runtime/include/gnuradio/xoroshiro128p.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// Built on XOROSHIRO128+ by David Blackman and Sebastiano Vigna who put this
+// under CC-0, colloquially known as "public domain (or as close you get to that
+// in your local legislation)" see
+// http://xoroshiro.di.unimi.it/xoroshiro128plus.c
+// Conversion to a local state (original used global state) done by Marcus
+// Müller, 2018.
+#ifndef INCLUDED_XOROSHIRO128P_H
+#define INCLUDED_XOROSHIRO128P_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+/*! \brief rotating left shift helper
+ * According to the original authors, this will on most platforms reduce to a single instruction
+ */
+static inline uint64_t rotl(const uint64_t x, const int k) {
+ return (x << k) | (x >> (64 - k));
+}
+
+
+/*! \brief generate the next random number and update the state.
+ * This is the workhorse, here!
+ */
+static inline uint64_t xoroshiro128p_next(uint64_t *state) {
+ const uint64_t s0 = state[0];
+ uint64_t s1 = state[1];
+ const uint64_t result = s0 + s1;
+
+ s1 ^= s0;
+ state[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b
+ state[1] = rotl(s1, 36); // c
+
+ return result;
+}
+
+
+/*! \brief Advance the internal state by 2^64 steps; useful when coordinating multiple independent RNGs
+ This is the jump function for the generator. It is equivalent
+ to 2^64 calls to next(); it can be used to generate 2^64
+ non-overlapping subsequences for parallel computations. */
+static inline void xoroshiro128p_jump(uint64_t *state) {
+ static const uint64_t JUMP[] = { 0xbeac0467eba5facb, 0xd86b048b86aa9922 };
+
+ uint64_t s0 = 0;
+ uint64_t s1 = 0;
+ for(unsigned int i = 0; i < sizeof (JUMP) / sizeof (*JUMP); ++i) {
+ for(unsigned int b = 0; b < 64; ++b) {
+ if (JUMP[i] & UINT64_C(1) << b) {
+ s0 ^= state[0];
+ s1 ^= state[1];
+ }
+ xoroshiro128p_next(state);
+ }
+ }
+
+ state[0] = s0;
+ state[1] = s1;
+}
+
+/*! \brief step of the SPLITMIX64 RNG; only used internally for seeding
+ * This RNG isn't as good as XOROSHIRO128+, so it's only used to initialize a 128 bit state from a seed.
+ */
+static inline uint64_t splitmix64_next(uint64_t *state) {
+ uint64_t z = (*state += 0x9e3779b97f4a7c15);
+ z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
+ z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
+ return z ^ (z >> 31);
+}
+
+/*! \brief Seed the 128 bit state from a 64 bit seed
+ */
+static inline void xoroshiro128p_seed(uint64_t *state, const uint64_t seed) {
+ state[0] = seed;
+ state[1] = splitmix64_next(state);
+ xoroshiro128p_jump(state);
+}
+#ifdef __cplusplus
+}
+#endif
+#endif // Include guard
diff --git a/gnuradio-runtime/lib/math/random.cc b/gnuradio-runtime/lib/math/random.cc
index 401ba89735..cedaf4b97f 100644
--- a/gnuradio-runtime/lib/math/random.cc
+++ b/gnuradio-runtime/lib/math/random.cc
@@ -73,9 +73,12 @@ namespace gr {
void
random::reseed(unsigned int seed)
{
- if(seed==0) d_seed = static_cast<unsigned int>(std::time(0));
- else d_seed = seed;
- d_rng->seed(d_seed);
+ d_seed = seed;
+ if (d_seed == 0){
+ d_rng->seed();
+ } else {
+ d_rng->seed(d_seed);
+ }
// reinstantiate generators. Otherwise reseed doesn't take effect.
delete d_generator;
d_generator = new boost::variate_generator<boost::mt19937&, boost::uniform_real<float> > (*d_rng,*d_uniform); // create number generator in [0,1) from boost.random
@@ -138,11 +141,12 @@ namespace gr {
float
random::laplacian()
{
- float z = ran1()-0.5;
- if(z>0) return -logf(1-2*z);
- else return logf(1+2*z);
+ float z = ran1();
+ if (z > 0.5f){
+ return -logf(2.0f * (1.0f - z) );
+ }
+ return logf(2 * z);
}
-
/*
* Copied from The KC7WW / OH2BNS Channel Simulator
* FIXME Need to check how good this is at some point
diff --git a/gnuradio-runtime/lib/pmt/pmt.cc b/gnuradio-runtime/lib/pmt/pmt.cc
index 3b92481549..0fe4dbde8e 100644
--- a/gnuradio-runtime/lib/pmt/pmt.cc
+++ b/gnuradio-runtime/lib/pmt/pmt.cc
@@ -1158,12 +1158,12 @@ equal(const pmt_t& x, const pmt_t& y)
return false;
size_t len_x, len_y;
- if (memcmp(xv->uniform_elements(len_x),
- yv->uniform_elements(len_y),
- len_x) == 0)
+ const void *x_m = xv->uniform_elements(len_x);
+ const void *y_m = yv->uniform_elements(len_y);
+ if (memcmp(x_m, y_m, len_x) == 0)
return true;
- return true;
+ return false;
}
// FIXME add other cases here...
diff --git a/gnuradio-runtime/python/gnuradio/eng_notation.py b/gnuradio-runtime/python/gnuradio/eng_notation.py
index d23f9005f0..12332aef7d 100644
--- a/gnuradio-runtime/python/gnuradio/eng_notation.py
+++ b/gnuradio-runtime/python/gnuradio/eng_notation.py
@@ -36,29 +36,30 @@ scale_factor['p'] = 1e-12
scale_factor['f'] = 1e-15
scale_factor['a'] = 1e-18
-def num_to_str (n):
+def num_to_str (n, precision=6):
'''Convert a number to a string in engineering notation. E.g., 5e-9 -> 5n'''
m = abs(n)
+ format_spec = '%.' + repr(int(precision)) + 'g'
if m >= 1e9:
- return "%gG" % (n * 1e-9)
+ return '%sG' % float(format_spec % (n * 1e-9))
elif m >= 1e6:
- return "%gM" % (n * 1e-6)
+ return '%sM' % float(format_spec % (n * 1e-6))
elif m >= 1e3:
- return "%gk" % (n * 1e-3)
+ return '%sk' % float(format_spec % (n * 1e-3))
elif m >= 1:
- return "%g" % (n)
+ return '%s' % float(format_spec % (n))
elif m >= 1e-3:
- return "%gm" % (n * 1e3)
+ return '%sm' % float(format_spec % (n * 1e3))
elif m >= 1e-6:
- return "%gu" % (n * 1e6) # where's that mu when you need it (unicode?)
+ return '%su' % float(format_spec % (n * 1e6))
elif m >= 1e-9:
- return "%gn" % (n * 1e9)
+ return '%sn' % float(format_spec % (n * 1e9))
elif m >= 1e-12:
- return "%gp" % (n * 1e12)
+ return '%sp' % float(format_spec % (n * 1e12))
elif m >= 1e-15:
- return "%gf" % (n * 1e15)
+ return '%sf' % float(format_spec % (n * 1e15))
else:
- return "%g" % (n)
+ return '%s' % float(format_spec % (n))
def str_to_num (value):