base: Remove unused files
[gem5.git] / src / base / random.cc
index ceab337d9cd0b396282099c3181d490286fba4b2..cffeddec95927d049d1f19a83b88ae813b21edaa 100644 (file)
  *          Ali Saidi
  */
 
-#if defined(__sun)
-#include <ieeefp.h>
-#endif
-#ifdef __SUNPRO_CC
-#include <stdlib.h>
-#include <math.h>
-#endif
-
-#include <cstdlib>
-#include <cmath>
-
+#include <limits>
+#include "base/fenv.hh"
+#include "base/intmath.hh"
+#include "base/misc.hh"
 #include "base/random.hh"
+#include "sim/serialize.hh"
 
 using namespace std;
 
-uint32_t
-getInt32()
+Random::Random()
+{
+    // default random seed taken from original source
+    init(5489);
+}
+
+Random::Random(uint32_t s)
 {
-    return mrand48() & 0xffffffff;
+    init(s);
 }
 
-double
-getDouble()
+Random::Random(uint32_t init_key[], int key_length)
 {
-    return drand48();
+    init(init_key, key_length);
 }
 
-double
-m5round(double r)
+Random::~Random()
 {
-#if defined(__sun)
-    double val;
-    fp_rnd oldrnd = fpsetround(FP_RN);
-    val = rint(r);
-    fpsetround(oldrnd);
-    return val;
-#else
-    return round(r);
-#endif
 }
 
-int64_t
-getUniform(int64_t min, int64_t max)
+// To preserve the uniform random distribution between min and max,
+// and allow all numbers to be represented, we generate a uniform
+// random number to the nearest power of two greater than max.  If
+// this number doesn't fall between 0 and max, we try again.  Anything
+// else would skew the distribution.
+uint32_t
+Random::genrand(uint32_t max)
 {
-    double r;
-    r = drand48() * (max-min) + min;
+    if (max == 0)
+        return 0;
+    if (max == std::numeric_limits<uint32_t>::max())
+        return genrand();
+
+    int log = ceilLog2(max + 1);
+    int shift = (sizeof(uint32_t) * 8 - log);
+    uint32_t random;
 
-    return (int64_t)m5round(r);
+    do {
+        random = genrand() >> shift;
+    } while (random > max);
+
+    return random;
 }
 
 uint64_t
-getUniformPos(uint64_t min, uint64_t max)
+Random::genrand(uint64_t max)
+{
+    if (max == 0)
+        return 0;
+    if (max == std::numeric_limits<uint64_t>::max())
+        return genrand();
+
+    int log = ceilLog2(max + 1);
+    int shift = (sizeof(uint64_t) * 8 - log);
+    uint64_t random;
+
+    do {
+        random = (uint64_t)genrand() << 32 | (uint64_t)genrand();
+        random = random >> shift;
+    } while (random > max);
+
+    return random;
+}
+
+void
+Random::serialize(const string &base, ostream &os)
 {
-    double r;
-    r = drand48() * (max-min) + min;
+    int length = N;
+    paramOut(os, base + ".mti", mti);
+    paramOut(os, base + ".length", length);
+    arrayParamOut(os, base + ".data", mt, length);
+}
+
+void
+Random::unserialize(const string &base, Checkpoint *cp, const string &section)
+{
+    int length;
 
-    return (uint64_t)m5round(r);
+    paramIn(cp, section, base + ".mti", mti);
+    paramIn(cp, section, base + ".length", length);
+    if (length != N)
+        panic("cant unserialize random number data. length != %d\n", length);
+
+    arrayParamIn(cp, section, base + ".data", mt, length);
 }
+
+Random random_mt;