diff options
-rw-r--r-- | base/random.cc | 27 | ||||
-rw-r--r-- | base/random.hh | 26 | ||||
-rw-r--r-- | dev/etherlink.cc | 20 | ||||
-rw-r--r-- | dev/etherlink.hh | 5 |
4 files changed, 65 insertions, 13 deletions
diff --git a/base/random.cc b/base/random.cc index a6d9da6c1..babe93db5 100644 --- a/base/random.cc +++ b/base/random.cc @@ -31,6 +31,7 @@ #include "sim/param.hh" #include "base/random.hh" +#include "base/trace.hh" using namespace std; @@ -52,15 +53,33 @@ seed(¶mContext, "seed", "seed to random number generator", 1); void RandomContext::checkParams() { - ::srandom(seed); + ::srand48(seed); } long getLong() { - return random(); + return mrand48(); } +int64_t +getUniform(int64_t maxmin) +{ + double r; + r = (drand48() - 0.500) * 2 * maxmin; + DPRINTFN("getUniform %f\n", r); + return (int64_t)round(r); +} + +uint64_t +getUniformPos(uint64_t max) +{ + double r; + r = drand48() * 2 * max; + return (uint64_t)round(r); +} + + // idea for generating a double from erand48 double getDouble() @@ -70,8 +89,8 @@ getDouble() uint16_t _short[4]; }; - _long[0] = random(); - _long[1] = random(); + _long[0] = mrand48(); + _long[1] = mrand48(); return ldexp((double) _short[0], -48) + ldexp((double) _short[1], -32) + diff --git a/base/random.hh b/base/random.hh index b4d20a274..eac91a53c 100644 --- a/base/random.hh +++ b/base/random.hh @@ -33,6 +33,8 @@ long getLong(); double getDouble(); +uint64_t getUniformPos(uint64_t max); +int64_t getUniform(int64_t max); template <typename T> struct Random; @@ -41,48 +43,72 @@ template<> struct Random<int8_t> { static int8_t get() { return getLong() & (int8_t)-1; } + + static int8_t uniform(int8_t maxmin) + { return getUniform(maxmin); } }; template<> struct Random<uint8_t> { static uint8_t get() { return getLong() & (uint8_t)-1; } + + static uint8_t uniform(uint8_t max) + { return getUniformPos(max); } }; template<> struct Random<int16_t> { static int16_t get() { return getLong() & (int16_t)-1; } + + static int16_t uniform(int16_t maxmin) + { return getUniform(maxmin); } }; template<> struct Random<uint16_t> { static uint16_t get() { return getLong() & (uint16_t)-1; } + + static uint16_t uniform(uint16_t max) + { return getUniformPos(max); } }; template<> struct Random<int32_t> { static int32_t get() { return (int32_t)getLong(); } + + static int32_t uniform(int32_t maxmin) + { return getUniform(maxmin); } }; template<> struct Random<uint32_t> { static uint32_t get() { return (uint32_t)getLong(); } + + static uint32_t uniform(uint32_t max) + { return getUniformPos(max); } }; template<> struct Random<int64_t> { static int64_t get() { return (int64_t)getLong() << 32 || (uint64_t)getLong(); } + + static int64_t uniform(int64_t maxmin) + { return getUniform(maxmin); } }; template<> struct Random<uint64_t> { static uint64_t get() { return (uint64_t)getLong() << 32 || (uint64_t)getLong(); } + + static uint64_t uniform(uint64_t max) + { return getUniformPos(max); } }; template<> struct Random<float> diff --git a/dev/etherlink.cc b/dev/etherlink.cc index 75360f368..f5c47bd22 100644 --- a/dev/etherlink.cc +++ b/dev/etherlink.cc @@ -35,6 +35,7 @@ #include <string> #include <vector> +#include "base/random.hh" #include "base/trace.hh" #include "dev/etherdump.hh" #include "dev/etherint.hh" @@ -48,11 +49,11 @@ using namespace std; EtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1, - double rate, Tick delay, EtherDump *dump) + double rate, Tick delay, Tick delayVar, EtherDump *dump) : SimObject(name) { - link[0] = new Link(name + ".link0", this, 0, rate, delay, dump); - link[1] = new Link(name + ".link1", this, 1, rate, delay, dump); + link[0] = new Link(name + ".link0", this, 0, rate, delay, delayVar, dump); + link[1] = new Link(name + ".link1", this, 1, rate, delay, delayVar, dump); interface[0] = new Interface(name + ".int0", link[0], link[1]); interface[1] = new Interface(name + ".int1", link[1], link[0]); @@ -80,9 +81,9 @@ EtherLink::Interface::Interface(const string &name, Link *tx, Link *rx) } EtherLink::Link::Link(const string &name, EtherLink *p, int num, - double rate, Tick delay, EtherDump *d) + double rate, Tick delay, Tick delay_var, EtherDump *d) : objName(name), parent(p), number(num), txint(NULL), rxint(NULL), - ticksPerByte(rate), linkDelay(delay), dump(d), + ticksPerByte(rate), linkDelay(delay), delayVar(delay_var), dump(d), doneEvent(this) { } @@ -158,7 +159,9 @@ EtherLink::Link::transmit(PacketPtr pkt) DDUMP(EthernetData, pkt->data, pkt->length); packet = pkt; - Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0); + Random<Tick> var; + Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0 + + var.uniform(delayVar)); DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n", delay, ticksPerByte); doneEvent.schedule(curTick + delay); @@ -270,6 +273,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink) SimObjectParam<EtherInt *> int2; Param<double> speed; Param<Tick> delay; + Param<Tick> delay_var; SimObjectParam<EtherDump *> dump; END_DECLARE_SIM_OBJECT_PARAMS(EtherLink) @@ -280,13 +284,15 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink) INIT_PARAM(int2, "interface 2"), INIT_PARAM(speed, "link speed in bits per second"), INIT_PARAM(delay, "transmit delay of packets in us"), + INIT_PARAM(delay_var, "Difference in amount of time to traverse wire"), INIT_PARAM(dump, "object to dump network packets to") END_INIT_SIM_OBJECT_PARAMS(EtherLink) CREATE_SIM_OBJECT(EtherLink) { - return new EtherLink(getInstanceName(), int1, int2, speed, delay, dump); + return new EtherLink(getInstanceName(), int1, int2, speed, delay, delay_var, + dump); } REGISTER_SIM_OBJECT("EtherLink", EtherLink) diff --git a/dev/etherlink.hh b/dev/etherlink.hh index b9e6047fc..305007d9e 100644 --- a/dev/etherlink.hh +++ b/dev/etherlink.hh @@ -66,6 +66,7 @@ class EtherLink : public SimObject double ticksPerByte; Tick linkDelay; + Tick delayVar; EtherDump *dump; protected: @@ -83,7 +84,7 @@ class EtherLink : public SimObject public: Link(const std::string &name, EtherLink *p, int num, - double rate, Tick delay, EtherDump *dump); + double rate, Tick delay, Tick delay_var, EtherDump *dump); ~Link() {} const std::string name() const { return objName; } @@ -118,7 +119,7 @@ class EtherLink : public SimObject public: EtherLink(const std::string &name, EtherInt *peer0, EtherInt *peer1, - double rate, Tick delay, EtherDump *dump); + double rate, Tick delay, Tick delayVar, EtherDump *dump); virtual ~EtherLink(); virtual void serialize(std::ostream &os); |