sim: Ensure GDB interrupts the simulation at an instruction boundary.
[gem5.git] / src / base / random.hh
index 40d62da7f4d83a39eeb75b2bbf73f913e151741f..cedbd6bd44bcd8d581e78243020c28d6bdb162f1 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2003-2005 The Regents of The University of Michigan
  * All rights reserved.
  *
  *
  * Authors: Nathan Binkert
  *          Ali Saidi
+ *          Andreas Hansson
+ */
+
+/*
+ * Mersenne twister random number generator.
  */
 
 #ifndef __BASE_RANDOM_HH__
 #define __BASE_RANDOM_HH__
 
-#include "sim/host.hh"
-
-long getLong();
-double getDouble();
-double m5random(double r);
-uint64_t getUniformPos(uint64_t min, uint64_t max);
-int64_t getUniform(int64_t min, int64_t max);
-
-template <typename T>
-struct Random;
-
-template<> struct Random<int8_t>
-{
-    static int8_t get()
-    { return getLong() & (int8_t)-1; }
-
-    static int8_t uniform(int8_t min, int8_t max)
-    { return getUniform(min, max); }
-};
-
-template<> struct Random<uint8_t>
-{
-    static uint8_t get()
-    { return getLong() & (uint8_t)-1; }
-
-    static uint8_t uniform(uint8_t min, uint8_t max)
-    { return getUniformPos(min, max); }
-};
-
-template<> struct Random<int16_t>
-{
-    static int16_t get()
-    { return getLong() & (int16_t)-1; }
-
-    static int16_t uniform(int16_t min, int16_t max)
-    { return getUniform(min, max); }
-};
-
-template<> struct Random<uint16_t>
-{
-    static uint16_t get()
-    { return getLong() & (uint16_t)-1; }
-
-    static uint16_t uniform(uint16_t min, uint16_t max)
-    { return getUniformPos(min, max); }
-};
-
-template<> struct Random<int32_t>
-{
-    static int32_t get()
-    { return (int32_t)getLong(); }
+#include <random>
+#include <string>
+#include <type_traits>
 
-    static int32_t uniform(int32_t min, int32_t max)
-    { return getUniform(min, max); }
-};
+#include "base/types.hh"
 
-template<> struct Random<uint32_t>
-{
-    static uint32_t get()
-    { return (uint32_t)getLong(); }
-
-    static uint32_t uniform(uint32_t min, uint32_t max)
-    { return getUniformPos(min, max); }
-};
+class Checkpoint;
 
-template<> struct Random<int64_t>
+class Random
 {
-    static int64_t get()
-    { return (int64_t)getLong() << 32 || (uint64_t)getLong(); }
 
-    static int64_t uniform(int64_t min, int64_t max)
-    { return getUniform(min, max); }
+  private:
+
+    std::mt19937_64 gen;
+
+  public:
+
+    Random();
+    Random(uint32_t s);
+    ~Random();
+
+    void init(uint32_t s);
+
+    /**
+     * Use the SFINAE idiom to choose an implementation based on
+     * whether the type is integral or floating point.
+     */
+    template <typename T>
+    typename std::enable_if<std::is_integral<T>::value, T>::type
+    random()
+    {
+        // [0, max_value] for integer types
+        std::uniform_int_distribution<T> dist;
+        return dist(gen);
+    }
+
+    template <typename T>
+    typename std::enable_if<std::is_floating_point<T>::value, T>::type
+    random()
+    {
+        // [0, 1) for real types
+        std::uniform_real_distribution<T> dist;
+        return dist(gen);
+    }
+
+    template <typename T>
+    typename std::enable_if<std::is_integral<T>::value, T>::type
+    random(T min, T max)
+    {
+        std::uniform_int_distribution<T> dist(min, max);
+        return dist(gen);
+    }
+
+    void serialize(std::ostream &os);
+    void unserialize(Checkpoint *cp, const std::string &section);
 };
 
-template<> struct Random<uint64_t>
-{
-    static uint64_t get()
-    { return (uint64_t)getLong() << 32 || (uint64_t)getLong(); }
-
-    static uint64_t uniform(uint64_t min, uint64_t max)
-    { return getUniformPos(min, max); }
-};
-
-template<> struct Random<float>
-{
-    static float get()
-    { return getDouble(); }
-};
-
-template<> struct Random<double>
-{
-    static double get()
-    { return getDouble(); }
-};
+extern Random random_mt;
 
 #endif // __BASE_RANDOM_HH__