commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r5067 - in gnuradio/branches/features/inband-usb: mblo


From: eb
Subject: [Commit-gnuradio] r5067 - in gnuradio/branches/features/inband-usb: mblock/src/lib pmt/src/lib pmt/src/scheme/gnuradio usrp/host/lib/inband
Date: Sat, 21 Apr 2007 18:51:18 -0600 (MDT)

Author: eb
Date: 2007-04-21 18:51:18 -0600 (Sat, 21 Apr 2007)
New Revision: 5067

Added:
   gnuradio/branches/features/inband-usb/mblock/src/lib/getres.cc
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_msg_accepter_msgq.cc
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_msg_accepter_msgq.h
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_base.cc
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_base.h
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_time.cc
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_time.h
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_timer_queue.cc
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_timer_queue.h
   gnuradio/branches/features/inband-usb/mblock/src/lib/qa_timeouts.cc
   gnuradio/branches/features/inband-usb/mblock/src/lib/qa_timeouts.h
Removed:
   
gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_placeholder.cc
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_placeholder.h
Modified:
   gnuradio/branches/features/inband-usb/mblock/src/lib/
   gnuradio/branches/features/inband-usb/mblock/src/lib/Makefile.am
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_mblock.cc
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_mblock.h
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_mblock_impl.cc
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_mblock_impl.h
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_msg_queue.cc
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_msg_queue.h
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime.cc
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime.h
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_nop.h
   
gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_thread_per_block.cc
   
gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_thread_per_block.h
   gnuradio/branches/features/inband-usb/mblock/src/lib/mb_worker.cc
   gnuradio/branches/features/inband-usb/mblock/src/lib/mbi_runtime_lock.h
   gnuradio/branches/features/inband-usb/mblock/src/lib/qa_mblock.cc
   gnuradio/branches/features/inband-usb/pmt/src/lib/Makefile.am
   gnuradio/branches/features/inband-usb/pmt/src/lib/pmt.cc
   gnuradio/branches/features/inband-usb/pmt/src/lib/pmt.h
   gnuradio/branches/features/inband-usb/pmt/src/lib/pmt_int.h
   gnuradio/branches/features/inband-usb/pmt/src/lib/qa_pmt_prims.cc
   gnuradio/branches/features/inband-usb/pmt/src/lib/qa_pmt_prims.h
   gnuradio/branches/features/inband-usb/pmt/src/scheme/gnuradio/Makefile.am
   gnuradio/branches/features/inband-usb/usrp/host/lib/inband/Makefile.am
Log:
Merged eb/ibu -r5046:5066 into features/inband-usb.  These changes
implement periodic and one-shot timeouts for mblocks.  There are also
a couple of tweaks for distcheck.  

At this point, mblocks are usable standalone.




Property changes on: gnuradio/branches/features/inband-usb/mblock/src/lib
___________________________________________________________________
Name: svn:ignore
   - Makefile
Makefile.in
.la
.lo
.deps
.libs
*.la
*.lo
test_mblock
qa_bitset_mbh.cc
benchmark_send

   + Makefile
Makefile.in
.la
.lo
.deps
.libs
*.la
*.lo
test_mblock
qa_bitset_mbh.cc
benchmark_send
getres


Modified: gnuradio/branches/features/inband-usb/mblock/src/lib/Makefile.am
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/Makefile.am    
2007-04-21 22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/Makefile.am    
2007-04-22 00:51:18 UTC (rev 5067)
@@ -28,7 +28,8 @@
 lib_LTLIBRARIES = libmblock.la libmblock-qa.la
 
 EXTRA_DIST =                           \
-       README.locking                  
+       README.locking                  \
+       qa_bitset.mbh                   
 
 
 BUILT_SOURCES =                                \
@@ -48,14 +49,18 @@
        mb_mblock_impl.cc               \
        mb_message.cc                   \
        mb_msg_accepter.cc              \
+       mb_msg_accepter_msgq.cc         \
        mb_msg_accepter_smp.cc          \
        mb_msg_queue.cc                 \
        mb_port.cc                      \
        mb_port_simple.cc               \
        mb_protocol_class.cc            \
        mb_runtime.cc                   \
+       mb_runtime_base.cc              \
        mb_runtime_nop.cc               \
        mb_runtime_thread_per_block.cc  \
+       mb_time.cc                      \
+       mb_timer_queue.cc               \
        mb_util.cc                      \
        mb_worker.cc                    
 
@@ -77,12 +82,13 @@
        mb_mblock.h                     \
        mb_message.h                    \
        mb_msg_accepter.h               \
+       mb_msg_accepter_msgq.h          \
        mb_msg_queue.h                  \
        mb_port.h                       \
        mb_port_simple.h                \
        mb_protocol_class.h             \
        mb_runtime.h                    \
-       mb_runtime_nop.h                \
+       mb_time.h                       \
        mb_util.h                       
 
 
@@ -91,13 +97,17 @@
        mb_endpoint.h                   \
        mb_mblock_impl.h                \
        mb_msg_accepter_smp.h           \
+       mb_runtime_base.h               \
+       mb_runtime_nop.h                \
        mb_runtime_thread_per_block.h   \
+       mb_timer_queue.h                \
        mb_worker.h                     \
        mbi_runtime_lock.h              \
        qa_mblock.h                     \
        qa_mblock_prims.h               \
        qa_mblock_send.h                \
-       qa_mblock_sys.h                 
+       qa_mblock_sys.h                 \
+       qa_timeouts.h                   
 
 
 # Build the qa code into its own library
@@ -109,7 +119,8 @@
        qa_mblock.cc                    \
        qa_mblock_prims.cc              \
        qa_mblock_send.cc               \
-       qa_mblock_sys.cc                
+       qa_mblock_sys.cc                \
+       qa_timeouts.cc                  
 
 
 # magic flags

Copied: gnuradio/branches/features/inband-usb/mblock/src/lib/getres.cc (from 
rev 5066, gnuradio/branches/developers/eb/ibu/mblock/src/lib/getres.cc)
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/getres.cc              
                (rev 0)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/getres.cc      
2007-04-22 00:51:18 UTC (rev 5067)
@@ -0,0 +1,32 @@
+#include <time.h>
+#include <stdio.h>
+
+int
+main(int argc, char **argv)
+{
+  bool ok = true;
+  struct timespec ts;
+  int r;
+
+  r = clock_getres(CLOCK_REALTIME, &ts);
+  if (r != 0){
+    perror("clock_getres(CLOCK_REALTIME, ...)");
+    ok = false;
+  }
+  else
+    printf("clock_getres(CLOCK_REALTIME, ...)  => %11.9f\n",
+          (double) ts.tv_sec + ts.tv_nsec * 1e-9);
+
+
+  r = clock_getres(CLOCK_MONOTONIC, &ts);
+  if (r != 0){
+    perror("clock_getres(CLOCK_MONOTONIC, ...");
+    ok = false;
+  }
+  else
+    printf("clock_getres(CLOCK_MONOTONIC, ...) => %11.9f\n",
+          (double) ts.tv_sec + ts.tv_nsec * 1e-9);
+
+
+  return ok == true ? 0 : 1;
+}  

Modified: gnuradio/branches/features/inband-usb/mblock/src/lib/mb_mblock.cc
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/mb_mblock.cc   
2007-04-21 22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/mb_mblock.cc   
2007-04-22 00:51:18 UTC (rev 5067)
@@ -42,7 +42,9 @@
 mb_mblock::mb_mblock(mb_runtime *runtime,
                     const std::string &instance_name,
                     pmt_t user_arg)
-  : d_impl(mb_mblock_impl_sptr(new mb_mblock_impl(runtime, this, 
instance_name)))
+  : d_impl(mb_mblock_impl_sptr(
+              new mb_mblock_impl(dynamic_cast<mb_runtime_base*>(runtime),
+                                 this, instance_name)))
 {
 }
 
@@ -198,3 +200,30 @@
 {
   d_impl->runtime()->request_shutdown(result);
 }
+
+pmt_t
+mb_mblock::schedule_one_shot_timeout(const mb_time &abs_time, pmt_t user_data)
+{
+  mb_msg_accepter_sptr accepter = impl()->make_accepter(s_sys_port);
+  return d_impl->runtime()->schedule_one_shot_timeout(abs_time, user_data,
+                                                     accepter);
+}
+
+pmt_t
+mb_mblock::schedule_periodic_timeout(const mb_time &first_abs_time,
+                                    const mb_time &delta_time,
+                                    pmt_t user_data)
+{
+  mb_msg_accepter_sptr accepter = impl()->make_accepter(s_sys_port);
+  return d_impl->runtime()->schedule_periodic_timeout(first_abs_time,
+                                                     delta_time,
+                                                     user_data,
+                                                     accepter);
+}
+
+void
+mb_mblock::cancel_timeout(pmt_t handle)
+{
+  d_impl->runtime()->cancel_timeout(handle);
+}
+

Modified: gnuradio/branches/features/inband-usb/mblock/src/lib/mb_mblock.h
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/mb_mblock.h    
2007-04-21 22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/mb_mblock.h    
2007-04-22 00:51:18 UTC (rev 5067)
@@ -24,6 +24,7 @@
 #include <mb_common.h>
 #include <mb_message.h>
 #include <mb_port.h>
+#include <mb_time.h>
 
 
 /*!
@@ -242,6 +243,62 @@
   mb_mblock *parent() const;
 
   /*!
+   * \brief Schedule a "one shot" timeout.
+   *
+   * \param abs_time the absolute time at which the timeout should fire
+   * \param user_data the data passed in the %timeout message.
+   *
+   * When the timeout fires, a message will be sent to the mblock.
+   *
+   * The message will have port_id = %sys-port, signal = %timeout,
+   * data = user_data, metadata = the handle returned from
+   * schedule_one_shot_timeout, pri = MB_PRI_BEST.
+   *
+   * \returns a handle that can be used in cancel_timeout, and is passed
+   * as the metadata field of the generated %timeout message.
+   *
+   * To cancel a pending timeout, call cancel_timeout.
+   */
+  pmt_t
+  schedule_one_shot_timeout(const mb_time &abs_time, pmt_t user_data);
+
+  /*!
+   * \brief Schedule a periodic timeout.
+   *
+   * \param first_abs_time The absolute time at which the first timeout should 
fire.
+   * \param delta_time The relative delay between the first and successive 
timeouts.
+   * \param user_data the data passed in the %timeout message.
+   *
+   * When the timeout fires, a message will be sent to the mblock, and a
+   * new timeout will be scheduled for previous absolute time + delta_time.
+   *
+   * The message will have port_id = %sys-port, signal = %timeout,
+   * data = user_data, metadata = the handle returned from
+   * schedule_one_shot_timeout, pri = MB_PRI_BEST.
+   *
+   * \returns a handle that can be used in cancel_timeout, and is passed
+   * as the metadata field of the generated %timeout message.
+   *
+   * To cancel a pending timeout, call cancel_timeout.
+   */
+  pmt_t
+  schedule_periodic_timeout(const mb_time &first_abs_time,
+                           const mb_time &delta_time,
+                           pmt_t user_data);
+
+  /*!
+   * \brief Attempt to cancel a pending timeout.
+   *
+   * Note that this only stops a future timeout from firing.  It is
+   * possible that a timeout may have already fired and enqueued a
+   * %timeout message, but that that message has not yet been seen by
+   * handle_message.
+   *
+   * \param handle returned from schedule_one_shot_timeout or 
schedule_periodic_timeout.
+   */
+  void cancel_timeout(pmt_t handle);
+
+  /*!
    * \brief Perform a pre-order depth-first traversal of the hierarchy.
    *
    * The traversal stops and returns false if any call to visitor returns 
false.

Modified: gnuradio/branches/features/inband-usb/mblock/src/lib/mb_mblock_impl.cc
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/mb_mblock_impl.cc      
2007-04-21 22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/mb_mblock_impl.cc      
2007-04-22 00:51:18 UTC (rev 5067)
@@ -52,7 +52,7 @@
 
 ////////////////////////////////////////////////////////////////////////
 
-mb_mblock_impl::mb_mblock_impl(mb_runtime *runtime, mb_mblock *mb,
+mb_mblock_impl::mb_mblock_impl(mb_runtime_base *runtime, mb_mblock *mb,
                               const std::string &instance_name)
   : d_runtime(runtime), d_mb(mb), d_mb_parent(0), 
     d_instance_name(instance_name), d_class_name("mblock")

Modified: gnuradio/branches/features/inband-usb/mblock/src/lib/mb_mblock_impl.h
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/mb_mblock_impl.h       
2007-04-21 22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/mb_mblock_impl.h       
2007-04-22 00:51:18 UTC (rev 5067)
@@ -22,6 +22,7 @@
 #define INCLUDED_MB_MBLOCK_IMPL_H
 
 #include <mb_mblock.h>
+#include <mb_runtime_base.h>
 #include <mb_connection.h>
 #include <mb_msg_queue.h>
 #include <list>
@@ -37,7 +38,7 @@
  */
 class mb_mblock_impl : boost::noncopyable
 {
-  mb_runtime                  *d_runtime;      // pointer to runtime
+  mb_runtime_base             *d_runtime;      // pointer to runtime
   mb_mblock                   *d_mb;           // pointer to our associated 
mblock
   mb_mblock                   *d_mb_parent;    // pointer to our parent
 
@@ -51,7 +52,8 @@
   mb_msg_queue                 d_msgq;         // incoming messages for us
 
 public:
-  mb_mblock_impl(mb_runtime *runtime, mb_mblock *mb, const std::string 
&instance_name);
+  mb_mblock_impl(mb_runtime_base *runtime, mb_mblock *mb,
+                const std::string &instance_name);
   ~mb_mblock_impl();
 
   /*!
@@ -185,10 +187,10 @@
   mb_mblock_sptr component(const std::string &comp_name);
 
   //! Return the runtime instance
-  mb_runtime *runtime() { return d_runtime; }
+  mb_runtime_base *runtime() { return d_runtime; }
 
   //! Set the runtime instance
-  void set_runtime(mb_runtime *runtime) { d_runtime = runtime; }
+  void set_runtime(mb_runtime_base *runtime) { d_runtime = runtime; }
 
   /*
    * Our implementation methods

Copied: 
gnuradio/branches/features/inband-usb/mblock/src/lib/mb_msg_accepter_msgq.cc 
(from rev 5066, 
gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_msg_accepter_msgq.cc)
===================================================================
--- 
gnuradio/branches/features/inband-usb/mblock/src/lib/mb_msg_accepter_msgq.cc    
                            (rev 0)
+++ 
gnuradio/branches/features/inband-usb/mblock/src/lib/mb_msg_accepter_msgq.cc    
    2007-04-22 00:51:18 UTC (rev 5067)
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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 2, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <mb_msg_accepter_msgq.h>
+#include <mb_message.h>
+
+pmt_t s_sys_port = pmt_intern("%sys-port");
+
+mb_msg_accepter_msgq::mb_msg_accepter_msgq(mb_msg_queue *msgq)
+  : d_msgq(msgq)
+{
+}
+
+mb_msg_accepter_msgq::~mb_msg_accepter_msgq()
+{
+}
+
+void
+mb_msg_accepter_msgq::operator()(pmt_t signal, pmt_t data,
+                                pmt_t metadata, mb_pri_t priority)
+{
+  mb_message_sptr msg = mb_make_message(signal, data, metadata, priority);
+  msg->set_port_id(s_sys_port);
+  d_msgq->insert(msg);
+}

Copied: 
gnuradio/branches/features/inband-usb/mblock/src/lib/mb_msg_accepter_msgq.h 
(from rev 5066, 
gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_msg_accepter_msgq.h)
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/mb_msg_accepter_msgq.h 
                        (rev 0)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/mb_msg_accepter_msgq.h 
2007-04-22 00:51:18 UTC (rev 5067)
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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 2, 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_MB_MSG_ACCEPTER_MSGQ_H
+#define INCLUDED_MB_MSG_ACCEPTER_MSGQ_H
+
+#include <mb_msg_accepter.h>
+#include <mb_msg_queue.h>
+
+/*!
+ * \brief Concrete class that accepts messages and inserts them into a message 
queue.
+ */
+class mb_msg_accepter_msgq : public mb_msg_accepter {
+  mb_msg_queue *d_msgq;
+
+public:
+  mb_msg_accepter_msgq(mb_msg_queue *msgq);
+  ~mb_msg_accepter_msgq();
+  void operator()(pmt_t signal, pmt_t data, pmt_t metadata, mb_pri_t priority);
+};
+
+#endif /* INCLUDED_MB_MSG_ACCEPTER_MSGQ_H */

Modified: gnuradio/branches/features/inband-usb/mblock/src/lib/mb_msg_queue.cc
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/mb_msg_queue.cc        
2007-04-21 22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/mb_msg_queue.cc        
2007-04-22 00:51:18 UTC (rev 5067)
@@ -83,7 +83,7 @@
     }
   }
 
-  return mb_message_sptr();    // equivalent of a zero pointer
+  return mb_message_sptr();            // eqv to a zero pointer
 }
 
 
@@ -109,3 +109,20 @@
   }
 }
 
+mb_message_sptr
+mb_msg_queue::get_highest_pri_msg_timedwait(const mb_time &abs_time)
+{
+  unsigned long secs  = abs_time.d_secs;
+  unsigned long nsecs = abs_time.d_nsecs;
+
+  omni_mutex_lock l(d_mutex);
+
+  while (1){
+    mb_message_sptr msg = get_highest_pri_msg_helper();
+    if (msg)                   // Got one; return it
+      return msg;
+
+    if (!d_not_empty.timedwait(secs, nsecs))   // timed out
+      return mb_message_sptr();                        // eqv to zero pointer
+  }
+}

Modified: gnuradio/branches/features/inband-usb/mblock/src/lib/mb_msg_queue.h
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/mb_msg_queue.h 
2007-04-21 22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/mb_msg_queue.h 
2007-04-22 00:51:18 UTC (rev 5067)
@@ -23,6 +23,7 @@
 
 #include <mb_common.h>
 #include <omnithread.h>
+#include <mb_time.h>
 
 /*!
  * \brief priority queue for mblock messages
@@ -63,6 +64,19 @@
    * If the queue is empty, this call blocks until it can return a message.
    */
   mb_message_sptr get_highest_pri_msg();
+
+  /*
+   * \brief Delete highest pri message from the queue and return it.
+   * If the queue is empty, this call blocks until it can return a message
+   * or real-time exceeds the absolute time, abs_time.
+   *
+   * \param abs_time specifies the latest absolute time to wait until.
+   * \sa mb_time::time
+   *
+   * \returns a valid mb_message_sptr, or the equivalent of a zero pointer
+   * if the call timed out while waiting.
+   */
+  mb_message_sptr get_highest_pri_msg_timedwait(const mb_time &abs_time);
 };
 
 #endif /* INCLUDED_MB_MSG_QUEUE_H */

Modified: gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime.cc
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime.cc  
2007-04-21 22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime.cc  
2007-04-22 00:51:18 UTC (rev 5067)
@@ -37,8 +37,3 @@
   // nop
 }
 
-void
-mb_runtime::request_shutdown(pmt_t result)
-{
-  // nop
-}

Modified: gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime.h
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime.h   
2007-04-21 22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime.h   
2007-04-22 00:51:18 UTC (rev 5067)
@@ -37,13 +37,8 @@
 class mb_runtime : boost::noncopyable,
                   public boost::enable_shared_from_this<mb_runtime>
 {
-  friend class mb_mblock_impl;
-
-  omni_mutex           d_brl;  // big runtime lock (avoid using this if 
possible...)
-
 protected:  
   mb_mblock_sptr       d_top;
-  
 
 public:
   mb_runtime(){}
@@ -66,32 +61,8 @@
                   pmt_t user_arg,
                   pmt_t *result = 0) = 0;
 
-
-  // ----------------------------------------------------------------
-  // Stuff from here down is really private to the implementation...
-  // ----------------------------------------------------------------
-
-  /*!
-   * \brief lock the big runtime lock
-   * \implementation
-   */
-  inline void lock() { d_brl.lock(); }
-
-  /*!
-   * \brief unlock the big runtime lock
-   * \implementation
-   */
-  inline void unlock() { d_brl.unlock(); }
-
-  virtual void request_shutdown(pmt_t result);
-
+  // QA only...
   mb_mblock_sptr top() { return d_top; }
-
-protected:
-  virtual mb_mblock_sptr
-  create_component(const std::string &instance_name,
-                  const std::string &class_name,
-                  pmt_t user_arg) = 0;
 };
 
 #endif /* INCLUDED_MB_RUNTIME_H */

Copied: gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_base.cc 
(from rev 5066, 
gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_runtime_base.cc)
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_base.cc     
                        (rev 0)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_base.cc     
2007-04-22 00:51:18 UTC (rev 5067)
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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 2, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <mb_runtime_base.h>
+
+/*
+ * Default nop implementations...
+ */
+
+void
+mb_runtime_base::request_shutdown(pmt_t result)
+{
+}
+
+pmt_t
+mb_runtime_base::schedule_one_shot_timeout(const mb_time &abs_time,
+                                          pmt_t user_data,
+                                          mb_msg_accepter_sptr accepter)
+{
+  return PMT_F;
+}
+
+pmt_t
+mb_runtime_base::schedule_periodic_timeout(const mb_time &first_abs_time,
+                                          const mb_time &delta_time,
+                                          pmt_t user_data,
+                                          mb_msg_accepter_sptr accepter)
+{
+  return PMT_F;
+}
+
+void
+mb_runtime_base::cancel_timeout(pmt_t handle)
+{
+}
+

Copied: gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_base.h 
(from rev 5066, 
gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_runtime_base.h)
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_base.h      
                        (rev 0)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_base.h      
2007-04-22 00:51:18 UTC (rev 5067)
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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 2, 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_MB_RUNTIME_BASE_H
+#define INCLUDED_MB_RUNTIME_BASE_H
+
+#include <mb_runtime.h>
+#include <omnithread.h>
+#include <mb_time.h>
+
+/*
+ * \brief This is the runtime class used by the implementation.
+ */
+class mb_runtime_base : public mb_runtime
+{
+  omni_mutex           d_brl;  // big runtime lock (avoid using this if 
possible...)
+
+protected:
+  mb_msg_accepter_sptr  d_accepter;
+
+public:
+
+  /*!
+   * \brief lock the big runtime lock
+   * \implementation
+   */
+  inline void lock() { d_brl.lock(); }
+
+  /*!
+   * \brief unlock the big runtime lock
+   * \implementation
+   */
+  inline void unlock() { d_brl.unlock(); }
+
+  virtual void request_shutdown(pmt_t result);
+
+  virtual mb_mblock_sptr
+  create_component(const std::string &instance_name,
+                  const std::string &class_name,
+                  pmt_t user_arg) = 0;
+
+  virtual pmt_t
+  schedule_one_shot_timeout(const mb_time &abs_time, pmt_t user_data,
+                           mb_msg_accepter_sptr accepter);
+
+  virtual pmt_t
+  schedule_periodic_timeout(const mb_time &first_abs_time,
+                           const mb_time &delta_time,
+                           pmt_t user_data,
+                           mb_msg_accepter_sptr accepter);
+  virtual void
+  cancel_timeout(pmt_t handle);
+
+  mb_msg_accepter_sptr
+  accepter() { return d_accepter; }
+  
+};
+
+
+#endif /* INCLUDED_MB_RUNTIME_BASE_H */

Modified: gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_nop.h
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_nop.h       
2007-04-21 22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_nop.h       
2007-04-22 00:51:18 UTC (rev 5067)
@@ -21,7 +21,7 @@
 #ifndef INCLUDED_MB_RUNTIME_NOP_H
 #define INCLUDED_MB_RUNTIME_NOP_H
 
-#include <mb_runtime.h>
+#include <mb_runtime_base.h>
 
 /*!
  * \brief Public constructor (factory) for mb_runtime_nop objects.
@@ -31,7 +31,7 @@
 /*!
  * \brief Concrete runtime that does nothing.  Used only during early QA tests.
  */
-class mb_runtime_nop : public mb_runtime
+class mb_runtime_nop : public mb_runtime_base
 {
 public:
   mb_runtime_nop();

Deleted: 
gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_placeholder.cc

Deleted: 
gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_placeholder.h

Modified: 
gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_thread_per_block.cc
===================================================================
--- 
gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_thread_per_block.cc
 2007-04-21 22:33:03 UTC (rev 5066)
+++ 
gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_thread_per_block.cc
 2007-04-22 00:51:18 UTC (rev 5067)
@@ -30,12 +30,20 @@
 #include <mb_worker.h>
 #include <omnithread.h>
 #include <iostream>
+#include <mb_msg_accepter_msgq.h>
 
+
+static pmt_t s_halt = pmt_intern("%halt");
 static pmt_t s_sys_port = pmt_intern("%sys-port");
 static pmt_t s_shutdown = pmt_intern("%shutdown");
-static pmt_t s_halt = pmt_intern("%halt");
+static pmt_t s_request_shutdown = pmt_intern("%request-shutdown");
+static pmt_t s_worker_state_changed = pmt_intern("%worker-state-changed");
+static pmt_t s_timeout = pmt_intern("%timeout");
+static pmt_t s_request_timeout = pmt_intern("%request-timeout");
+static pmt_t s_cancel_timeout = pmt_intern("%cancel-timeout");
+static pmt_t s_send_halt = pmt_intern("send-halt");
+static pmt_t s_exit_now = pmt_intern("exit-now");
 
-
 static void
 send_sys_msg(mb_msg_queue &msgq, pmt_t signal,
             pmt_t data = PMT_F, pmt_t metadata = PMT_F,
@@ -48,10 +56,10 @@
 
 
 mb_runtime_thread_per_block::mb_runtime_thread_per_block()
-  : d_runtime_cond(&d_mutex),
-    d_shutdown_requested(false), d_shutdown_in_progress(false),
+  : d_shutdown_in_progress(false),
     d_shutdown_result(PMT_T)
 {
+  d_accepter = mb_msg_accepter_sptr(new mb_msg_accepter_msgq(&d_msgq));
 }
 
 mb_runtime_thread_per_block::~mb_runtime_thread_per_block()
@@ -66,13 +74,7 @@
 void
 mb_runtime_thread_per_block::request_shutdown(pmt_t result)
 {
-  omni_mutex_lock l1(d_mutex);
-
-  if (!d_shutdown_requested){
-    d_shutdown_result = result;
-    d_shutdown_requested = true;
-    d_runtime_cond.broadcast();
-  }
+  (*accepter())(s_request_shutdown, result, PMT_F, MB_PRI_BEST);
 }
 
 bool
@@ -84,12 +86,14 @@
     *result = PMT_F;
   
   // reset the shutdown state
-  d_shutdown_requested = false;
   d_shutdown_in_progress = false;
   d_shutdown_result = PMT_T;
 
   assert(d_workers.empty());
 
+  while (!d_timer_queue.empty())       // ensure timer queue is empty
+    d_timer_queue.pop();
+
   /*
    * Create the top-level component, and recursively all of its
    * subcomponents.
@@ -114,38 +118,85 @@
 void
 mb_runtime_thread_per_block::run_loop()
 {
-  /*
-   * FIXME probably ought to recode this to use a message queue
-   * and state machine like the rest of the world ;)
-   */
+  while (1){
+    mb_message_sptr msg;
 
-  omni_mutex_lock l1(d_mutex);
+    if (d_timer_queue.empty())                   // Any timeouts pending?
+      msg = d_msgq.get_highest_pri_msg();        // Nope.  Block forever.
 
-  while (1){
+    else {
+      mb_timeout_sptr to = d_timer_queue.top();          // Yep.  Get earliest 
timeout.
 
-    reap_dead_workers();
+      // wait for a msg or the timeout...
+      msg = d_msgq.get_highest_pri_msg_timedwait(to->d_when);
 
-    if (d_workers.empty())     // no work left to do...
-      return;          
+      if (!msg){               // We timed out.
+       d_timer_queue.pop();    // Remove timeout from timer queue.
 
-    if (d_shutdown_requested && !d_shutdown_in_progress){
-      d_shutdown_in_progress = true;
+       // send the %timeout msg
+       (*to->d_accepter)(s_timeout, to->d_user_data, to->handle(), 
MB_PRI_BEST);
 
-      // FIXME state machine, delay before sending %halt
-      send_all_sys_msg(s_shutdown);
+       if (to->d_is_periodic){
+         to->d_when = to->d_when + to->d_delta;        // update time of next 
firing
+         d_timer_queue.push(to);                       // push it back into 
the queue
+       }
+       continue;
+      }
+    }
+
+    pmt_t signal = msg->signal();
+
+    if (pmt_eq(signal, s_worker_state_changed)){       // %worker-state-changed
+      omni_mutex_lock l1(d_workers_mutex);
+      reap_dead_workers();
+      if (d_workers.empty())   // no work left to do...
+       return;
+    }
+    else if (pmt_eq(signal, s_request_shutdown)){      // %request-shutdown
+      if (!d_shutdown_in_progress){
+       d_shutdown_in_progress = true;
+       d_shutdown_result = msg->data();
+
+       // schedule a timeout for ourselves...
+       schedule_one_shot_timeout(mb_time::time(0.100), s_send_halt, 
d_accepter);
+       send_all_sys_msg(s_shutdown);
+      }
+    }
+    else if (pmt_eq(signal, s_request_timeout)){       // %request-timeout
+      mb_timeout_sptr to =
+       boost::any_cast<mb_timeout_sptr>(pmt_any_ref(msg->data()));
+      d_timer_queue.push(to);
+    }
+    else if (pmt_eq(signal, s_cancel_timeout)){                // 
%cancel-timeout
+      d_timer_queue.cancel(msg->data());
+    }
+    else if (pmt_eq(signal, s_timeout)
+            && pmt_eq(msg->data(), s_send_halt)){      // %timeout, send-halt
+
+      // schedule another timeout for ourselves...
+      schedule_one_shot_timeout(mb_time::time(0.100), s_exit_now, d_accepter);
       send_all_sys_msg(s_halt);
+    }
+    else if (pmt_eq(signal, s_timeout)
+            && pmt_eq(msg->data(), s_exit_now)){       // %timeout, exit-now
 
-      continue;
+      // We only get here if we've sent all workers %shutdown followed
+      // by %halt, and one or more of them is still alive.  They must
+      // be blocked in the kernel.  FIXME We could add one more step:
+      // pthread_kill(...) but for now, we'll just ignore them...
+      return;
     }
-
-    d_runtime_cond.wait();     // wait for something to do.
+    else {
+      std::cerr << "mb_runtime_thread_per_block: unhandled msg: " << msg << 
std::endl;
+    }
   }
 }
 
 void
 mb_runtime_thread_per_block::reap_dead_workers()
 {
-  // omni_mutex_lock l1(d_mutex);
+  // Already holding mutex
+  // omni_mutex_lock l1(d_workers_mutex);
 
   for (worker_iter_t wi = d_workers.begin(); wi != d_workers.end(); ){
     bool is_dead;
@@ -178,6 +229,8 @@
 // Create the thread, then create the component in the thread.
 // Return a pointer to the created mblock.
 //
+// Can be invoked from any thread
+//
 mb_mblock_sptr
 mb_runtime_thread_per_block::create_component(const std::string &instance_name,
                                              const std::string &class_name,
@@ -227,7 +280,7 @@
 
   // Add w to the vector of workers, and return the mblock.
   {
-    omni_mutex_lock l(d_mutex);
+    omni_mutex_lock l(d_workers_mutex);
     d_workers.push_back(w);
   }
 
@@ -245,11 +298,52 @@
                                              pmt_t metadata,
                                              mb_pri_t priority)
 {
-  // Already holding lock
-  // omni_mutex_lock l1(d_mutex);
+  omni_mutex_lock l1(d_workers_mutex);
 
   for (worker_iter_t wi = d_workers.begin(); wi != d_workers.end(); ++wi){
     send_sys_msg((*wi)->d_mblock->impl()->msgq(),
                 signal, data, metadata, priority);
   }
 }
+
+//
+// Can be invoked from any thread.
+// Sends a message to the runtime.
+//
+pmt_t
+mb_runtime_thread_per_block::schedule_one_shot_timeout
+  (const mb_time &abs_time,
+   pmt_t user_data,
+   mb_msg_accepter_sptr accepter)
+{
+  mb_timeout_sptr to(new mb_timeout(abs_time, user_data, accepter));
+  (*d_accepter)(s_request_timeout, pmt_make_any(to), PMT_F, MB_PRI_BEST);
+  return to->handle();
+}
+
+//
+// Can be invoked from any thread.
+// Sends a message to the runtime.
+//
+pmt_t
+mb_runtime_thread_per_block::schedule_periodic_timeout
+  (const mb_time &first_abs_time,
+   const mb_time &delta_time,
+   pmt_t user_data,
+   mb_msg_accepter_sptr accepter)
+{
+  mb_timeout_sptr to(new mb_timeout(first_abs_time, delta_time,
+                                   user_data, accepter));
+  (*d_accepter)(s_request_timeout, pmt_make_any(to), PMT_F, MB_PRI_BEST);
+  return to->handle();
+}
+
+//
+// Can be invoked from any thread.
+// Sends a message to the runtime.
+//
+void
+mb_runtime_thread_per_block::cancel_timeout(pmt_t handle)
+{
+  (*d_accepter)(s_cancel_timeout, handle, PMT_F, MB_PRI_BEST);
+}

Modified: 
gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_thread_per_block.h
===================================================================
--- 
gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_thread_per_block.h
  2007-04-21 22:33:03 UTC (rev 5066)
+++ 
gnuradio/branches/features/inband-usb/mblock/src/lib/mb_runtime_thread_per_block.h
  2007-04-22 00:51:18 UTC (rev 5067)
@@ -21,8 +21,10 @@
 #ifndef INCLUDED_MB_RUNTIME_THREAD_PER_BLOCK_H
 #define INCLUDED_MB_RUNTIME_THREAD_PER_BLOCK_H
 
-#include <mb_runtime.h>
+#include <mb_runtime_base.h>
 #include <mb_worker.h>
+#include <mb_msg_queue.h>
+#include <mb_timer_queue.h>
 
 /*!
  * \brief Concrete runtime that uses a thread per mblock
@@ -30,18 +32,16 @@
  *
  * These are all implementation details.
  */
-class mb_runtime_thread_per_block : public mb_runtime
+class mb_runtime_thread_per_block : public mb_runtime_base
 {
 public:
-  omni_mutex                 d_mutex;
-  omni_condition             d_runtime_cond;  // runtime waits here
-  //std::vector<mb_worker_sptr> d_workers;
+  omni_mutex                 d_workers_mutex;  // hold while manipulating 
d_workers
   std::vector<mb_worker*>     d_workers;
-  bool                       d_shutdown_requested;
   bool                       d_shutdown_in_progress;
   pmt_t                              d_shutdown_result;
+  mb_msg_queue               d_msgq;
+  mb_timer_queue             d_timer_queue;
 
-  //typedef std::vector<mb_worker_sptr>::iterator  worker_iter_t;
   typedef std::vector<mb_worker*>::iterator  worker_iter_t;
 
   mb_runtime_thread_per_block();
@@ -60,13 +60,25 @@
                   const std::string &class_name,
                   pmt_t user_arg);
 
+  pmt_t
+  schedule_one_shot_timeout(const mb_time &abs_time, pmt_t user_data,
+                           mb_msg_accepter_sptr accepter);
+
+  pmt_t
+  schedule_periodic_timeout(const mb_time &first_abs_time,
+                           const mb_time &delta_time,
+                           pmt_t user_data,
+                           mb_msg_accepter_sptr accepter);
+  void
+  cancel_timeout(pmt_t handle);
+
+private:
   void reap_dead_workers();
   void run_loop();
 
   void send_all_sys_msg(pmt_t signal, pmt_t data = PMT_F,
                        pmt_t metadata = PMT_F,
                        mb_pri_t priority = MB_PRI_BEST);
-
 };
 
 #endif /* INCLUDED_MB_RUNTIME_THREAD_PER_BLOCK_H */

Copied: gnuradio/branches/features/inband-usb/mblock/src/lib/mb_time.cc (from 
rev 5066, gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_time.cc)
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/mb_time.cc             
                (rev 0)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/mb_time.cc     
2007-04-22 00:51:18 UTC (rev 5067)
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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 2, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <mb_time.h>
+#include <omnithread.h>
+#include <math.h>
+#include <assert.h>
+
+
+mb_time::mb_time(double real_secs)
+{
+  double floor_secs = floor(real_secs);
+  d_secs = (long) floor_secs;
+  d_nsecs = (long) ((real_secs - floor_secs) * 1e9);     // always positive
+}
+
+mb_time
+mb_time::time(const mb_time &delta_t)
+{
+  unsigned long        abs_sec, abs_nsec;
+  unsigned long rel_sec  = delta_t.d_secs;
+  unsigned long rel_nsec = delta_t.d_nsecs;
+  
+  omni_thread::get_time(&abs_sec, &abs_nsec, rel_sec, rel_nsec);
+  return mb_time(abs_sec, abs_nsec);
+}
+
+
+mb_time
+operator+(const mb_time &x, const mb_time &y)
+{
+  mb_time r(x.d_secs + y.d_secs, x.d_nsecs + y.d_nsecs);
+  while (r.d_nsecs >= 1000000000){
+    r.d_nsecs -= 1000000000;
+    r.d_secs++;
+  }
+  return r;
+}
+
+mb_time
+operator-(const mb_time &x, const mb_time &y)
+{
+  // assert(!(x < y));
+
+  mb_time r(x.d_secs - y.d_secs, x.d_nsecs - y.d_nsecs);
+  while (r.d_nsecs < 0){
+    r.d_nsecs += 1000000000;
+    r.d_secs--;
+  }
+  return r;
+}
+
+mb_time
+operator+(const mb_time &x, double y)
+{
+  return x + mb_time(y);
+}
+
+mb_time
+operator-(const mb_time &x, double y)
+{
+  return x - mb_time(y);
+}

Copied: gnuradio/branches/features/inband-usb/mblock/src/lib/mb_time.h (from 
rev 5066, gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_time.h)
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/mb_time.h              
                (rev 0)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/mb_time.h      
2007-04-22 00:51:18 UTC (rev 5067)
@@ -0,0 +1,89 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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 2, 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_MB_TIME_H
+#define INCLUDED_MB_TIME_H
+
+struct mb_time {
+  long int d_secs;     // seconds.
+  long int d_nsecs;    // nanoseconds.  Always in [0, 1e9-1]
+
+  mb_time() : d_secs(0), d_nsecs(0) {}
+  mb_time(long secs, long nanosecs=0) : d_secs(secs), d_nsecs(nanosecs) {}
+
+  // N.B., this only makes sense for differences between times.
+  // Double doesn't have enough bits to precisely represent an absolute time.
+  mb_time(double secs);
+
+  // N.B. This only makes sense for differences between times.
+  // Double doesn't have enough bits to precisely represent an absolute time.
+  double double_time() const { return (double)d_secs + d_nsecs * 1e-9; }
+
+  /*!
+   * \brief Return an absolute time suitable for use with
+   * schedule_one_shot_timeout & schedule_periodic_timeout
+   *
+   * The return value is the current time plus the given relative offset.
+   */
+  static mb_time time(const mb_time &relative_offset = mb_time());
+};
+
+
+inline static bool
+operator<(const mb_time &x, const mb_time &y)
+{
+  return ((x.d_secs < y.d_secs)
+         || (x.d_secs == y.d_secs && x.d_nsecs < y.d_nsecs));
+}
+
+inline static bool
+operator>(const mb_time &x, const mb_time &y)
+{
+  return ((x.d_secs > y.d_secs)
+         || (x.d_secs == y.d_secs && x.d_nsecs > y.d_nsecs));
+}
+
+inline static bool
+operator>=(const mb_time &x, const mb_time &y)
+{
+  return ((x.d_secs > y.d_secs)
+         || (x.d_secs == y.d_secs && x.d_nsecs >= y.d_nsecs));
+}
+
+inline static bool
+operator<=(const mb_time &x, const mb_time &y)
+{
+  return ((x.d_secs < y.d_secs)
+         || (x.d_secs == y.d_secs && x.d_nsecs <= y.d_nsecs));
+}
+
+inline static bool
+operator==(const mb_time &x, const mb_time &y)
+{
+  return (x.d_secs == y.d_secs && x.d_nsecs == y.d_nsecs);
+}
+
+
+mb_time operator+(const mb_time &x, const mb_time &y);
+mb_time operator+(const mb_time &x, double y);
+mb_time operator-(const mb_time &x, const mb_time &y);
+mb_time operator-(const mb_time &x, double y);
+
+#endif /* INCLUDED_MB_TIME_H */

Copied: gnuradio/branches/features/inband-usb/mblock/src/lib/mb_timer_queue.cc 
(from rev 5066, 
gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_timer_queue.cc)
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/mb_timer_queue.cc      
                        (rev 0)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/mb_timer_queue.cc      
2007-04-22 00:51:18 UTC (rev 5067)
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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 2, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <mb_timer_queue.h>
+
+static pmt_t
+make_handle()
+{
+  static long counter = 0;
+  pmt_t n = pmt_from_long(counter++);
+  return pmt_list1(n);         // guaranteed to be a unique object
+}
+
+// one-shot constructor
+mb_timeout::mb_timeout(const mb_time &abs_time,
+                      pmt_t user_data, mb_msg_accepter_sptr accepter)
+  : d_when(abs_time), d_is_periodic(false),
+    d_user_data(user_data), d_handle(make_handle()), d_accepter(accepter)
+{
+}
+
+// periodic constructor
+mb_timeout::mb_timeout(const mb_time &first_abs_time, const mb_time 
&delta_time,
+                      pmt_t user_data, mb_msg_accepter_sptr accepter)
+  : d_when(first_abs_time), d_delta(delta_time), d_is_periodic(true),
+    d_user_data(user_data), d_handle(make_handle()), d_accepter(accepter)
+{
+}
+
+void
+mb_timer_queue::cancel(pmt_t handle)
+{
+  container_type::iterator it;
+
+  for (it = c.begin(); it != c.end();){
+    if (pmt_equal((*it)->handle(), handle))
+      it = c.erase(it);
+    else
+      ++it;
+  }
+  std::make_heap(c.begin(), c.end(), comp);
+}

Copied: gnuradio/branches/features/inband-usb/mblock/src/lib/mb_timer_queue.h 
(from rev 5066, 
gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_timer_queue.h)
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/mb_timer_queue.h       
                        (rev 0)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/mb_timer_queue.h       
2007-04-22 00:51:18 UTC (rev 5067)
@@ -0,0 +1,73 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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 2, 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_MB_TIMER_QUEUE_H
+#define INCLUDED_MB_TIMER_QUEUE_H
+
+#include <mb_time.h>
+#include <vector>
+#include <queue>
+#include <pmt.h>
+#include <mb_msg_accepter.h>
+
+class mb_timeout {
+public:
+  mb_time              d_when;         // absolute time to fire timeout
+  mb_time              d_delta;        // if periodic, delta_t to next timeout
+  bool                 d_is_periodic;  // true iff this is a periodic timeout
+  pmt_t                        d_user_data;    // data from %timeout msg
+  pmt_t                        d_handle;       // handle for cancellation
+  mb_msg_accepter_sptr d_accepter;     // where to send the message
+
+  // one-shot constructor
+  mb_timeout(const mb_time &abs_time,
+            pmt_t user_data, mb_msg_accepter_sptr accepter);
+
+  // periodic constructor
+  mb_timeout(const mb_time &first_abs_time, const mb_time &delta_time,
+            pmt_t user_data, mb_msg_accepter_sptr accepter);
+
+  pmt_t handle() const { return d_handle; }
+};
+
+typedef boost::shared_ptr<mb_timeout> mb_timeout_sptr;
+
+
+//! Sort criterion for priority_queue
+class timeout_later
+{
+public:
+  bool operator() (const mb_timeout_sptr t1, const mb_timeout_sptr t2)
+  {
+    return t1->d_when > t2->d_when;
+  }
+};
+
+
+class mb_timer_queue : public std::priority_queue<mb_timeout_sptr,
+                                                 std::vector<mb_timeout_sptr>,
+                                                 timeout_later>
+{
+public:
+  void cancel(pmt_t handle);
+};
+
+#endif /* INCLUDED_MB_TIMER_QUEUE_H */

Modified: gnuradio/branches/features/inband-usb/mblock/src/lib/mb_worker.cc
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/mb_worker.cc   
2007-04-21 22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/mb_worker.cc   
2007-04-22 00:51:18 UTC (rev 5067)
@@ -27,6 +27,7 @@
 #include <mb_exception.h>
 #include <mb_mblock.h>
 #include <mb_gettid.h>
+#include <mb_msg_accepter.h>
 #include <iostream>
 #ifdef HAVE_SCHED_H
 #include <sched.h>
@@ -34,6 +35,10 @@
 
 #define VERBOSE 0              // define to 0 or 1
 
+
+static pmt_t s_worker_state_changed = pmt_intern("%worker-state-changed");
+
+
 mb_worker::mb_worker(mb_runtime_thread_per_block *runtime,
                     mb_mblock_maker_t maker,
                     const std::string &instance_name,
@@ -81,12 +86,15 @@
 void
 mb_worker::set_state(worker_state_t state)
 {
-  omni_mutex_lock  l1(d_runtime->d_mutex);     // lock runtime first, then 
worker
-  omni_mutex_lock  l2(d_mutex);
+  {
+    omni_mutex_lock  l2(d_mutex);
 
-  d_state = state;                       // update our state
-  d_state_cond.broadcast();              // Notify everybody who cares...
-  d_runtime->d_runtime_cond.broadcast();
+    d_state = state;                     // update our state
+    d_state_cond.broadcast();            // Notify everybody who cares...
+  }
+
+  // send msg to runtime, telling it something changed.
+  (*d_runtime->accepter())(s_worker_state_changed, PMT_F, PMT_F, MB_PRI_BEST);
 }
 
 void *

Modified: 
gnuradio/branches/features/inband-usb/mblock/src/lib/mbi_runtime_lock.h
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/mbi_runtime_lock.h     
2007-04-21 22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/mbi_runtime_lock.h     
2007-04-22 00:51:18 UTC (rev 5067)
@@ -48,9 +48,9 @@
  */
 
 class mbi_runtime_lock : boost::noncopyable {
-  mb_runtime   *d_rt;
+  mb_runtime_base      *d_rt;
 public:
-  mbi_runtime_lock(mb_runtime *rt) : d_rt(rt) { d_rt->lock(); }
+  mbi_runtime_lock(mb_runtime_base *rt) : d_rt(rt) { d_rt->lock(); }
   mbi_runtime_lock(mb_mblock_impl *mi) : d_rt(mi->runtime()) { d_rt->lock(); }
   mbi_runtime_lock(mb_mblock *mb) : d_rt(mb->impl()->runtime()) { 
d_rt->lock(); }
   ~mbi_runtime_lock(void) { d_rt->unlock(); }

Modified: gnuradio/branches/features/inband-usb/mblock/src/lib/qa_mblock.cc
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/qa_mblock.cc   
2007-04-21 22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/qa_mblock.cc   
2007-04-22 00:51:18 UTC (rev 5067)
@@ -28,6 +28,7 @@
 #include <qa_mblock_prims.h>
 #include <qa_mblock_send.h>
 #include <qa_mblock_sys.h>
+#include <qa_timeouts.h>
 
 CppUnit::TestSuite *
 qa_mblock::suite()
@@ -37,6 +38,7 @@
   s->addTest (qa_mblock_prims::suite());
   s->addTest (qa_mblock_send::suite());
   s->addTest (qa_mblock_sys::suite());
+  s->addTest (qa_timeouts::suite());
   
   return s;
 }

Copied: gnuradio/branches/features/inband-usb/mblock/src/lib/qa_timeouts.cc 
(from rev 5066, 
gnuradio/branches/developers/eb/ibu/mblock/src/lib/qa_timeouts.cc)
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/qa_timeouts.cc         
                (rev 0)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/qa_timeouts.cc 
2007-04-22 00:51:18 UTC (rev 5067)
@@ -0,0 +1,292 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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 2, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_timeouts.h>
+#include <cppunit/TestAssert.h>
+#include <mb_mblock.h>
+#include <mb_runtime.h>
+#include <mb_protocol_class.h>
+#include <mb_exception.h>
+#include <mb_msg_queue.h>
+#include <mb_message.h>
+#include <mb_mblock_impl.h>
+#include <mb_msg_accepter.h>
+#include <mb_class_registry.h>
+#include <mb_timer_queue.h>
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+
+
+static pmt_t s_timeout = pmt_intern("%timeout");
+static pmt_t s_done = pmt_intern("done");
+
+
+// ------------------------------------------------------------------------
+// This test exercises the priority queue that we use to implement timeouts
+// ------------------------------------------------------------------------
+void
+qa_timeouts::test_timer_queue()
+{
+  mb_timer_queue       tq;
+  mb_msg_accepter_sptr accepter;
+
+  mb_timeout_sptr      t1000_000 =
+    mb_timeout_sptr(new mb_timeout(mb_time(1000,0), PMT_F, accepter));
+
+  mb_timeout_sptr      t2000_000 =
+    mb_timeout_sptr(new mb_timeout(mb_time(2000,0), PMT_F, accepter));
+                                                                   
+  mb_timeout_sptr      t3000_000 =
+    mb_timeout_sptr(new mb_timeout(mb_time(3000,0), PMT_F, accepter));
+                                                                   
+  mb_timeout_sptr      t3000_125 =
+    mb_timeout_sptr(new mb_timeout(mb_time(3000,125), PMT_F, accepter));
+                                                                   
+  mb_timeout_sptr      t3000_250 =
+    mb_timeout_sptr(new mb_timeout(mb_time(3000,250), PMT_F, accepter));
+                                                                   
+  mb_timeout_sptr      t4000_000 =
+    mb_timeout_sptr(new mb_timeout(mb_time(4000,0), PMT_F, accepter));
+                                                                   
+  // insert in pseudo-random order
+
+  tq.push(t3000_125);
+  tq.push(t1000_000);
+  tq.push(t4000_000);
+  tq.push(t3000_250);
+  tq.push(t2000_000);
+  tq.push(t3000_000);
+
+  CPPUNIT_ASSERT_EQUAL(t1000_000, tq.top());
+  tq.pop();
+  
+  CPPUNIT_ASSERT_EQUAL(t2000_000, tq.top());
+  tq.pop();
+  
+  CPPUNIT_ASSERT_EQUAL(t3000_000, tq.top());
+  tq.pop();
+  
+  CPPUNIT_ASSERT_EQUAL(t3000_125, tq.top());
+  tq.pop();
+  
+  CPPUNIT_ASSERT_EQUAL(t3000_250, tq.top());
+  tq.pop();
+  
+  CPPUNIT_ASSERT_EQUAL(t4000_000, tq.top());
+  tq.pop();
+
+  CPPUNIT_ASSERT(tq.empty());
+
+  // insert in pseudo-random order
+
+  tq.push(t3000_000);
+  tq.push(t4000_000);
+  tq.push(t3000_125);
+  tq.push(t1000_000);
+  tq.push(t2000_000);
+  tq.push(t3000_250);
+
+  tq.cancel(t1000_000->handle());
+
+  CPPUNIT_ASSERT_EQUAL(t2000_000, tq.top());
+  tq.pop();
+  
+  CPPUNIT_ASSERT_EQUAL(t3000_000, tq.top());
+  tq.pop();
+  
+  tq.cancel(t3000_250->handle());
+
+  CPPUNIT_ASSERT_EQUAL(t3000_125, tq.top());
+  tq.pop();
+  
+  CPPUNIT_ASSERT_EQUAL(t4000_000, tq.top());
+  tq.pop();
+  
+  CPPUNIT_ASSERT(tq.empty());
+}
+
+// ------------------------------------------------------------------------
+//   Test one-shot timeouts
+// ------------------------------------------------------------------------
+
+// FWIW, on SuSE 10.1 for x86-64, clock_getres returns 0.004 seconds.
+
+#define TIMING_MARGIN 0.010    // seconds
+
+class qa_timeouts_1_top : public mb_mblock
+{
+  int          d_nleft;
+  int          d_nerrors;
+  mb_time      d_t0;
+  
+public:
+  qa_timeouts_1_top(mb_runtime *runtime,
+                   const std::string &instance_name, pmt_t user_arg);
+
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+};
+
+qa_timeouts_1_top::qa_timeouts_1_top(mb_runtime *runtime,
+                                    const std::string &instance_name,
+                                    pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg),
+    d_nleft(0), d_nerrors(0)
+{
+}
+
+void
+qa_timeouts_1_top::initial_transition()
+{
+  d_t0 = mb_time::time();      // now
+
+  schedule_one_shot_timeout(d_t0 + 0.200, pmt_from_double(0.200));
+  schedule_one_shot_timeout(d_t0 + 0.125, pmt_from_double(0.125));
+  schedule_one_shot_timeout(d_t0 + 0.075, pmt_from_double(0.075));
+  schedule_one_shot_timeout(d_t0 + 0.175, pmt_from_double(0.175));
+
+  d_nleft = 4;
+}
+
+void
+qa_timeouts_1_top::handle_message(mb_message_sptr msg)
+{
+  if (pmt_eq(msg->signal(), s_timeout)){
+    mb_time t_now = mb_time::time();
+    double expected_delta_t = pmt_to_double(msg->data());
+    double actual_delta_t = (t_now - d_t0).double_time();
+    double delta = expected_delta_t - actual_delta_t;
+
+    if (fabs(delta) > TIMING_MARGIN){
+      std::cerr << "qa_timeouts_1_top: expected_delta_t = " << expected_delta_t
+               << " actual_delta_t = " << actual_delta_t << std::endl;
+      d_nerrors++;
+    }
+
+    if (--d_nleft <= 0)
+      shutdown_all(d_nerrors == 0 ? PMT_T : PMT_F);
+  }
+}
+
+REGISTER_MBLOCK_CLASS(qa_timeouts_1_top);
+
+void
+qa_timeouts::test_timeouts_1()
+{
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_NIL;
+
+  rt->run("top", "qa_timeouts_1_top", PMT_F, &result);
+
+  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
+}
+
+// ------------------------------------------------------------------------
+//   Test periodic timeouts
+// ------------------------------------------------------------------------
+
+class qa_timeouts_2_top : public mb_mblock
+{
+  int          d_nhandled;
+  int          d_nerrors;
+  double       d_delta_t;
+  mb_time      d_t0;
+  
+public:
+  qa_timeouts_2_top(mb_runtime *runtime,
+                   const std::string &instance_name, pmt_t user_arg);
+
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+};
+
+qa_timeouts_2_top::qa_timeouts_2_top(mb_runtime *runtime,
+                                    const std::string &instance_name,
+                                    pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg),
+    d_nhandled(0), d_nerrors(0), d_delta_t(0.075)
+{
+}
+
+void
+qa_timeouts_2_top::initial_transition()
+{
+  d_t0 = mb_time::time();      // now
+
+  schedule_periodic_timeout(d_t0 + d_delta_t, mb_time(d_delta_t), PMT_T);
+}
+
+void
+qa_timeouts_2_top::handle_message(mb_message_sptr msg)
+{
+  static const int NMSGS_TO_HANDLE = 5;
+
+  if (pmt_eq(msg->signal(), s_timeout)
+      && !pmt_eq(msg->data(), s_done)){
+
+    mb_time t_now = mb_time::time();
+
+    d_nhandled++;
+
+    double expected_delta_t = d_delta_t * d_nhandled;
+    double actual_delta_t = (t_now - d_t0).double_time();
+    double delta = expected_delta_t - actual_delta_t;
+
+    if (fabs(delta) > TIMING_MARGIN){
+      std::cerr << "qa_timeouts_2_top: expected_delta_t = " << expected_delta_t
+               << " actual_delta_t = " << actual_delta_t << std::endl;
+      d_nerrors++;
+    }
+
+    if (d_nhandled == NMSGS_TO_HANDLE){
+      cancel_timeout(msg->metadata()); // test cancel_timeout...
+      schedule_one_shot_timeout(d_t0 + (d_delta_t * (d_nhandled + 2)), s_done);
+    }
+  }
+
+  if (pmt_eq(msg->signal(), s_timeout)
+      && pmt_eq(msg->data(), s_done)){
+    if (d_nhandled != NMSGS_TO_HANDLE){
+      std::cerr << "qa_timeouts_2_top: d_nhandled = " << d_nhandled
+               << " expected d_nhandled = " << NMSGS_TO_HANDLE
+               << " (cancel_timeout didn't work)\n";
+      d_nerrors++;
+    }
+    shutdown_all(d_nerrors == 0 ? PMT_T : PMT_F);
+  }
+}
+
+REGISTER_MBLOCK_CLASS(qa_timeouts_2_top);
+
+void
+qa_timeouts::test_timeouts_2()
+{
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_NIL;
+
+  rt->run("top", "qa_timeouts_2_top", PMT_F, &result);
+
+  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
+}

Copied: gnuradio/branches/features/inband-usb/mblock/src/lib/qa_timeouts.h 
(from rev 5066, 
gnuradio/branches/developers/eb/ibu/mblock/src/lib/qa_timeouts.h)
===================================================================
--- gnuradio/branches/features/inband-usb/mblock/src/lib/qa_timeouts.h          
                (rev 0)
+++ gnuradio/branches/features/inband-usb/mblock/src/lib/qa_timeouts.h  
2007-04-22 00:51:18 UTC (rev 5067)
@@ -0,0 +1,43 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2007 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_QA_TIMEOUTS_H
+#define INCLUDED_QA_TIMEOUTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_timeouts : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE(qa_timeouts);
+  CPPUNIT_TEST(test_timer_queue);
+  CPPUNIT_TEST(test_timeouts_1);
+  CPPUNIT_TEST(test_timeouts_2);
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  void test_timer_queue();
+  void test_timeouts_1();
+  void test_timeouts_2();
+};
+
+#endif /* INCLUDED_QA_TIMEOUTS_H */
+

Modified: gnuradio/branches/features/inband-usb/pmt/src/lib/Makefile.am
===================================================================
--- gnuradio/branches/features/inband-usb/pmt/src/lib/Makefile.am       
2007-04-21 22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/pmt/src/lib/Makefile.am       
2007-04-22 00:51:18 UTC (rev 5067)
@@ -76,6 +76,7 @@
 
 include_HEADERS =                      \
        pmt.h                           \
+       pmt_pool.h                      \
        pmt_serial_tags.h               
 
 noinst_HEADERS =                       \

Modified: gnuradio/branches/features/inband-usb/pmt/src/lib/pmt.cc
===================================================================
--- gnuradio/branches/features/inband-usb/pmt/src/lib/pmt.cc    2007-04-21 
22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/pmt/src/lib/pmt.cc    2007-04-22 
00:51:18 UTC (rev 5067)
@@ -135,6 +135,12 @@
   return dynamic_cast<pmt_dict*>(x.get());
 }
 
+static pmt_any *
+_any(pmt_t x)
+{
+  return dynamic_cast<pmt_any*>(x.get());
+}
+
 ////////////////////////////////////////////////////////////////////////////
 //                           Globals
 ////////////////////////////////////////////////////////////////////////////
@@ -200,7 +206,7 @@
   unsigned int h = 0;
   unsigned int g = 0;
 
-  for (std::string::const_iterator p = s.begin(); p != s.end(); p++){
+  for (std::string::const_iterator p = s.begin(); p != s.end(); ++p){
     h = (h << 4) + (*p & 0xff);
     g = h & 0xf0000000;
     if (g){
@@ -630,6 +636,40 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////
+//                                 Any
+////////////////////////////////////////////////////////////////////////////
+
+pmt_any::pmt_any(const boost::any &any) : d_any(any) {}
+
+bool
+pmt_is_any(pmt_t obj)
+{
+  return obj->is_any();
+}
+
+pmt_t
+pmt_make_any(const boost::any &any)
+{
+  return pmt_t(new pmt_any(any));
+}
+
+boost::any
+pmt_any_ref(pmt_t obj)
+{
+  if (!obj->is_any())
+    throw pmt_wrong_type("pmt_any_ref", obj);
+  return _any(obj)->ref();
+}
+
+void
+pmt_any_set(pmt_t obj, const boost::any &any)
+{
+  if (!obj->is_any())
+    throw pmt_wrong_type("pmt_any_set", obj);
+  _any(obj)->set(any);
+}
+
+////////////////////////////////////////////////////////////////////////////
 //                          General Functions
 ////////////////////////////////////////////////////////////////////////////
 

Modified: gnuradio/branches/features/inband-usb/pmt/src/lib/pmt.h
===================================================================
--- gnuradio/branches/features/inband-usb/pmt/src/lib/pmt.h     2007-04-21 
22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/pmt/src/lib/pmt.h     2007-04-22 
00:51:18 UTC (rev 5067)
@@ -24,6 +24,7 @@
 #define INCLUDED_PMT_H
 
 #include <boost/shared_ptr.hpp>
+#include <boost/any.hpp>
 #include <complex>
 #include <string>
 #include <stdint.h>
@@ -421,6 +422,28 @@
 
 /*
  * ------------------------------------------------------------------------
+ *   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
+bool pmt_is_any(pmt_t obj);
+
+//! make an any
+pmt_t pmt_make_any(const boost::any &any);
+
+//! Return underlying boost::any
+boost::any pmt_any_ref(pmt_t obj);
+
+//! Store \p any in \p obj
+void pmt_any_set(pmt_t obj, const boost::any &any);
+
+
+/*
+ * ------------------------------------------------------------------------
  *                       General functions
  * ------------------------------------------------------------------------
  */

Modified: gnuradio/branches/features/inband-usb/pmt/src/lib/pmt_int.h
===================================================================
--- gnuradio/branches/features/inband-usb/pmt/src/lib/pmt_int.h 2007-04-21 
22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/pmt/src/lib/pmt_int.h 2007-04-22 
00:51:18 UTC (rev 5067)
@@ -49,6 +49,7 @@
   virtual bool is_pair()    const { return false; }
   virtual bool is_vector()  const { return false; }
   virtual bool is_dict()    const { return false; }
+  virtual bool is_any()     const { return false; }
 
   virtual bool is_uniform_vector() const { return false; }
   virtual bool is_u8vector()  const { return false; }
@@ -195,6 +196,20 @@
   pmt_t values() const;
 };
 
+class pmt_any : public pmt_base
+{
+  boost::any   d_any;
+
+public:
+  pmt_any(const boost::any &any);
+  //~pmt_any();
+
+  bool is_any() const { return true; }
+  const boost::any &ref() const { return d_any; }
+  void  set(const boost::any &any) { d_any = any; }
+};
+
+
 class pmt_uniform_vector : public pmt_base
 {
 public:

Modified: gnuradio/branches/features/inband-usb/pmt/src/lib/qa_pmt_prims.cc
===================================================================
--- gnuradio/branches/features/inband-usb/pmt/src/lib/qa_pmt_prims.cc   
2007-04-21 22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/pmt/src/lib/qa_pmt_prims.cc   
2007-04-22 00:51:18 UTC (rev 5067)
@@ -295,7 +295,58 @@
   CPPUNIT_ASSERT_EQUAL(std::string("k0"), pmt_write_string(k0));
 }
 
+// ------------------------------------------------------------------------
+
+// class foo is used in test_any below.
+// It can't be declared in the scope of test_any because of template
+// namespace problems.
+
+class foo {
+public:
+  double       d_double;
+  int          d_int;
+  foo(double d=0, int i=0) : d_double(d), d_int(i) {}
+};
+
+bool operator==(const foo &a, const foo &b)
+{
+  return a.d_double == b.d_double && a.d_int == b.d_int;
+}
+
+std::ostream& operator<<(std::ostream &os, const foo obj)
+{
+  os << "<foo: " << obj.d_double << ", " << obj.d_int << ">";
+  return os;
+}
+
 void
+qa_pmt_prims::test_any()
+{
+  boost::any a0;
+  boost::any a1;
+  boost::any a2;
+
+  a0 = std::string("Hello!");
+  a1 = 42;
+  a2 = foo(3.250, 21);
+
+  pmt_t p0 = pmt_make_any(a0);
+  pmt_t p1 = pmt_make_any(a1);
+  pmt_t p2 = pmt_make_any(a2);
+
+  CPPUNIT_ASSERT_EQUAL(std::string("Hello!"),
+                      boost::any_cast<std::string>(pmt_any_ref(p0)));
+
+  CPPUNIT_ASSERT_EQUAL(42,
+                      boost::any_cast<int>(pmt_any_ref(p1)));
+
+  CPPUNIT_ASSERT_EQUAL(foo(3.250, 21),
+                      boost::any_cast<foo>(pmt_any_ref(p2)));
+}
+
+// ------------------------------------------------------------------------
+
+void
 qa_pmt_prims::test_serialize()
 {
   std::stringbuf sb;           // fake channel

Modified: gnuradio/branches/features/inband-usb/pmt/src/lib/qa_pmt_prims.h
===================================================================
--- gnuradio/branches/features/inband-usb/pmt/src/lib/qa_pmt_prims.h    
2007-04-21 22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/pmt/src/lib/qa_pmt_prims.h    
2007-04-22 00:51:18 UTC (rev 5067)
@@ -38,6 +38,7 @@
   CPPUNIT_TEST(test_equivalence);
   CPPUNIT_TEST(test_misc);
   CPPUNIT_TEST(test_dict);
+  CPPUNIT_TEST(test_any);
   CPPUNIT_TEST(test_io);
   CPPUNIT_TEST(test_serialize);
   CPPUNIT_TEST_SUITE_END();
@@ -53,6 +54,7 @@
   void test_equivalence();
   void test_misc();
   void test_dict();
+  void test_any();
   void test_io();
   void test_serialize();
 };

Modified: 
gnuradio/branches/features/inband-usb/pmt/src/scheme/gnuradio/Makefile.am
===================================================================
--- gnuradio/branches/features/inband-usb/pmt/src/scheme/gnuradio/Makefile.am   
2007-04-21 22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/pmt/src/scheme/gnuradio/Makefile.am   
2007-04-22 00:51:18 UTC (rev 5067)
@@ -21,7 +21,9 @@
 #pkgdatadir = $(datadir)/gnuradio
 
 EXTRA_DIST =                           \
-       gen-serial-tags.scm             
+       gen-serial-tags.scm             \
+       pmt-serial-tags.scm             \
+       pmt-serialize.scm               
 
 
 # really scheme source files

Modified: gnuradio/branches/features/inband-usb/usrp/host/lib/inband/Makefile.am
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/Makefile.am      
2007-04-21 22:33:03 UTC (rev 5066)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/Makefile.am      
2007-04-22 00:51:18 UTC (rev 5067)
@@ -24,8 +24,11 @@
        $(DEFINES) $(OMNITHREAD_INCLUDES) $(PMT_INCLUDES) $(MBLOCK_INCLUDES) \
        $(USRP_INCLUDES) $(BOOST_CFLAGS)
 
-EXTRA_DIST =                           
 
+EXTRA_DIST =                           \
+       usrp_server.mbh
+
+
 noinst_LTLIBRARIES = libinband.la
 
 
@@ -47,6 +50,10 @@
 include_HEADERS =                      \
        usrp_server.h                   
 
+noinst_HEADERS =                       \
+       usrp_inband_usb_packet.h        
+
+
 MOSTLYCLEANFILES = \
        $(BUILT_SOURCES) *~ *.pyc
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]