summaryrefslogtreecommitdiff
path: root/gruel/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'gruel/src/include')
-rw-r--r--gruel/src/include/gruel/CMakeLists.txt39
-rw-r--r--gruel/src/include/gruel/api.h33
-rw-r--r--gruel/src/include/gruel/attributes.h74
-rw-r--r--gruel/src/include/gruel/high_res_timer.h124
-rw-r--r--gruel/src/include/gruel/msg_accepter.h53
-rw-r--r--gruel/src/include/gruel/msg_accepter_msgq.h50
-rw-r--r--gruel/src/include/gruel/msg_passing.h116
-rw-r--r--gruel/src/include/gruel/msg_queue.h91
-rw-r--r--gruel/src/include/gruel/pmt.h864
-rw-r--r--gruel/src/include/gruel/pmt_pool.h73
-rw-r--r--gruel/src/include/gruel/pmt_sugar.h171
-rw-r--r--gruel/src/include/gruel/realtime.h96
-rw-r--r--gruel/src/include/gruel/sys_pri.h42
-rw-r--r--gruel/src/include/gruel/thread.h139
-rw-r--r--gruel/src/include/gruel/thread_body_wrapper.h69
-rw-r--r--gruel/src/include/gruel/thread_group.h45
16 files changed, 2079 insertions, 0 deletions
diff --git a/gruel/src/include/gruel/CMakeLists.txt b/gruel/src/include/gruel/CMakeLists.txt
new file mode 100644
index 000000000..d4c36eddb
--- /dev/null
+++ b/gruel/src/include/gruel/CMakeLists.txt
@@ -0,0 +1,39 @@
+# Copyright 2010-2012 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.
+
+########################################################################
+# Install the headers
+########################################################################
+install(FILES
+ api.h
+ attributes.h
+ high_res_timer.h
+ msg_accepter.h
+ msg_accepter_msgq.h
+ msg_queue.h
+ msg_passing.h
+ pmt.h
+ pmt_pool.h
+ pmt_sugar.h
+ realtime.h
+ sys_pri.h
+ thread_body_wrapper.h
+ thread_group.h
+ thread.h
+DESTINATION ${GR_INCLUDE_DIR}/gruel COMPONENT "gruel_devel")
diff --git a/gruel/src/include/gruel/api.h b/gruel/src/include/gruel/api.h
new file mode 100644
index 000000000..945814d43
--- /dev/null
+++ b/gruel/src/include/gruel/api.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010 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.
+ */
+
+#ifndef INCLUDED_GRUEL_API_H
+#define INCLUDED_GRUEL_API_H
+
+#include <gruel/attributes.h>
+
+#ifdef gruel_EXPORTS
+# define GRUEL_API __GR_ATTR_EXPORT
+#else
+# define GRUEL_API __GR_ATTR_IMPORT
+#endif
+
+#endif /* INCLUDED_GRUEL_API_H */
diff --git a/gruel/src/include/gruel/attributes.h b/gruel/src/include/gruel/attributes.h
new file mode 100644
index 000000000..baa5521c8
--- /dev/null
+++ b/gruel/src/include/gruel/attributes.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2010 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.
+ */
+
+#ifndef INCLUDED_GRUEL_ATTRIBUTES_H
+#define INCLUDED_GRUEL_ATTRIBUTES_H
+
+////////////////////////////////////////////////////////////////////////
+// Cross-platform attribute macros
+////////////////////////////////////////////////////////////////////////
+#if defined __GNUC__
+# define __GR_ATTR_ALIGNED(x) __attribute__((aligned(x)))
+# define __GR_ATTR_UNUSED __attribute__((unused))
+# define __GR_ATTR_INLINE __attribute__((always_inline))
+# define __GR_ATTR_DEPRECATED __attribute__((deprecated))
+# if __GNUC__ >= 4
+# define __GR_ATTR_EXPORT __attribute__((visibility("default")))
+# define __GR_ATTR_IMPORT __attribute__((visibility("default")))
+# else
+# define __GR_ATTR_EXPORT
+# define __GR_ATTR_IMPORT
+# endif
+#elif _MSC_VER
+# define __GR_ATTR_ALIGNED(x) __declspec(align(x))
+# define __GR_ATTR_UNUSED
+# define __GR_ATTR_INLINE __forceinline
+# define __GR_ATTR_DEPRECATED __declspec(deprecated)
+# define __GR_ATTR_EXPORT __declspec(dllexport)
+# define __GR_ATTR_IMPORT __declspec(dllimport)
+#else
+# define __GR_ATTR_ALIGNED(x)
+# define __GR_ATTR_UNUSED
+# define __GR_ATTR_INLINE
+# define __GR_ATTR_DEPRECATED
+# define __GR_ATTR_EXPORT
+# define __GR_ATTR_IMPORT
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// define inline when building C
+////////////////////////////////////////////////////////////////////////
+#if defined(_MSC_VER) && !defined(__cplusplus) && !defined(inline)
+# define inline __inline
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// suppress warnings
+////////////////////////////////////////////////////////////////////////
+#ifdef _MSC_VER
+# pragma warning(disable: 4251) // class 'A<T>' needs to have dll-interface to be used by clients of class 'B'
+# pragma warning(disable: 4275) // non dll-interface class ... used as base for dll-interface class ...
+# pragma warning(disable: 4244) // conversion from 'double' to 'float', possible loss of data
+# pragma warning(disable: 4305) // 'initializing' : truncation from 'double' to 'float'
+# pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
+#endif
+
+#endif /* INCLUDED_GRUEL_ATTRIBUTES_H */
diff --git a/gruel/src/include/gruel/high_res_timer.h b/gruel/src/include/gruel/high_res_timer.h
new file mode 100644
index 000000000..a885520b6
--- /dev/null
+++ b/gruel/src/include/gruel/high_res_timer.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2011 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GRUEL_HIGH_RES_TIMER_H
+#define INCLUDED_GRUEL_HIGH_RES_TIMER_H
+
+namespace gruel {
+ //! Typedef for the timer tick count
+ typedef signed long long high_res_timer_type;
+
+ //! Get the current time in ticks
+ high_res_timer_type high_res_timer_now(void);
+
+ //! Get the number of ticks per second
+ high_res_timer_type high_res_timer_tps(void);
+
+ //! Get the tick count at the epoch
+ high_res_timer_type high_res_timer_epoch(void);
+
+} /* namespace gruel */
+
+////////////////////////////////////////////////////////////////////////
+// Use architecture defines to determine the implementation
+////////////////////////////////////////////////////////////////////////
+#if defined(linux) || defined(__linux) || defined(__linux__)
+ #define GRUEL_HRT_USE_CLOCK_GETTIME
+#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+ #define GRUEL_HRT_USE_QUERY_PERFORMANCE_COUNTER
+#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+ #define GRUEL_HRT_USE_MACH_ABSOLUTE_TIME
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+ #define GRUEL_HRT_USE_CLOCK_GETTIME
+#else
+ #define GRUEL_HRT_USE_MICROSEC_CLOCK
+#endif
+
+////////////////////////////////////////////////////////////////////////
+#ifdef GRUEL_HRT_USE_CLOCK_GETTIME
+ #include <ctime>
+
+ inline gruel::high_res_timer_type gruel::high_res_timer_now(void){
+ timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return ts.tv_sec*high_res_timer_tps() + ts.tv_nsec;
+ }
+
+ inline gruel::high_res_timer_type gruel::high_res_timer_tps(void){
+ return 1000000000UL;
+ }
+#endif /* GRUEL_HRT_USE_CLOCK_GETTIME */
+
+////////////////////////////////////////////////////////////////////////
+#ifdef GRUEL_HRT_USE_MACH_ABSOLUTE_TIME
+ #include <mach/mach_time.h>
+
+ inline gruel::high_res_timer_type gruel::high_res_timer_now(void){
+ return mach_absolute_time();
+ }
+
+ inline gruel::high_res_timer_type gruel::high_res_timer_tps(void){
+ mach_timebase_info_data_t info;
+ mach_timebase_info(&info);
+ return gruel::high_res_timer_type(info.numer*1000000000UL)/info.denom;
+ }
+#endif
+
+////////////////////////////////////////////////////////////////////////
+#ifdef GRUEL_HRT_USE_QUERY_PERFORMANCE_COUNTER
+ #include <Windows.h>
+
+ inline gruel::high_res_timer_type gruel::high_res_timer_now(void){
+ LARGE_INTEGER counts;
+ QueryPerformanceCounter(&counts);
+ return counts.QuadPart;
+ }
+
+ inline gruel::high_res_timer_type gruel::high_res_timer_tps(void){
+ LARGE_INTEGER freq;
+ QueryPerformanceFrequency(&freq);
+ return freq.QuadPart;
+ }
+#endif
+
+////////////////////////////////////////////////////////////////////////
+#ifdef GRUEL_HRT_USE_MICROSEC_CLOCK
+ #include <boost/date_time/posix_time/posix_time.hpp>
+
+ inline gruel::high_res_timer_type gruel::high_res_timer_now(void){
+ static const boost::posix_time::ptime epoch(boost::posix_time::from_time_t(0));
+ return (boost::posix_time::microsec_clock::universal_time() - epoch).ticks();
+ }
+
+ inline gruel::high_res_timer_type gruel::high_res_timer_tps(void){
+ return boost::posix_time::time_duration::ticks_per_second();
+ }
+#endif
+
+////////////////////////////////////////////////////////////////////////
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+inline gruel::high_res_timer_type gruel::high_res_timer_epoch(void){
+ static const double hrt_ticks_per_utc_ticks = gruel::high_res_timer_tps()/double(boost::posix_time::time_duration::ticks_per_second());
+ boost::posix_time::time_duration utc = boost::posix_time::microsec_clock::universal_time() - boost::posix_time::from_time_t(0);
+ return gruel::high_res_timer_now() - utc.ticks()*hrt_ticks_per_utc_ticks;
+}
+
+#endif /* INCLUDED_GRUEL_HIGH_RES_TIMER_H */
diff --git a/gruel/src/include/gruel/msg_accepter.h b/gruel/src/include/gruel/msg_accepter.h
new file mode 100644
index 000000000..45acb3c78
--- /dev/null
+++ b/gruel/src/include/gruel/msg_accepter.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GRUEL_MSG_ACCEPTER_H
+#define INCLUDED_GRUEL_MSG_ACCEPTER_H
+
+#include <gruel/api.h>
+#include <gruel/pmt.h>
+#include <boost/shared_ptr.hpp>
+
+namespace gruel {
+
+ /*!
+ * \brief Virtual base class that accepts messages
+ */
+ class GRUEL_API msg_accepter
+ {
+ public:
+ msg_accepter() {};
+ virtual ~msg_accepter();
+
+ /*!
+ * \brief send \p msg to \p msg_accepter on port \p which_port
+ *
+ * Sending a message is an asynchronous operation. The \p post
+ * call will not wait for the message either to arrive at the
+ * destination or to be received.
+ */
+ virtual void post(pmt::pmt_t which_port, pmt::pmt_t msg) = 0;
+ };
+
+ typedef boost::shared_ptr<msg_accepter> msg_accepter_sptr;
+
+} /* namespace gruel */
+
+#endif /* INCLUDED_GRUEL_MSG_ACCEPTER_H */
diff --git a/gruel/src/include/gruel/msg_accepter_msgq.h b/gruel/src/include/gruel/msg_accepter_msgq.h
new file mode 100644
index 000000000..6b9bcf4db
--- /dev/null
+++ b/gruel/src/include/gruel/msg_accepter_msgq.h
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_MSG_ACCEPTER_MSGQ_H
+#define INCLUDED_MSG_ACCEPTER_MSGQ_H
+
+#include <gruel/api.h>
+#include <gruel/msg_accepter.h>
+#include <gruel/msg_queue.h>
+
+namespace gruel {
+
+ /*!
+ * \brief Concrete class that accepts messages and inserts them into a message queue.
+ */
+ class GRUEL_API msg_accepter_msgq : public msg_accepter
+ {
+ protected:
+ msg_queue_sptr d_msg_queue;
+
+ public:
+ msg_accepter_msgq(msg_queue_sptr msgq);
+ ~msg_accepter_msgq();
+
+ virtual void post(pmt::pmt_t msg);
+
+ msg_queue_sptr msg_queue() const { return d_msg_queue; }
+ };
+
+} /* namespace gruel */
+
+#endif /* INCLUDED_MSG_ACCEPTER_MSGQ_H */
diff --git a/gruel/src/include/gruel/msg_passing.h b/gruel/src/include/gruel/msg_passing.h
new file mode 100644
index 000000000..25f30118f
--- /dev/null
+++ b/gruel/src/include/gruel/msg_passing.h
@@ -0,0 +1,116 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GRUEL_MSG_PASSING_H
+#define INCLUDED_GRUEL_MSG_PASSING_H
+
+/*!
+ * \brief Include this header to use the message passing features
+ */
+
+#include <gruel/api.h>
+#include <gruel/pmt.h>
+#include <gruel/msg_accepter.h>
+
+
+namespace gruel {
+
+ /*!
+ * \brief send message to msg_accepter
+ *
+ * \param accepter is the target of the send.
+ * \param which_port A pmt symbol describing the port by name.
+ * \param msg is the message to send. It's usually a pmt tuple.
+ *
+ * Sending a message is an asynchronous operation. The \p send
+ * call will not wait for the message either to arrive at the
+ * destination or to be received.
+ *
+ * \returns msg
+ */
+ static inline pmt::pmt_t
+ send(msg_accepter_sptr accepter, const pmt::pmt_t &which_port, const pmt::pmt_t &msg)
+ {
+ accepter->post(which_port, msg);
+ return msg;
+ }
+
+ /*!
+ * \brief send message to msg_accepter
+ *
+ * \param accepter is the target of the send.
+ * \param which_port A pmt symbol describing the port by name.
+ * \param msg is the message to send. It's usually a pmt tuple.
+ *
+ * Sending a message is an asynchronous operation. The \p send
+ * call will not wait for the message either to arrive at the
+ * destination or to be received.
+ *
+ * \returns msg
+ */
+ static inline pmt::pmt_t
+ send(msg_accepter *accepter, const pmt::pmt_t &which_port, const pmt::pmt_t &msg)
+ {
+ accepter->post(which_port, msg);
+ return msg;
+ }
+
+ /*!
+ * \brief send message to msg_accepter
+ *
+ * \param accepter is the target of the send.
+ * \param which_port A pmt symbol describing the port by name.
+ * \param msg is the message to send. It's usually a pmt tuple.
+ *
+ * Sending a message is an asynchronous operation. The \p send
+ * call will not wait for the message either to arrive at the
+ * destination or to be received.
+ *
+ * \returns msg
+ */
+ static inline pmt::pmt_t
+ send(msg_accepter &accepter, const pmt::pmt_t &which_port, const pmt::pmt_t &msg)
+ {
+ accepter.post(which_port, msg);
+ return msg;
+ }
+
+ /*!
+ * \brief send message to msg_accepter
+ *
+ * \param accepter is the target of the send. precond: pmt_is_msg_accepter(accepter)
+ * \param which_port A pmt symbol describing the port by name.
+ * \param msg is the message to send. It's usually a pmt tuple.
+ *
+ * Sending a message is an asynchronous operation. The \p send
+ * call will not wait for the message either to arrive at the
+ * destination or to be received.
+ *
+ * \returns msg
+ */
+ static inline pmt::pmt_t
+ send(pmt::pmt_t accepter, const pmt::pmt_t &which_port, const pmt::pmt_t &msg)
+ {
+ return send(pmt_msg_accepter_ref(accepter), which_port, msg);
+ }
+
+} /* namespace gruel */
+
+#endif /* INCLUDED_GRUEL_MSG_PASSING_H */
diff --git a/gruel/src/include/gruel/msg_queue.h b/gruel/src/include/gruel/msg_queue.h
new file mode 100644
index 000000000..f038ca325
--- /dev/null
+++ b/gruel/src/include/gruel/msg_queue.h
@@ -0,0 +1,91 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+#ifndef INCLUDED_MSG_QUEUE_H
+#define INCLUDED_MSG_QUEUE_H
+
+#include <gruel/api.h>
+#include <gruel/thread.h>
+#include <gruel/pmt.h>
+#include <deque>
+
+namespace gruel {
+
+ class msg_queue;
+ typedef boost::shared_ptr<msg_queue> msg_queue_sptr;
+
+ msg_queue_sptr make_msg_queue(unsigned int limit=0);
+
+ /*!
+ * \brief thread-safe message queue
+ */
+ class GRUEL_API msg_queue {
+
+ gruel::mutex d_mutex;
+ gruel::condition_variable d_not_empty;
+ gruel::condition_variable d_not_full;
+ unsigned int d_limit; // max # of messages in queue. 0 -> unbounded
+
+ std::deque<pmt::pmt_t> d_msgs;
+
+ public:
+ msg_queue(unsigned int limit);
+ ~msg_queue();
+
+ /*!
+ * \brief Insert message at tail of queue.
+ * \param msg message
+ *
+ * Block if queue if full.
+ */
+ void insert_tail(pmt::pmt_t msg);
+
+ /*!
+ * \brief Delete message from head of queue and return it.
+ * Block if no message is available.
+ */
+ pmt::pmt_t delete_head();
+
+ /*!
+ * \brief If there's a message in the q, delete it and return it.
+ * If no message is available, return pmt_t().
+ */
+ pmt::pmt_t delete_head_nowait();
+
+ //! Delete all messages from the queue
+ void flush();
+
+ //! is the queue empty?
+ bool empty_p() const { return d_msgs.empty(); }
+
+ //! is the queue full?
+ bool full_p() const { return d_limit != 0 && count() >= d_limit; }
+
+ //! return number of messages in queue
+ unsigned int count() const { return d_msgs.size(); }
+
+ //! return limit on number of message in queue. 0 -> unbounded
+ unsigned int limit() const { return d_limit; }
+ };
+
+} /* namespace gruel */
+
+#endif /* INCLUDED_MSG_QUEUE_H */
diff --git a/gruel/src/include/gruel/pmt.h b/gruel/src/include/gruel/pmt.h
new file mode 100644
index 000000000..383a1d44d
--- /dev/null
+++ b/gruel/src/include/gruel/pmt.h
@@ -0,0 +1,864 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2010 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.
+ */
+
+#ifndef INCLUDED_PMT_H
+#define INCLUDED_PMT_H
+
+#include <gruel/api.h>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/any.hpp>
+#include <complex>
+#include <string>
+#include <stdint.h>
+#include <iosfwd>
+#include <stdexcept>
+#include <vector>
+
+namespace gruel {
+ class msg_accepter;
+};
+
+/*!
+ * This file defines a polymorphic type and the operations on it.
+ *
+ * It draws heavily on the idea of scheme and lisp data types.
+ * The interface parallels that in Guile 1.8, with the notable
+ * exception that these objects are transparently reference counted.
+ */
+
+namespace pmt {
+
+/*!
+ * \brief base class of all pmt types
+ */
+class pmt_base;
+
+/*!
+ * \brief typedef for shared pointer (transparent reference counting).
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ */
+typedef boost::intrusive_ptr<pmt_base> pmt_t;
+
+extern GRUEL_API void intrusive_ptr_add_ref(pmt_base*);
+extern GRUEL_API void intrusive_ptr_release(pmt_base*);
+
+class GRUEL_API pmt_exception : public std::logic_error
+{
+public:
+ pmt_exception(const std::string &msg, pmt_t obj);
+};
+
+class GRUEL_API pmt_wrong_type : public pmt_exception
+{
+public:
+ pmt_wrong_type(const std::string &msg, pmt_t obj);
+};
+
+class GRUEL_API pmt_out_of_range : public pmt_exception
+{
+public:
+ pmt_out_of_range(const std::string &msg, pmt_t obj);
+};
+
+class GRUEL_API pmt_notimplemented : public pmt_exception
+{
+public:
+ pmt_notimplemented(const std::string &msg, pmt_t obj);
+};
+
+/*
+ * ------------------------------------------------------------------------
+ * Booleans. Two constants, #t and #f.
+ *
+ * In predicates, anything that is not #f is considered true.
+ * I.e., there is a single false value, #f.
+ * ------------------------------------------------------------------------
+ */
+extern GRUEL_API const pmt_t PMT_T; //< \#t : boolean true constant
+extern GRUEL_API const pmt_t PMT_F; //< \#f : boolean false constant
+
+//! Return true if obj is \#t or \#f, else return false.
+GRUEL_API bool pmt_is_bool(pmt_t obj);
+
+//! Return false if obj is \#f, else return true.
+GRUEL_API bool pmt_is_true(pmt_t obj);
+
+//! Return true if obj is \#f, else return true.
+GRUEL_API bool pmt_is_false(pmt_t obj);
+
+//! Return \#f is val is false, else return \#t.
+GRUEL_API pmt_t pmt_from_bool(bool val);
+
+//! Return true if val is PMT_T, return false when val is PMT_F,
+// else raise wrong_type exception.
+GRUEL_API bool pmt_to_bool(pmt_t val);
+
+/*
+ * ------------------------------------------------------------------------
+ * Symbols
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if obj is a symbol, else false.
+GRUEL_API bool pmt_is_symbol(const pmt_t& obj);
+
+//! Return the symbol whose name is \p s.
+GRUEL_API pmt_t pmt_string_to_symbol(const std::string &s);
+
+//! Alias for pmt_string_to_symbol
+GRUEL_API pmt_t pmt_intern(const std::string &s);
+
+
+/*!
+ * If \p is a symbol, return the name of the symbol as a string.
+ * Otherwise, raise the wrong_type exception.
+ */
+GRUEL_API const std::string pmt_symbol_to_string(const pmt_t& sym);
+
+/*
+ * ------------------------------------------------------------------------
+ * Numbers: we support integer, real and complex
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if obj is any kind of number, else false.
+GRUEL_API bool pmt_is_number(pmt_t obj);
+
+/*
+ * ------------------------------------------------------------------------
+ * Integers
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p x is an integer number, else false
+GRUEL_API bool pmt_is_integer(pmt_t x);
+
+//! Return the pmt value that represents the integer \p x.
+GRUEL_API pmt_t pmt_from_long(long x);
+
+/*!
+ * \brief Convert pmt to long if possible.
+ *
+ * When \p x represents an exact integer that fits in a long,
+ * return that integer. Else raise an exception, either wrong_type
+ * when x is not an exact integer, or out_of_range when it doesn't fit.
+ */
+GRUEL_API long pmt_to_long(pmt_t x);
+
+/*
+ * ------------------------------------------------------------------------
+ * uint64_t
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p x is an uint64 number, else false
+GRUEL_API bool pmt_is_uint64(pmt_t x);
+
+//! Return the pmt value that represents the uint64 \p x.
+GRUEL_API pmt_t pmt_from_uint64(uint64_t x);
+
+/*!
+ * \brief Convert pmt to uint64 if possible.
+ *
+ * When \p x represents an exact integer that fits in a uint64,
+ * return that uint64. Else raise an exception, either wrong_type
+ * when x is not an exact uint64, or out_of_range when it doesn't fit.
+ */
+GRUEL_API uint64_t pmt_to_uint64(pmt_t x);
+
+/*
+ * ------------------------------------------------------------------------
+ * Reals
+ * ------------------------------------------------------------------------
+ */
+
+/*
+ * \brief Return true if \p obj is a real number, else false.
+ */
+GRUEL_API bool pmt_is_real(pmt_t obj);
+
+//! Return the pmt value that represents double \p x.
+GRUEL_API pmt_t pmt_from_double(double x);
+
+/*!
+ * \brief Convert pmt to double if possible.
+ *
+ * Returns the number closest to \p val that is representable
+ * as a double. The argument \p val must be a real or integer, otherwise
+ * a wrong_type exception is raised.
+ */
+GRUEL_API double pmt_to_double(pmt_t x);
+
+/*
+ * ------------------------------------------------------------------------
+ * Complex
+ * ------------------------------------------------------------------------
+ */
+
+/*!
+ * \brief return true if \p obj is a complex number, false otherwise.
+ */
+GRUEL_API bool pmt_is_complex(pmt_t obj);
+
+//! Return a complex number constructed of the given real and imaginary parts.
+GRUEL_API pmt_t pmt_make_rectangular(double re, double im);
+
+//! Return a complex number constructed of the given real and imaginary parts.
+GRUEL_API pmt_t pmt_from_complex(double re, double im);
+
+//! Return a complex number constructed of the given a complex number.
+GRUEL_API pmt_t pmt_from_complex(const std::complex<double> &z);
+
+/*!
+ * If \p z is complex, real or integer, return the closest complex<double>.
+ * Otherwise, raise the wrong_type exception.
+ */
+GRUEL_API std::complex<double> pmt_to_complex(pmt_t z);
+
+/*
+ * ------------------------------------------------------------------------
+ * Pairs
+ * ------------------------------------------------------------------------
+ */
+
+extern GRUEL_API const pmt_t PMT_NIL; //< the empty list
+
+//! Return true if \p x is the empty list, otherwise return false.
+GRUEL_API bool pmt_is_null(const pmt_t& x);
+
+//! Return true if \p obj is a pair, else false.
+GRUEL_API bool pmt_is_pair(const pmt_t& obj);
+
+//! Return a newly allocated pair whose car is \p x and whose cdr is \p y.
+GRUEL_API pmt_t pmt_cons(const pmt_t& x, const pmt_t& y);
+
+//! If \p pair is a pair, return the car of the \p pair, otherwise raise wrong_type.
+GRUEL_API pmt_t pmt_car(const pmt_t& pair);
+
+//! If \p pair is a pair, return the cdr of the \p pair, otherwise raise wrong_type.
+GRUEL_API pmt_t pmt_cdr(const pmt_t& pair);
+
+//! Stores \p value in the car field of \p pair.
+GRUEL_API void pmt_set_car(pmt_t pair, pmt_t value);
+
+//! Stores \p value in the cdr field of \p pair.
+GRUEL_API void pmt_set_cdr(pmt_t pair, pmt_t value);
+
+GRUEL_API pmt_t pmt_caar(pmt_t pair);
+GRUEL_API pmt_t pmt_cadr(pmt_t pair);
+GRUEL_API pmt_t pmt_cdar(pmt_t pair);
+GRUEL_API pmt_t pmt_cddr(pmt_t pair);
+GRUEL_API pmt_t pmt_caddr(pmt_t pair);
+GRUEL_API pmt_t pmt_cadddr(pmt_t pair);
+
+/*
+ * ------------------------------------------------------------------------
+ * Tuples
+ *
+ * Store a fixed number of objects. Tuples are not modifiable, and thus
+ * are excellent for use as messages. Indexing is zero based.
+ * Access time to an element is O(1).
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p x is a tuple, othewise false.
+GRUEL_API bool pmt_is_tuple(pmt_t x);
+
+GRUEL_API pmt_t pmt_make_tuple();
+GRUEL_API pmt_t pmt_make_tuple(const pmt_t &e0);
+GRUEL_API pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1);
+GRUEL_API pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2);
+GRUEL_API pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3);
+GRUEL_API pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4);
+GRUEL_API pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5);
+GRUEL_API pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6);
+GRUEL_API pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7);
+GRUEL_API pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8);
+GRUEL_API pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8, const pmt_t &e9);
+
+/*!
+ * If \p x is a vector or proper list, return a tuple containing the elements of x
+ */
+GRUEL_API pmt_t pmt_to_tuple(const pmt_t &x);
+
+/*!
+ * Return the contents of position \p k of \p tuple.
+ * \p k must be a valid index of \p tuple.
+ */
+GRUEL_API pmt_t pmt_tuple_ref(const pmt_t &tuple, size_t k);
+
+/*
+ * ------------------------------------------------------------------------
+ * Vectors
+ *
+ * These vectors can hold any kind of objects. Indexing is zero based.
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p x is a vector, othewise false.
+GRUEL_API bool pmt_is_vector(pmt_t x);
+
+//! Make a vector of length \p k, with initial values set to \p fill
+GRUEL_API pmt_t pmt_make_vector(size_t k, pmt_t fill);
+
+/*!
+ * Return the contents of position \p k of \p vector.
+ * \p k must be a valid index of \p vector.
+ */
+GRUEL_API pmt_t pmt_vector_ref(pmt_t vector, size_t k);
+
+//! Store \p obj in position \p k.
+GRUEL_API void pmt_vector_set(pmt_t vector, size_t k, pmt_t obj);
+
+//! Store \p fill in every position of \p vector
+GRUEL_API void pmt_vector_fill(pmt_t vector, pmt_t fill);
+
+/*
+ * ------------------------------------------------------------------------
+ * Binary Large Objects (BLOBs)
+ *
+ * Handy for passing around uninterpreted chunks of memory.
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p x is a blob, othewise false.
+GRUEL_API bool pmt_is_blob(pmt_t x);
+
+/*!
+ * \brief Make a blob given a pointer and length in bytes
+ *
+ * \param buf is the pointer to data to use to create blob
+ * \param len is the size of the data in bytes.
+ *
+ * The data is copied into the blob.
+ */
+GRUEL_API pmt_t pmt_make_blob(const void *buf, size_t len);
+
+//! Return a pointer to the blob's data
+GRUEL_API const void *pmt_blob_data(pmt_t blob);
+
+//! Return the blob's length in bytes
+GRUEL_API size_t pmt_blob_length(pmt_t blob);
+
+/*!
+ * <pre>
+ * ------------------------------------------------------------------------
+ * Uniform Numeric Vectors
+ *
+ * A uniform numeric vector is a vector whose elements are all of single
+ * numeric type. pmt offers uniform numeric vectors for signed and
+ * unsigned 8-bit, 16-bit, 32-bit, and 64-bit integers, two sizes of
+ * floating point values, and complex floating-point numbers of these
+ * two sizes. Indexing is zero based.
+ *
+ * The names of the functions include these tags in their names:
+ *
+ * u8 unsigned 8-bit integers
+ * s8 signed 8-bit integers
+ * u16 unsigned 16-bit integers
+ * s16 signed 16-bit integers
+ * u32 unsigned 32-bit integers
+ * s32 signed 32-bit integers
+ * u64 unsigned 64-bit integers
+ * s64 signed 64-bit integers
+ * f32 the C++ type float
+ * f64 the C++ type double
+ * c32 the C++ type complex<float>
+ * c64 the C++ type complex<double>
+ * ------------------------------------------------------------------------
+ * </pre>
+ */
+
+//! true if \p x is any kind of uniform numeric vector
+GRUEL_API bool pmt_is_uniform_vector(pmt_t x);
+
+GRUEL_API bool pmt_is_u8vector(pmt_t x);
+GRUEL_API bool pmt_is_s8vector(pmt_t x);
+GRUEL_API bool pmt_is_u16vector(pmt_t x);
+GRUEL_API bool pmt_is_s16vector(pmt_t x);
+GRUEL_API bool pmt_is_u32vector(pmt_t x);
+GRUEL_API bool pmt_is_s32vector(pmt_t x);
+GRUEL_API bool pmt_is_u64vector(pmt_t x);
+GRUEL_API bool pmt_is_s64vector(pmt_t x);
+GRUEL_API bool pmt_is_f32vector(pmt_t x);
+GRUEL_API bool pmt_is_f64vector(pmt_t x);
+GRUEL_API bool pmt_is_c32vector(pmt_t x);
+GRUEL_API bool pmt_is_c64vector(pmt_t x);
+
+GRUEL_API pmt_t pmt_make_u8vector(size_t k, uint8_t fill);
+GRUEL_API pmt_t pmt_make_s8vector(size_t k, int8_t fill);
+GRUEL_API pmt_t pmt_make_u16vector(size_t k, uint16_t fill);
+GRUEL_API pmt_t pmt_make_s16vector(size_t k, int16_t fill);
+GRUEL_API pmt_t pmt_make_u32vector(size_t k, uint32_t fill);
+GRUEL_API pmt_t pmt_make_s32vector(size_t k, int32_t fill);
+GRUEL_API pmt_t pmt_make_u64vector(size_t k, uint64_t fill);
+GRUEL_API pmt_t pmt_make_s64vector(size_t k, int64_t fill);
+GRUEL_API pmt_t pmt_make_f32vector(size_t k, float fill);
+GRUEL_API pmt_t pmt_make_f64vector(size_t k, double fill);
+GRUEL_API pmt_t pmt_make_c32vector(size_t k, std::complex<float> fill);
+GRUEL_API pmt_t pmt_make_c64vector(size_t k, std::complex<double> fill);
+
+GRUEL_API pmt_t pmt_init_u8vector(size_t k, const uint8_t *data);
+GRUEL_API pmt_t pmt_init_u8vector(size_t k, const std::vector<uint8_t> &data);
+GRUEL_API pmt_t pmt_init_s8vector(size_t k, const int8_t *data);
+GRUEL_API pmt_t pmt_init_s8vector(size_t k, const std::vector<int8_t> &data);
+GRUEL_API pmt_t pmt_init_u16vector(size_t k, const uint16_t *data);
+GRUEL_API pmt_t pmt_init_u16vector(size_t k, const std::vector<uint16_t> &data);
+GRUEL_API pmt_t pmt_init_s16vector(size_t k, const int16_t *data);
+GRUEL_API pmt_t pmt_init_s16vector(size_t k, const std::vector<int16_t> &data);
+GRUEL_API pmt_t pmt_init_u32vector(size_t k, const uint32_t *data);
+GRUEL_API pmt_t pmt_init_u32vector(size_t k, const std::vector<uint32_t> &data);
+GRUEL_API pmt_t pmt_init_s32vector(size_t k, const int32_t *data);
+GRUEL_API pmt_t pmt_init_s32vector(size_t k, const std::vector<int32_t> &data);
+GRUEL_API pmt_t pmt_init_u64vector(size_t k, const uint64_t *data);
+GRUEL_API pmt_t pmt_init_u64vector(size_t k, const std::vector<uint64_t> &data);
+GRUEL_API pmt_t pmt_init_s64vector(size_t k, const int64_t *data);
+GRUEL_API pmt_t pmt_init_s64vector(size_t k, const std::vector<int64_t> &data);
+GRUEL_API pmt_t pmt_init_f32vector(size_t k, const float *data);
+GRUEL_API pmt_t pmt_init_f32vector(size_t k, const std::vector<float> &data);
+GRUEL_API pmt_t pmt_init_f64vector(size_t k, const double *data);
+GRUEL_API pmt_t pmt_init_f64vector(size_t k, const std::vector<double> &data);
+GRUEL_API pmt_t pmt_init_c32vector(size_t k, const std::complex<float> *data);
+GRUEL_API pmt_t pmt_init_c32vector(size_t k, const std::vector<std::complex<float> > &data);
+GRUEL_API pmt_t pmt_init_c64vector(size_t k, const std::complex<double> *data);
+GRUEL_API pmt_t pmt_init_c64vector(size_t k, const std::vector<std::complex<double> > &data);
+
+GRUEL_API uint8_t pmt_u8vector_ref(pmt_t v, size_t k);
+GRUEL_API int8_t pmt_s8vector_ref(pmt_t v, size_t k);
+GRUEL_API uint16_t pmt_u16vector_ref(pmt_t v, size_t k);
+GRUEL_API int16_t pmt_s16vector_ref(pmt_t v, size_t k);
+GRUEL_API uint32_t pmt_u32vector_ref(pmt_t v, size_t k);
+GRUEL_API int32_t pmt_s32vector_ref(pmt_t v, size_t k);
+GRUEL_API uint64_t pmt_u64vector_ref(pmt_t v, size_t k);
+GRUEL_API int64_t pmt_s64vector_ref(pmt_t v, size_t k);
+GRUEL_API float pmt_f32vector_ref(pmt_t v, size_t k);
+GRUEL_API double pmt_f64vector_ref(pmt_t v, size_t k);
+GRUEL_API std::complex<float> pmt_c32vector_ref(pmt_t v, size_t k);
+GRUEL_API std::complex<double> pmt_c64vector_ref(pmt_t v, size_t k);
+
+GRUEL_API void pmt_u8vector_set(pmt_t v, size_t k, uint8_t x); //< v[k] = x
+GRUEL_API void pmt_s8vector_set(pmt_t v, size_t k, int8_t x);
+GRUEL_API void pmt_u16vector_set(pmt_t v, size_t k, uint16_t x);
+GRUEL_API void pmt_s16vector_set(pmt_t v, size_t k, int16_t x);
+GRUEL_API void pmt_u32vector_set(pmt_t v, size_t k, uint32_t x);
+GRUEL_API void pmt_s32vector_set(pmt_t v, size_t k, int32_t x);
+GRUEL_API void pmt_u64vector_set(pmt_t v, size_t k, uint64_t x);
+GRUEL_API void pmt_s64vector_set(pmt_t v, size_t k, int64_t x);
+GRUEL_API void pmt_f32vector_set(pmt_t v, size_t k, float x);
+GRUEL_API void pmt_f64vector_set(pmt_t v, size_t k, double x);
+GRUEL_API void pmt_c32vector_set(pmt_t v, size_t k, std::complex<float> x);
+GRUEL_API void pmt_c64vector_set(pmt_t v, size_t k, std::complex<double> x);
+
+// Return const pointers to the elements
+
+GRUEL_API const void *pmt_uniform_vector_elements(pmt_t v, size_t &len); //< works with any; len is in bytes
+
+GRUEL_API const uint8_t *pmt_u8vector_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API const int8_t *pmt_s8vector_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API const uint16_t *pmt_u16vector_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API const int16_t *pmt_s16vector_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API const uint32_t *pmt_u32vector_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API const int32_t *pmt_s32vector_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API const uint64_t *pmt_u64vector_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API const int64_t *pmt_s64vector_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API const float *pmt_f32vector_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API const double *pmt_f64vector_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API const std::complex<float> *pmt_c32vector_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API const std::complex<double> *pmt_c64vector_elements(pmt_t v, size_t &len); //< len is in elements
+
+// len is in elements
+GRUEL_API const std::vector<uint8_t> pmt_u8vector_elements(pmt_t v);
+GRUEL_API const std::vector<int8_t> pmt_s8vector_elements(pmt_t v);
+GRUEL_API const std::vector<uint16_t> pmt_u16vector_elements(pmt_t v);
+GRUEL_API const std::vector<int16_t> pmt_s16vector_elements(pmt_t v);
+GRUEL_API const std::vector<uint32_t> pmt_u32vector_elements(pmt_t v);
+GRUEL_API const std::vector<int32_t> pmt_s32vector_elements(pmt_t v);
+GRUEL_API const std::vector<uint64_t> pmt_u64vector_elements(pmt_t v);
+GRUEL_API const std::vector<int64_t> pmt_s64vector_elements(pmt_t v);
+GRUEL_API const std::vector<float> pmt_f32vector_elements(pmt_t v);
+GRUEL_API const std::vector<double> pmt_f64vector_elements(pmt_t v);
+GRUEL_API const std::vector<std::complex<float> > pmt_c32vector_elements(pmt_t v);
+GRUEL_API const std::vector<std::complex<double> > pmt_c64vector_elements(pmt_t v);
+
+// Return non-const pointers to the elements
+
+GRUEL_API void *pmt_uniform_vector_writable_elements(pmt_t v, size_t &len); //< works with any; len is in bytes
+
+GRUEL_API uint8_t *pmt_u8vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API int8_t *pmt_s8vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API uint16_t *pmt_u16vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API int16_t *pmt_s16vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API uint32_t *pmt_u32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API int32_t *pmt_s32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API uint64_t *pmt_u64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API int64_t *pmt_s64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API float *pmt_f32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API double *pmt_f64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API std::complex<float> *pmt_c32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+GRUEL_API std::complex<double> *pmt_c64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+
+/*
+ * ------------------------------------------------------------------------
+ * Dictionary (a.k.a associative array, hash, map)
+ *
+ * This is a functional data structure that is persistent. Updating a
+ * functional data structure does not destroy the existing version, but
+ * rather creates a new version that coexists with the old.
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p obj is a dictionary
+GRUEL_API bool pmt_is_dict(const pmt_t &obj);
+
+//! Make an empty dictionary
+GRUEL_API pmt_t pmt_make_dict();
+
+//! Return a new dictionary with \p key associated with \p value.
+GRUEL_API pmt_t pmt_dict_add(const pmt_t &dict, const pmt_t &key, const pmt_t &value);
+
+//! Return a new dictionary with \p key removed.
+GRUEL_API pmt_t pmt_dict_delete(const pmt_t &dict, const pmt_t &key);
+
+//! Return true if \p key exists in \p dict
+GRUEL_API bool pmt_dict_has_key(const pmt_t &dict, const pmt_t &key);
+
+//! If \p key exists in \p dict, return associated value; otherwise return \p not_found.
+GRUEL_API pmt_t pmt_dict_ref(const pmt_t &dict, const pmt_t &key, const pmt_t &not_found);
+
+//! Return list of (key . value) pairs
+GRUEL_API pmt_t pmt_dict_items(pmt_t dict);
+
+//! Return list of keys
+GRUEL_API pmt_t pmt_dict_keys(pmt_t dict);
+
+//! Return list of values
+GRUEL_API pmt_t pmt_dict_values(pmt_t dict);
+
+/*
+ * ------------------------------------------------------------------------
+ * Any (wraps boost::any -- can be used to wrap pretty much anything)
+ *
+ * Cannot be serialized or used across process boundaries.
+ * See http://www.boost.org/doc/html/any.html
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p obj is an any
+GRUEL_API bool pmt_is_any(pmt_t obj);
+
+//! make an any
+GRUEL_API pmt_t pmt_make_any(const boost::any &any);
+
+//! Return underlying boost::any
+GRUEL_API boost::any pmt_any_ref(pmt_t obj);
+
+//! Store \p any in \p obj
+GRUEL_API void pmt_any_set(pmt_t obj, const boost::any &any);
+
+
+/*
+ * ------------------------------------------------------------------------
+ * msg_accepter -- pmt representation of gruel::msg_accepter
+ * ------------------------------------------------------------------------
+ */
+//! Return true if \p obj is a msg_accepter
+GRUEL_API bool pmt_is_msg_accepter(const pmt_t &obj);
+
+//! make a msg_accepter
+GRUEL_API pmt_t pmt_make_msg_accepter(boost::shared_ptr<gruel::msg_accepter> ma);
+
+//! Return underlying msg_accepter
+GRUEL_API boost::shared_ptr<gruel::msg_accepter> pmt_msg_accepter_ref(const pmt_t &obj);
+
+/*
+ * ------------------------------------------------------------------------
+ * General functions
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if x and y are the same object; otherwise return false.
+GRUEL_API bool pmt_eq(const pmt_t& x, const pmt_t& y);
+
+/*!
+ * \brief Return true if x and y should normally be regarded as the same object, else false.
+ *
+ * <pre>
+ * eqv returns true if:
+ * x and y are the same object.
+ * x and y are both \#t or both \#f.
+ * x and y are both symbols and their names are the same.
+ * x and y are both numbers, and are numerically equal.
+ * x and y are both the empty list (nil).
+ * x and y are pairs or vectors that denote same location in store.
+ * </pre>
+ */
+GRUEL_API bool pmt_eqv(const pmt_t& x, const pmt_t& y);
+
+/*!
+ * pmt_equal recursively compares the contents of pairs and vectors,
+ * applying pmt_eqv on other objects such as numbers and symbols.
+ * pmt_equal may fail to terminate if its arguments are circular data
+ * structures.
+ */
+GRUEL_API bool pmt_equal(const pmt_t& x, const pmt_t& y);
+
+
+//! Return the number of elements in v
+GRUEL_API size_t pmt_length(const pmt_t& v);
+
+/*!
+ * \brief Find the first pair in \p alist whose car field is \p obj
+ * and return that pair.
+ *
+ * \p alist (for "association list") must be a list of pairs. If no pair
+ * in \p alist has \p obj as its car then \#f is returned.
+ * Uses pmt_eq to compare \p obj with car fields of the pairs in \p alist.
+ */
+GRUEL_API pmt_t pmt_assq(pmt_t obj, pmt_t alist);
+
+/*!
+ * \brief Find the first pair in \p alist whose car field is \p obj
+ * and return that pair.
+ *
+ * \p alist (for "association list") must be a list of pairs. If no pair
+ * in \p alist has \p obj as its car then \#f is returned.
+ * Uses pmt_eqv to compare \p obj with car fields of the pairs in \p alist.
+ */
+GRUEL_API pmt_t pmt_assv(pmt_t obj, pmt_t alist);
+
+/*!
+ * \brief Find the first pair in \p alist whose car field is \p obj
+ * and return that pair.
+ *
+ * \p alist (for "association list") must be a list of pairs. If no pair
+ * in \p alist has \p obj as its car then \#f is returned.
+ * Uses pmt_equal to compare \p obj with car fields of the pairs in \p alist.
+ */
+GRUEL_API pmt_t pmt_assoc(pmt_t obj, pmt_t alist);
+
+/*!
+ * \brief Apply \p proc element-wise to the elements of list and returns
+ * a list of the results, in order.
+ *
+ * \p list must be a list. The dynamic order in which \p proc is
+ * applied to the elements of \p list is unspecified.
+ */
+GRUEL_API pmt_t pmt_map(pmt_t proc(const pmt_t&), pmt_t list);
+
+/*!
+ * \brief reverse \p list.
+ *
+ * \p list must be a proper list.
+ */
+GRUEL_API pmt_t pmt_reverse(pmt_t list);
+
+/*!
+ * \brief destructively reverse \p list.
+ *
+ * \p list must be a proper list.
+ */
+GRUEL_API pmt_t pmt_reverse_x(pmt_t list);
+
+/*!
+ * \brief (acons x y a) == (cons (cons x y) a)
+ */
+inline static pmt_t
+pmt_acons(pmt_t x, pmt_t y, pmt_t a)
+{
+ return pmt_cons(pmt_cons(x, y), a);
+}
+
+/*!
+ * \brief locates \p nth element of \n list where the car is the 'zeroth' element.
+ */
+GRUEL_API pmt_t pmt_nth(size_t n, pmt_t list);
+
+/*!
+ * \brief returns the tail of \p list that would be obtained by calling
+ * cdr \p n times in succession.
+ */
+GRUEL_API pmt_t pmt_nthcdr(size_t n, pmt_t list);
+
+/*!
+ * \brief Return the first sublist of \p list whose car is \p obj.
+ * If \p obj does not occur in \p list, then \#f is returned.
+ * pmt_memq use pmt_eq to compare \p obj with the elements of \p list.
+ */
+GRUEL_API pmt_t pmt_memq(pmt_t obj, pmt_t list);
+
+/*!
+ * \brief Return the first sublist of \p list whose car is \p obj.
+ * If \p obj does not occur in \p list, then \#f is returned.
+ * pmt_memv use pmt_eqv to compare \p obj with the elements of \p list.
+ */
+GRUEL_API pmt_t pmt_memv(pmt_t obj, pmt_t list);
+
+/*!
+ * \brief Return the first sublist of \p list whose car is \p obj.
+ * If \p obj does not occur in \p list, then \#f is returned.
+ * pmt_member use pmt_equal to compare \p obj with the elements of \p list.
+ */
+GRUEL_API pmt_t pmt_member(pmt_t obj, pmt_t list);
+
+/*!
+ * \brief Return true if every element of \p list1 appears in \p list2, and false otherwise.
+ * Comparisons are done with pmt_eqv.
+ */
+GRUEL_API bool pmt_subsetp(pmt_t list1, pmt_t list2);
+
+/*!
+ * \brief Return a list of length 1 containing \p x1
+ */
+GRUEL_API pmt_t pmt_list1(const pmt_t& x1);
+
+/*!
+ * \brief Return a list of length 2 containing \p x1, \p x2
+ */
+GRUEL_API pmt_t pmt_list2(const pmt_t& x1, const pmt_t& x2);
+
+/*!
+ * \brief Return a list of length 3 containing \p x1, \p x2, \p x3
+ */
+GRUEL_API pmt_t pmt_list3(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3);
+
+/*!
+ * \brief Return a list of length 4 containing \p x1, \p x2, \p x3, \p x4
+ */
+GRUEL_API pmt_t pmt_list4(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4);
+
+/*!
+ * \brief Return a list of length 5 containing \p x1, \p x2, \p x3, \p x4, \p x5
+ */
+GRUEL_API pmt_t pmt_list5(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4, const pmt_t& x5);
+
+/*!
+ * \brief Return a list of length 6 containing \p x1, \p x2, \p x3, \p x4, \p
+ * x5, \p x6
+ */
+GRUEL_API pmt_t pmt_list6(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4, const pmt_t& x5, const pmt_t& x6);
+
+/*!
+ * \brief Return \p list with \p item added to it.
+ */
+GRUEL_API pmt_t pmt_list_add(pmt_t list, const pmt_t& item);
+
+/*!
+ * \brief Return \p list with \p item removed from it.
+ */
+GRUEL_API pmt_t pmt_list_rm(pmt_t list, const pmt_t& item);
+
+/*!
+ * \brief Return bool of \p list contains \p item
+ */
+GRUEL_API bool pmt_list_has(pmt_t list, const pmt_t& item);
+
+
+/*
+ * ------------------------------------------------------------------------
+ * read / write
+ * ------------------------------------------------------------------------
+ */
+extern GRUEL_API const pmt_t PMT_EOF; //< The end of file object
+
+//! return true if obj is the EOF object, otherwise return false.
+GRUEL_API bool pmt_is_eof_object(pmt_t obj);
+
+/*!
+ * read converts external representations of pmt objects into the
+ * objects themselves. Read returns the next object parsable from
+ * the given input port, updating port to point to the first
+ * character past the end of the external representation of the
+ * object.
+ *
+ * If an end of file is encountered in the input before any
+ * characters are found that can begin an object, then an end of file
+ * object is returned. The port remains open, and further attempts
+ * to read will also return an end of file object. If an end of file
+ * is encountered after the beginning of an object's external
+ * representation, but the external representation is incomplete and
+ * therefore not parsable, an error is signaled.
+ */
+GRUEL_API pmt_t pmt_read(std::istream &port);
+
+/*!
+ * Write a written representation of \p obj to the given \p port.
+ */
+GRUEL_API void pmt_write(pmt_t obj, std::ostream &port);
+
+/*!
+ * Return a string representation of \p obj.
+ * This is the same output as would be generated by pmt_write.
+ */
+GRUEL_API std::string pmt_write_string(pmt_t obj);
+
+
+GRUEL_API std::ostream& operator<<(std::ostream &os, pmt_t obj);
+
+/*!
+ * \brief Write pmt string representation to stdout.
+ */
+GRUEL_API void pmt_print(pmt_t v);
+
+
+/*
+ * ------------------------------------------------------------------------
+ * portable byte stream representation
+ * ------------------------------------------------------------------------
+ */
+/*!
+ * \brief Write portable byte-serial representation of \p obj to \p sink
+ */
+GRUEL_API bool pmt_serialize(pmt_t obj, std::streambuf &sink);
+
+/*!
+ * \brief Create obj from portable byte-serial representation
+ */
+GRUEL_API pmt_t pmt_deserialize(std::streambuf &source);
+
+
+GRUEL_API void pmt_dump_sizeof(); // debugging
+
+/*!
+ * \brief Provide a simple string generating interface to pmt's serialize function
+ */
+GRUEL_API std::string pmt_serialize_str(pmt_t obj);
+
+/*!
+ * \brief Provide a simple string generating interface to pmt's deserialize function
+ */
+GRUEL_API pmt_t pmt_deserialize_str(std::string str);
+
+/*!
+ * \brief Provide a comparator function object to allow pmt use in stl types
+ */
+class pmt_comperator {
+ public:
+ bool operator()(pmt::pmt_t const& p1, pmt::pmt_t const& p2) const
+ { return pmt::pmt_eqv(p1,p2)?false:p1.get()>p2.get(); }
+ };
+
+} /* namespace pmt */
+
+#include <gruel/pmt_sugar.h>
+
+#endif /* INCLUDED_PMT_H */
diff --git a/gruel/src/include/gruel/pmt_pool.h b/gruel/src/include/gruel/pmt_pool.h
new file mode 100644
index 000000000..93c5290ad
--- /dev/null
+++ b/gruel/src/include/gruel/pmt_pool.h
@@ -0,0 +1,73 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_PMT_POOL_H
+#define INCLUDED_PMT_POOL_H
+
+#include <gruel/api.h>
+#include <cstddef>
+#include <vector>
+#include <boost/thread.hpp>
+
+namespace pmt {
+
+/*!
+ * \brief very simple thread-safe fixed-size allocation pool
+ *
+ * FIXME may want to go to global allocation with per-thread free list.
+ * This would eliminate virtually all lock contention.
+ */
+class GRUEL_API pmt_pool {
+
+ struct GRUEL_API item {
+ struct item *d_next;
+ };
+
+ typedef boost::unique_lock<boost::mutex> scoped_lock;
+ mutable boost::mutex d_mutex;
+ boost::condition_variable d_cond;
+
+ size_t d_itemsize;
+ size_t d_alignment;
+ size_t d_allocation_size;
+ size_t d_max_items;
+ size_t d_n_items;
+ item *d_freelist;
+ std::vector<char *> d_allocations;
+
+public:
+ /*!
+ * \param itemsize size in bytes of the items to be allocated.
+ * \param alignment alignment in bytes of all objects to be allocated (must be power-of-2).
+ * \param allocation_size number of bytes to allocate at a time from the underlying allocator.
+ * \param max_items is the maximum number of items to allocate. If this number is exceeded,
+ * the allocate blocks. 0 implies no limit.
+ */
+ pmt_pool(size_t itemsize, size_t alignment = 16,
+ size_t allocation_size = 4096, size_t max_items = 0);
+ ~pmt_pool();
+
+ void *malloc();
+ void free(void *p);
+};
+
+} /* namespace pmt */
+
+#endif /* INCLUDED_PMT_POOL_H */
diff --git a/gruel/src/include/gruel/pmt_sugar.h b/gruel/src/include/gruel/pmt_sugar.h
new file mode 100644
index 000000000..bde7f716d
--- /dev/null
+++ b/gruel/src/include/gruel/pmt_sugar.h
@@ -0,0 +1,171 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GRUEL_PMT_SUGAR_H
+#define INCLUDED_GRUEL_PMT_SUGAR_H
+
+/*!
+ * This file is included by pmt.h and contains pseudo-constructor
+ * shorthand for making pmt objects
+ */
+
+namespace pmt {
+
+ //! Make pmt symbol
+ static inline pmt_t
+ mp(const std::string &s)
+ {
+ return pmt_string_to_symbol(s);
+ }
+
+ //! Make pmt symbol
+ static inline pmt_t
+ mp(const char *s)
+ {
+ return pmt_string_to_symbol(s);
+ }
+
+ //! Make pmt long
+ static inline pmt_t
+ mp(long x){
+ return pmt_from_long(x);
+ }
+
+ //! Make pmt long
+ static inline pmt_t
+ mp(long long unsigned x){
+ return pmt_from_long(x);
+ }
+
+ //! Make pmt long
+ static inline pmt_t
+ mp(int x){
+ return pmt_from_long(x);
+ }
+
+ //! Make pmt double
+ static inline pmt_t
+ mp(double x){
+ return pmt_from_double(x);
+ }
+
+ //! Make pmt complex
+ static inline pmt_t
+ mp(std::complex<double> z)
+ {
+ return pmt_make_rectangular(z.real(), z.imag());
+ }
+
+ //! Make pmt complex
+ static inline pmt_t
+ mp(std::complex<float> z)
+ {
+ return pmt_make_rectangular(z.real(), z.imag());
+ }
+
+ //! Make pmt msg_accepter
+ static inline pmt_t
+ mp(boost::shared_ptr<gruel::msg_accepter> ma)
+ {
+ return pmt_make_msg_accepter(ma);
+ }
+
+ //! Make pmt Binary Large Object (BLOB)
+ static inline pmt_t
+ mp(const void *data, size_t len_in_bytes)
+ {
+ return pmt_make_blob(data, len_in_bytes);
+ }
+
+ //! Make tuple
+ static inline pmt_t
+ mp(const pmt_t &e0)
+ {
+ return pmt_make_tuple(e0);
+ }
+
+ //! Make tuple
+ static inline pmt_t
+ mp(const pmt_t &e0, const pmt_t &e1)
+ {
+ return pmt_make_tuple(e0, e1);
+ }
+
+ //! Make tuple
+ static inline pmt_t
+ mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2)
+ {
+ return pmt_make_tuple(e0, e1, e2);
+ }
+
+ //! Make tuple
+ static inline pmt_t
+ mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3)
+ {
+ return pmt_make_tuple(e0, e1, e2, e3);
+ }
+
+ //! Make tuple
+ static inline pmt_t
+ mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4)
+ {
+ return pmt_make_tuple(e0, e1, e2, e3, e4);
+ }
+
+ //! Make tuple
+ static inline pmt_t
+ mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5)
+ {
+ return pmt_make_tuple(e0, e1, e2, e3, e4, e5);
+ }
+
+ //! Make tuple
+ static inline pmt_t
+ mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6)
+ {
+ return pmt_make_tuple(e0, e1, e2, e3, e4, e5, e6);
+ }
+
+ //! Make tuple
+ static inline pmt_t
+ mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7)
+ {
+ return pmt_make_tuple(e0, e1, e2, e3, e4, e5, e6, e7);
+ }
+
+ //! Make tuple
+ static inline pmt_t
+ mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8)
+ {
+ return pmt_make_tuple(e0, e1, e2, e3, e4, e5, e6, e7, e8);
+ }
+
+ //! Make tuple
+ static inline pmt_t
+ mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8, const pmt_t &e9)
+ {
+ return pmt_make_tuple(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9);
+ }
+
+
+} /* namespace pmt */
+
+
+#endif /* INCLUDED_GRUEL_PMT_SUGAR_H */
diff --git a/gruel/src/include/gruel/realtime.h b/gruel/src/include/gruel/realtime.h
new file mode 100644
index 000000000..13673ecb3
--- /dev/null
+++ b/gruel/src/include/gruel/realtime.h
@@ -0,0 +1,96 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2008 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.
+ */
+
+#ifndef INCLUDED_GRUEL_REALTIME_H
+#define INCLUDED_GRUEL_REALTIME_H
+
+#include <gruel/api.h>
+#include <stdexcept>
+
+/*!
+ * \brief System independent way to ask for realtime scheduling
+ *
+ * \sa sys_pri.h
+ */
+
+namespace gruel {
+
+ typedef enum {
+ RT_OK = 0,
+ RT_NOT_IMPLEMENTED,
+ RT_NO_PRIVS,
+ RT_OTHER_ERROR
+ } rt_status_t;
+
+
+ enum rt_sched_policy {
+ RT_SCHED_RR = 0, // round robin
+ RT_SCHED_FIFO = 1, // first in first out
+ };
+
+ /*
+ * Define the range for our virtual priorities (don't change these)
+ *
+ * Processes (or threads) with numerically higher priority values
+ * are scheduled before processes with numerically lower priority
+ * values. Thus, the value returned by rt_priority_max() will be
+ * greater than the value returned by rt_priority_min().
+ */
+ static inline int rt_priority_min() { return 0; }
+ static inline int rt_priority_max() { return 15; }
+ static inline int rt_priority_default() { return 1; }
+
+ struct GRUEL_API rt_sched_param {
+ int priority;
+ rt_sched_policy policy;
+
+ rt_sched_param()
+ : priority(rt_priority_default()), policy(RT_SCHED_RR){}
+
+ rt_sched_param(int priority_, rt_sched_policy policy_ = RT_SCHED_RR)
+ {
+ if (priority_ < rt_priority_min() || priority_ > rt_priority_max())
+ throw std::invalid_argument("rt_sched_param: priority out of range");
+
+ priority = priority_;
+ policy = policy_;
+ }
+ };
+
+ /*!
+ * \brief If possible, enable "realtime" scheduling.
+ * \ingroup misc
+ *
+ * In general, this means that the code will be scheduled before any
+ * non-realtime (normal) processes. Note that if your code contains
+ * an non-blocking infinite loop and you enable realtime scheduling,
+ * it's possible to hang the system.
+ */
+
+ // NOTE: If you change this, you need to change the code in
+ // gnuradio-core/src/lib/runtime/gr_realtime.i, see note there.
+ rt_status_t
+ GRUEL_API enable_realtime_scheduling(rt_sched_param = rt_sched_param());
+
+} // namespace gruel
+
+#endif /* INCLUDED_GRUEL_REALTIME_H */
diff --git a/gruel/src/include/gruel/sys_pri.h b/gruel/src/include/gruel/sys_pri.h
new file mode 100644
index 000000000..c0751e52c
--- /dev/null
+++ b/gruel/src/include/gruel/sys_pri.h
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GRUEL_SYS_PRI_H
+#define INCLUDED_GRUEL_SYS_PRI_H
+
+#include <gruel/api.h>
+#include <gruel/realtime.h>
+
+/*
+ * A single place to define real-time priorities used by the system itself
+ */
+namespace gruel {
+
+ struct GRUEL_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
+ };
+
+}
+
+#endif /* INCLUDED_GRUEL_SYS_PRI_H */
diff --git a/gruel/src/include/gruel/thread.h b/gruel/src/include/gruel/thread.h
new file mode 100644
index 000000000..10c6c38cc
--- /dev/null
+++ b/gruel/src/include/gruel/thread.h
@@ -0,0 +1,139 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009-2012 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_THREAD_H
+#define INCLUDED_THREAD_H
+
+#include <gruel/api.h>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <vector>
+
+#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+
+#include <windows.h>
+
+#endif
+
+namespace gruel {
+
+ typedef boost::thread thread;
+ typedef boost::mutex mutex;
+ typedef boost::unique_lock<boost::mutex> scoped_lock;
+ typedef boost::condition_variable condition_variable;
+
+ /*! \brief a system-dependent typedef for the underlying thread type.
+ */
+#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+ typedef HANDLE gr_thread_t;
+#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+ typedef pthread_t gr_thread_t;
+#else
+ typedef pthread_t gr_thread_t;
+#endif
+
+ /*! \brief Get the current thread's ID as a gr_thread_t
+ *
+ * We use this when setting the thread affinity or any other
+ * low-level thread settings. Can be called withing a GNU Radio
+ * block to get a reference to its current thread ID.
+ */
+ GRUEL_API gr_thread_t get_current_thread_id();
+
+ /*! \brief Bind the current thread to a set of cores.
+ *
+ * Wrapper for system-dependent calls to set the affinity of the
+ * current thread to the processor mask. The mask is simply a
+ * 1-demensional vector containing the processor or core number from
+ * 0 to N-1 for N cores.
+ *
+ * Note: this does not work on OSX; it is a nop call since OSX does
+ * not support the concept of thread affinity (and what they do
+ * support in this way since 10.5 is not what we want or can use in
+ * this fashion).
+ */
+ GRUEL_API void thread_bind_to_processor(const std::vector<int> &mask);
+
+ /*! \brief Convineince function to bind the current thread to a single core.
+ *
+ * Wrapper for system-dependent calls to set the affinity of the
+ * current thread to a given core from 0 to N-1 for N cores.
+ *
+ * Note: this does not work on OSX; it is a nop call since OSX does
+ * not support the concept of thread affinity (and what they do
+ * support in this way since 10.5 is not what we want or can use in
+ * this fashion).
+ */
+ GRUEL_API void thread_bind_to_processor(int n);
+
+ /*! \brief Bind a thread to a set of cores.
+ *
+ * Wrapper for system-dependent calls to set the affinity of the
+ * given thread ID to the processor mask. The mask is simply a
+ * 1-demensional vector containing the processor or core number from
+ * 0 to N-1 for N cores.
+ *
+ * Note: this does not work on OSX; it is a nop call since OSX does
+ * not support the concept of thread affinity (and what they do
+ * support in this way since 10.5 is not what we want or can use in
+ * this fashion).
+ */
+ GRUEL_API void thread_bind_to_processor(gr_thread_t thread, const std::vector<int> &mask);
+
+
+ /*! \brief Convineince function to bind the a thread to a single core.
+ *
+ * Wrapper for system-dependent calls to set the affinity of the
+ * given thread ID to a given core from 0 to N-1 for N cores.
+ *
+ * Note: this does not work on OSX; it is a nop call since OSX does
+ * not support the concept of thread affinity (and what they do
+ * support in this way since 10.5 is not what we want or can use in
+ * this fashion).
+ */
+ GRUEL_API void thread_bind_to_processor(gr_thread_t thread, unsigned int n);
+
+ /*! \brief Remove any thread-processor affinity for the current thread.
+ *
+ * Note: this does not work on OSX; it is a nop call since OSX does
+ * not support the concept of thread affinity (and what they do
+ * support in this way since 10.5 is not what we want or can use in
+ * this fashion).
+ */
+ GRUEL_API void thread_unbind();
+
+ /*! \brief Remove any thread-processor affinity for a given thread ID.
+ *
+ * Note: this does not work on OSX; it is a nop call since OSX does
+ * not support the concept of thread affinity (and what they do
+ * support in this way since 10.5 is not what we want or can use in
+ * this fashion).
+ */
+ GRUEL_API void thread_unbind(gr_thread_t thread);
+
+} /* namespace gruel */
+
+#endif /* INCLUDED_THREAD_H */
diff --git a/gruel/src/include/gruel/thread_body_wrapper.h b/gruel/src/include/gruel/thread_body_wrapper.h
new file mode 100644
index 000000000..e09a43e68
--- /dev/null
+++ b/gruel/src/include/gruel/thread_body_wrapper.h
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_THREAD_BODY_WRAPPER_H
+#define INCLUDED_THREAD_BODY_WRAPPER_H
+
+#include <gruel/api.h>
+#include <gruel/thread.h>
+#include <exception>
+#include <iostream>
+
+namespace gruel
+{
+
+ GRUEL_API void mask_signals();
+
+ template <class F>
+ class thread_body_wrapper
+ {
+ F d_f;
+ std::string d_name;
+
+ public:
+
+ explicit thread_body_wrapper(F f, const std::string &name="")
+ : d_f(f), d_name(name) {}
+
+ void operator()()
+ {
+ mask_signals();
+
+ try {
+ d_f();
+ }
+ catch(boost::thread_interrupted const &)
+ {
+ }
+ catch(std::exception const &e)
+ {
+ std::cerr << "thread[" << d_name << "]: "
+ << e.what() << std::endl;
+ }
+ catch(...)
+ {
+ std::cerr << "thread[" << d_name << "]: "
+ << "caught unrecognized exception\n";
+ }
+ }
+ };
+}
+
+#endif /* INCLUDED_THREAD_BODY_WRAPPER_H */
diff --git a/gruel/src/include/gruel/thread_group.h b/gruel/src/include/gruel/thread_group.h
new file mode 100644
index 000000000..1b8a0a4bf
--- /dev/null
+++ b/gruel/src/include/gruel/thread_group.h
@@ -0,0 +1,45 @@
+/* -*- c++ -*- */
+/*
+ * Copyright (C) 2001-2003 William E. Kempf
+ * Copyright (C) 2007 Anthony Williams
+ * Copyright 2008,2009 Free Software Foundation, Inc.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+/*
+ * This was extracted from Boost 1.35.0 and fixed.
+ */
+
+#ifndef INCLUDED_GRUEL_THREAD_GROUP_H
+#define INCLUDED_GRUEL_THREAD_GROUP_H
+
+#include <gruel/api.h>
+#include <gruel/thread.h>
+#include <boost/utility.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/function.hpp>
+
+namespace gruel
+{
+ class GRUEL_API thread_group : public boost::noncopyable
+ {
+ public:
+ thread_group();
+ ~thread_group();
+
+ boost::thread* create_thread(const boost::function0<void>& threadfunc);
+ void add_thread(boost::thread* thrd);
+ void remove_thread(boost::thread* thrd);
+ void join_all();
+ void interrupt_all();
+ size_t size() const;
+
+ private:
+ std::list<boost::thread*> m_threads;
+ mutable boost::shared_mutex m_mutex;
+ };
+}
+
+#endif /* INCLUDED_GRUEL_THREAD_GROUP_H */