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