commit-gnuradio
[Top][All Lists]
Advanced

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

[Commit-gnuradio] r5066 - gnuradio/branches/developers/eb/ibu/mblock/src


From: eb
Subject: [Commit-gnuradio] r5066 - gnuradio/branches/developers/eb/ibu/mblock/src/lib
Date: Sat, 21 Apr 2007 16:33:03 -0600 (MDT)

Author: eb
Date: 2007-04-21 16:33:03 -0600 (Sat, 21 Apr 2007)
New Revision: 5066

Added:
   gnuradio/branches/developers/eb/ibu/mblock/src/lib/getres.cc
Modified:
   gnuradio/branches/developers/eb/ibu/mblock/src/lib/
   gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_mblock.cc
   gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_mblock.h
   gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_msg_queue.cc
   gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_msg_queue.h
   gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_runtime_base.cc
   gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_runtime_base.h
   
gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_runtime_thread_per_block.cc
   
gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_runtime_thread_per_block.h
   gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_time.cc
   gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_time.h
   gnuradio/branches/developers/eb/ibu/mblock/src/lib/qa_timeouts.cc
   gnuradio/branches/developers/eb/ibu/mblock/src/lib/qa_timeouts.h
Log:
mblock timeouts are complete.



Property changes on: gnuradio/branches/developers/eb/ibu/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


Added: gnuradio/branches/developers/eb/ibu/mblock/src/lib/getres.cc
===================================================================
--- gnuradio/branches/developers/eb/ibu/mblock/src/lib/getres.cc                
                (rev 0)
+++ gnuradio/branches/developers/eb/ibu/mblock/src/lib/getres.cc        
2007-04-21 22:33:03 UTC (rev 5066)
@@ -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/developers/eb/ibu/mblock/src/lib/mb_mblock.cc
===================================================================
--- gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_mblock.cc     
2007-04-21 21:40:12 UTC (rev 5065)
+++ gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_mblock.cc     
2007-04-21 22:33:03 UTC (rev 5066)
@@ -201,12 +201,6 @@
   d_impl->runtime()->request_shutdown(result);
 }
 
-mb_time
-mb_mblock::time(const mb_time &relative_offset) const
-{
-  return d_impl->runtime()->time(relative_offset);
-}
-
 pmt_t
 mb_mblock::schedule_one_shot_timeout(const mb_time &abs_time, pmt_t user_data)
 {

Modified: gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_mblock.h
===================================================================
--- gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_mblock.h      
2007-04-21 21:40:12 UTC (rev 5065)
+++ gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_mblock.h      
2007-04-21 22:33:03 UTC (rev 5066)
@@ -243,14 +243,6 @@
   mb_mblock *parent() const;
 
   /*!
-   * \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.
-   */
-  mb_time time(const mb_time &relative_offset = mb_time()) const;
-
-  /*!
    * \brief Schedule a "one shot" timeout.
    *
    * \param abs_time the absolute time at which the timeout should fire

Modified: gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_msg_queue.cc
===================================================================
--- gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_msg_queue.cc  
2007-04-21 21:40:12 UTC (rev 5065)
+++ gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_msg_queue.cc  
2007-04-21 22:33:03 UTC (rev 5066)
@@ -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/developers/eb/ibu/mblock/src/lib/mb_msg_queue.h
===================================================================
--- gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_msg_queue.h   
2007-04-21 21:40:12 UTC (rev 5065)
+++ gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_msg_queue.h   
2007-04-21 22:33:03 UTC (rev 5066)
@@ -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/developers/eb/ibu/mblock/src/lib/mb_runtime_base.cc
===================================================================
--- gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_runtime_base.cc       
2007-04-21 21:40:12 UTC (rev 5065)
+++ gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_runtime_base.cc       
2007-04-21 22:33:03 UTC (rev 5066)
@@ -33,13 +33,6 @@
 {
 }
 
-
-mb_time
-mb_runtime_base::time(const mb_time &relative_offset)
-{
-  return mb_time();
-}
-
 pmt_t
 mb_runtime_base::schedule_one_shot_timeout(const mb_time &abs_time,
                                           pmt_t user_data,

Modified: gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_runtime_base.h
===================================================================
--- gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_runtime_base.h        
2007-04-21 21:40:12 UTC (rev 5065)
+++ gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_runtime_base.h        
2007-04-21 22:33:03 UTC (rev 5066)
@@ -57,9 +57,6 @@
                   const std::string &class_name,
                   pmt_t user_arg) = 0;
 
-  virtual mb_time
-  time(const mb_time &relative_offset);
-
   virtual pmt_t
   schedule_one_shot_timeout(const mb_time &abs_time, pmt_t user_data,
                            mb_msg_accepter_sptr accepter);

Modified: 
gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_runtime_thread_per_block.cc
===================================================================
--- 
gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_runtime_thread_per_block.cc
   2007-04-21 21:40:12 UTC (rev 5065)
+++ 
gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_runtime_thread_per_block.cc
   2007-04-21 22:33:03 UTC (rev 5066)
@@ -41,6 +41,8 @@
 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,
@@ -89,6 +91,9 @@
 
   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,13 +119,29 @@
 mb_runtime_thread_per_block::run_loop()
 {
   while (1){
+    mb_message_sptr msg;
 
-    // FIXME change this to a timed wait
-    mb_message_sptr msg = d_msgq.get_highest_pri_msg();
+    if (d_timer_queue.empty())                   // Any timeouts pending?
+      msg = d_msgq.get_highest_pri_msg();        // Nope.  Block forever.
 
-    if (!msg){
-      // FIXME we timed out, must be time to send somebody a %timeout
-      continue;
+    else {
+      mb_timeout_sptr to = d_timer_queue.top();          // Yep.  Get earliest 
timeout.
+
+      // wait for a msg or the timeout...
+      msg = d_msgq.get_highest_pri_msg_timedwait(to->d_when);
+
+      if (!msg){               // We timed out.
+       d_timer_queue.pop();    // Remove timeout from timer queue.
+
+       // send the %timeout msg
+       (*to->d_accepter)(s_timeout, to->d_user_data, to->handle(), 
MB_PRI_BEST);
+
+       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();
@@ -136,10 +157,9 @@
        d_shutdown_in_progress = true;
        d_shutdown_result = msg->data();
 
-       // FIXME state machine, delay before sending %halt
+       // 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);
-       send_all_sys_msg(s_halt);
-
       }
     }
     else if (pmt_eq(signal, s_request_timeout)){       // %request-timeout
@@ -150,6 +170,22 @@
     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
+
+      // 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;
+    }
     else {
       std::cerr << "mb_runtime_thread_per_block: unhandled msg: " << msg << 
std::endl;
     }
@@ -272,20 +308,6 @@
 
 //
 // Can be invoked from any thread.
-//
-mb_time
-mb_runtime_thread_per_block::time(const mb_time &delta_t)
-{
-  unsigned long        abs_sec, abs_nsec;
-  unsigned long rel_sec  = delta_t.d_sec;
-  unsigned long rel_nsec = delta_t.d_nsec;
-  
-  omni_thread::get_time(&abs_sec, &abs_nsec, rel_sec, rel_nsec);
-  return mb_time(abs_sec, abs_nsec);
-}
-
-//
-// Can be invoked from any thread.
 // Sends a message to the runtime.
 //
 pmt_t
@@ -325,4 +347,3 @@
 {
   (*d_accepter)(s_cancel_timeout, handle, PMT_F, MB_PRI_BEST);
 }
-

Modified: 
gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_runtime_thread_per_block.h
===================================================================
--- 
gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_runtime_thread_per_block.h
    2007-04-21 21:40:12 UTC (rev 5065)
+++ 
gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_runtime_thread_per_block.h
    2007-04-21 22:33:03 UTC (rev 5066)
@@ -60,9 +60,6 @@
                   const std::string &class_name,
                   pmt_t user_arg);
 
-  mb_time
-  time(const mb_time &relative_offset);
-
   pmt_t
   schedule_one_shot_timeout(const mb_time &abs_time, pmt_t user_data,
                            mb_msg_accepter_sptr accepter);

Modified: gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_time.cc
===================================================================
--- gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_time.cc       
2007-04-21 21:40:12 UTC (rev 5065)
+++ gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_time.cc       
2007-04-21 22:33:03 UTC (rev 5066)
@@ -23,15 +23,37 @@
 #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_sec + y.d_sec, x.d_nsec + y.d_nsec);
-  while (r.d_nsec >= 1000000000){
-    r.d_nsec -= 1000000000;
-    r.d_sec++;
+  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;
 }
@@ -41,11 +63,22 @@
 {
   // assert(!(x < y));
 
-  mb_time r(x.d_sec - y.d_sec, x.d_nsec - y.d_nsec);
-  while (r.d_nsec < 0){
-    r.d_nsec += 1000000000;
-    r.d_sec--;
+  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);
+}

Modified: gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_time.h
===================================================================
--- gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_time.h        
2007-04-21 21:40:12 UTC (rev 5065)
+++ gnuradio/branches/developers/eb/ibu/mblock/src/lib/mb_time.h        
2007-04-21 22:33:03 UTC (rev 5066)
@@ -22,50 +22,68 @@
 #define INCLUDED_MB_TIME_H
 
 struct mb_time {
-  long int d_sec;      // seconds 
-  long int d_nsec;     // nanosecs
+  long int d_secs;     // seconds.
+  long int d_nsecs;    // nanoseconds.  Always in [0, 1e9-1]
 
-  mb_time() : d_sec(0), d_nsec(0) {}
-  mb_time(long secs, long nanosecs=0) : d_sec(secs), d_nsec(nanosecs) {}
+  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_sec < y.d_sec)
-         || (x.d_sec == y.d_sec && x.d_nsec < y.d_nsec));
+  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_sec > y.d_sec)
-         || (x.d_sec == y.d_sec && x.d_nsec > y.d_nsec));
+  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_sec > y.d_sec)
-         || (x.d_sec == y.d_sec && x.d_nsec >= y.d_nsec));
+  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_sec < y.d_sec)
-         || (x.d_sec == y.d_sec && x.d_nsec <= y.d_nsec));
+  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_sec == y.d_sec && x.d_nsec == y.d_nsec);
+  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 */

Modified: gnuradio/branches/developers/eb/ibu/mblock/src/lib/qa_timeouts.cc
===================================================================
--- gnuradio/branches/developers/eb/ibu/mblock/src/lib/qa_timeouts.cc   
2007-04-21 21:40:12 UTC (rev 5065)
+++ gnuradio/branches/developers/eb/ibu/mblock/src/lib/qa_timeouts.cc   
2007-04-21 22:33:03 UTC (rev 5066)
@@ -38,6 +38,14 @@
 #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()
 {
@@ -118,3 +126,167 @@
   
   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));
+}

Modified: gnuradio/branches/developers/eb/ibu/mblock/src/lib/qa_timeouts.h
===================================================================
--- gnuradio/branches/developers/eb/ibu/mblock/src/lib/qa_timeouts.h    
2007-04-21 21:40:12 UTC (rev 5065)
+++ gnuradio/branches/developers/eb/ibu/mblock/src/lib/qa_timeouts.h    
2007-04-21 22:33:03 UTC (rev 5066)
@@ -29,10 +29,14 @@
 
   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 */





reply via email to

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