Howdy -

Attached is a candidate patch to update RandomSource include all of the nice bells and whistles that InfiniteSource already has (e.g. LIMITs, a settable ACTIVE parameter, etc). I did this by changing RandomSource to inherit from InfiniteSource, overriding the parts that need to be different. I tried to keep things as consistent as possible between the two elements since they are nearly identical in intended functionality with the exception of how packets are created.

- Ian
--- click-HEAD/elements/standard/randomsource.cc	2010-03-03 13:59:44.496620000 -0500
+++ click-1.7.0rc1/elements/standard/randomsource.cc	2010-03-20 11:25:12.911875000 -0400
@@ -20,12 +20,12 @@
 #include "randomsource.hh"
 #include <click/confparse.hh>
 #include <click/error.hh>
-#include <click/standard/scheduleinfo.hh>
+#include <click/router.hh>
 #include <click/glue.hh>
+#include <click/straccum.hh>
 CLICK_DECLS
 
 RandomSource::RandomSource()
-  : _task(this)
 {
 }
 
@@ -33,63 +33,118 @@
 {
 }
 
+void *
+RandomSource::cast(const char *n)
+{
+  if (strcmp(n, "RandomSource") == 0)
+    return (RandomSource *)this;
+  else if (strcmp(n, Notifier::EMPTY_NOTIFIER) == 0)
+    return static_cast<Notifier *>(this);
+  else
+    return 0;
+}
+
 int
 RandomSource::configure(Vector<String> &conf, ErrorHandler *errh)
 {
-  int length;
+  ActiveNotifier::initialize(Notifier::EMPTY_NOTIFIER, router());
+  int limit = -1;
+  int burstsize = 1;
+  int datasize = -1;
+  bool active = true, stop = false;
 
   if (cp_va_kparse(conf, this, errh,
-		   "LENGTH", cpkP+cpkM, cpInteger, &length,
+		   "LENGTH", cpkP+cpkM, cpInteger, &datasize,
+		   "LIMIT", cpkP, cpInteger, &limit,
+		   "BURST", cpkP, cpInteger, &burstsize,
+		   "ACTIVE", cpkP, cpBool, &active,
+		   "STOP", 0, cpBool, &stop,
 		   cpEnd) < 0)
     return -1;
-  if(length < 0 || length >= 64*1024)
-    return errh->error("bad length %d", length);
-  _length = length;
+  if(datasize < 0 || datasize >= 64*1024)
+    return errh->error("bad length %d", datasize);
+  if (burstsize < 1)
+    return errh->error("burst size must be >= 1");
+
+  _datasize = datasize;
+  _limit = limit;
+  _burstsize = burstsize;
+  _count = 0;
+  _active = active;
+  _stop = stop;
+  
   return 0;
 }
 
-int
-RandomSource::initialize(ErrorHandler *errh)
+bool
+RandomSource::run_task(Task *)
 {
-    if (output_is_push(0))
-	ScheduleInfo::initialize_task(this, &_task, errh);
-    return 0;
+    if (!_active || !_nonfull_signal)
+	return false;
+    int n = _burstsize;
+    if (_limit >= 0 && _count + n >= _limit)
+	n = (_count > _limit ? 0 : _limit - _count);
+    for (int i = 0; i < n; i++) {
+	Packet *p = make_packet();
+	output(0).push(p);
+    }
+    _count += n;
+    if (n > 0)
+	_task.fast_reschedule();
+    else if (_stop && _limit >= 0 && _count >= _limit)
+	router()->please_stop_driver();
+    return n > 0;
+}
+
+Packet *
+RandomSource::pull(int)
+{
+    if (!_active) {
+    done:
+	if (Notifier::active())
+	    sleep();
+	return 0;
+    }
+    if (_limit >= 0 && _count >= _limit) {
+	if (_stop)
+	    router()->please_stop_driver();
+	goto done;
+    }
+    _count++;
+    Packet *p = make_packet();
+    return p;
 }
 
 Packet *
 RandomSource::make_packet()
 {
-    WritablePacket *p = Packet::make(36, (const unsigned char*)0, _length, 0);
+    WritablePacket *p = Packet::make(36, (const unsigned char*)0, _datasize, 0);
 
     int i;
     char *d = (char *) p->data();
-    for (i = 0; i < _length; i += sizeof(int))
+    for (i = 0; i < _datasize; i += sizeof(int))
 	*(int*)(d + i) = click_random();
-    for( ; i < _length; i++)
+    for( ; i < _datasize; i++)
 	*(d + i) = click_random();
 
-    p->timestamp_anno().assign_now();
+    p->timestamp_anno().set_now();
     return p;
 }
 
-bool
-RandomSource::run_task(Task *)
-{
-  Packet *p = make_packet();
-  output(0).push(p);
-  _task.fast_reschedule();
-  return true;
-}
-
-Packet *
-RandomSource::pull(int)
-{
-  return make_packet();
-}
-
 void
 RandomSource::add_handlers()
 {
+  add_data_handlers("limit", Handler::OP_READ | Handler::CALM, &_limit);
+  add_write_handler("limit", change_param, (void *)1);
+  add_data_handlers("burst", Handler::OP_READ | Handler::CALM, &_burstsize);
+  add_write_handler("burst", change_param, (void *)2);
+  add_data_handlers("active", Handler::OP_READ | Handler::CHECKBOX, &_active);
+  add_write_handler("active", change_param, (void *)3);
+  add_data_handlers("count", Handler::OP_READ, &_count);
+  add_write_handler("reset", change_param, (void *)5, Handler::BUTTON);
+  add_data_handlers("length", Handler::OP_READ | Handler::CALM, &_datasize);
+  add_write_handler("length", change_param, (void *)6);
+
   if (output_is_push(0))
     add_task_handlers(&_task);
 }
--- click-HEAD/elements/standard/randomsource.hh	2010-03-03 13:59:44.499622000 -0500
+++ click-1.7.0rc1/elements/standard/randomsource.hh	2010-03-20 11:30:07.443357000 -0400
@@ -1,44 +1,96 @@
 #ifndef CLICK_RANDOMSOURCE_HH
 #define CLICK_RANDOMSOURCE_HH
-#include <click/element.hh>
-#include <click/task.hh>
+#include "infinitesource.hh"
 CLICK_DECLS
 
 /*
  * =c
- * RandomSource(LENGTH)
+ * RandomSource(LENGTH [, LIMIT, BURST, ACTIVE, I<KEYWORDS>])
  * =s basicsources
  * generates random packets whenever scheduled
  * =d
  *
  * Creates packets, of the indicated length, filled with random bytes.
- * Packets' timestamp annotations are set to the current time.
- *
- * =a InfiniteSource
- */
+ * Packets' timestamp annotations are set to the current time. Pushes BURST such
+ * packets out its single output every time it is scheduled (which will be
+ * often). Stops sending after LIMIT packets are generated; but if LIMIT is
+ * negative, sends packets forever. Will send packets only if ACTIVE is
+ * true. (ACTIVE is true by default.) Default LIMIT is -1 (send packets
+ * forever). Default BURST is 1.
+
+Keyword arguments are:
+
+=over 8
+
+=item LENGTH
+
+Integer. The outgoing packet will have this length.
+
+=item LIMIT
+
+Integer. Same as the LIMIT argument.
+
+=item BURST
+
+Integer. Same as the BURST argument.
+
+=item ACTIVE
+
+Boolean. Same as the ACTIVE argument.
+
+=item STOP
+
+Boolean. If true, then stop the driver once LIMIT packets are sent. Default is
+false.
+
+=e
+
+  RandomSource(64) -> Queue -> ...
 
-class RandomSource : public Element { public:
+=n
+
+Useful for profiling and experiments.  Packets' timestamp annotations are set
+to the current time.
+
+RandomSource listens for downstream full notification.
+
+=h count read-only
+Returns the total number of packets that have been generated.
+=h reset write-only
+Resets the number of generated packets to 0. The RandomSource will then
+generate another LIMIT packets (if it is active).
+=h length read/write
+Returns or sets the LENGTH parameter.
+=h limit read/write
+Returns or sets the LIMIT parameter.
+=h burst read/write
+Returns or sets the BURST parameter.
+=h active read/write
+Makes the element active or inactive.
+
+=a
+
+InfiniteSource */
+
+class RandomSource : public InfiniteSource { public:
 
   RandomSource();
   ~RandomSource();
 
   const char *class_name() const		{ return "RandomSource"; }
+  void *cast(const char *);
   const char *port_count() const		{ return PORTS_0_1; }
   const char *processing() const		{ return AGNOSTIC; }
-  int configure(Vector<String> &, ErrorHandler *);
-  int initialize(ErrorHandler *);
   void add_handlers();
 
-  Packet *pull(int);
+  int configure(Vector<String> &, ErrorHandler *);
+  bool can_live_reconfigure() const		{ return true; }
+
   bool run_task(Task *);
+  Packet *pull(int);
 
  protected:
-
-  int _length;
-  Task _task;
-
   Packet *make_packet();
-
 };
 
 CLICK_ENDDECLS
_______________________________________________
click mailing list
[email protected]
https://amsterdam.lcs.mit.edu/mailman/listinfo/click

Reply via email to