]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS-Plus/Source/Reliance-Edge/tests/util/rand.c
Update Reliance Edge fail safe file system to the latest version.
[freertos] / FreeRTOS-Plus / Source / Reliance-Edge / tests / util / rand.c
index 5f05be7625c5b48c791e885b6de48b91b5195444..6dd443023b7a2bd24250c264bfe80bdf15721d63 100644 (file)
-/*             ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
-\r
-                   Copyright (c) 2014-2015 Datalight, Inc.\r
-                       All Rights Reserved Worldwide.\r
-\r
-    This program is free software; you can redistribute it and/or modify\r
-    it under the terms of the GNU General Public License as published by\r
-    the Free Software Foundation; use version 2 of the License.\r
-\r
-    This program is distributed in the hope that it will be useful,\r
-    but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-    GNU General Public License for more details.\r
-\r
-    You should have received a copy of the GNU General Public License along\r
-    with this program; if not, write to the Free Software Foundation, Inc.,\r
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
-*/\r
-/*  Businesses and individuals that for commercial or other reasons cannot\r
-    comply with the terms of the GPLv2 license may obtain a commercial license\r
-    before incorporating Reliance Edge into proprietary software for\r
-    distribution in any form.  Visit http://www.datalight.com/reliance-edge for\r
-    more information.\r
-*/\r
-/** @file\r
-    @brief Implements a random number generator.\r
-*/\r
-#include <redfs.h>\r
-#include <redtestutils.h>\r
-\r
-\r
-/*  This is the global seed used by the random number generator when the caller\r
-    has not provided a seed to either the RedRand32() or RedRand64() functions.\r
-*/\r
-static uint64_t ullGlobalRandomNumberSeed;\r
-\r
-/*  Whether the above seed has been initialized.\r
-*/\r
-static bool fGlobalSeedInited;\r
-\r
-\r
-/** @brief Set the global seed used by the random number generator.\r
-\r
-    The global seed gets used when RedRand64() or RedRand32() are called with\r
-    a NULL seed argument.\r
-\r
-    @param ullSeed  The value to use as the global RNG seed.\r
-*/\r
-void RedRandSeed(\r
-    uint64_t ullSeed)\r
-{\r
-    ullGlobalRandomNumberSeed = ullSeed;\r
-    fGlobalSeedInited = true;\r
-}\r
-\r
-\r
-/** @brief Generate a 64-bit pseudo-random number.\r
-\r
-    The period of this random number generator is 2^64 (1.8 x 1019).  These\r
-    parameters are the same as the default one-stream SPRNG lcg64 generator and\r
-    it satisfies the requirements for a maximal period.\r
-\r
-    The tempering value is used and an AND mask and is specifically selected to\r
-    favor the distribution of lower bits.\r
-\r
-    @param pullSeed A pointer to the seed to use.  Set this value to NULL to\r
-                    use the internal global seed value.\r
-\r
-    @return A pseudo-random number in the range [0, UINT64_MAX].\r
-*/\r
-uint64_t RedRand64(\r
-    uint64_t       *pullSeed)\r
-{\r
-    const uint64_t  ullA = UINT64_SUFFIX(2862933555777941757);\r
-    const uint64_t  ullC = UINT64_SUFFIX(3037000493);\r
-    const uint64_t  ullT = UINT64_SUFFIX(4921441182957829599);\r
-    uint64_t        ullN;\r
-    uint64_t       *pullSeedPtr;\r
-    uint64_t        ullLocalSeed;\r
-\r
-    if(pullSeed != NULL)\r
-    {\r
-        ullLocalSeed = *pullSeed;\r
-        pullSeedPtr = pullSeed;\r
-    }\r
-    else\r
-    {\r
-        if(!fGlobalSeedInited)\r
-        {\r
-            /*  Unfortunately, the Reliance Edge OS services don't give us much\r
-                to work with to initialize the global seed.  There is no entropy\r
-                abstraction, no tick count abstraction, and the timestamp\r
-                abstraction uses an opaque type which is not guaranteed to be an\r
-                integer.  The best we can do is use the RTC.\r
-\r
-                Tests using the RNG should be supplying a seed anyway, for\r
-                reproducibility.\r
-            */\r
-            RedRandSeed((uint64_t)RedOsClockGetTime());\r
-        }\r
-\r
-        ullLocalSeed = ullGlobalRandomNumberSeed;\r
-        pullSeedPtr = &ullGlobalRandomNumberSeed;\r
-    }\r
-\r
-    ullN = (ullLocalSeed * ullA) + ullC;\r
-\r
-    *pullSeedPtr = ullN;\r
-\r
-    /*  The linear congruential generator used above produces good psuedo-random\r
-        64-bit number sequences, however, as with any LCG, the period of the\r
-        lower order bits is much shorter resulting in alternately odd/even pairs\r
-        in bit zero.\r
-\r
-        The result of the LGC above is tempered below with a series of XOR and\r
-        shift operations to produce a more acceptable equidistribution of bits\r
-        throughout the 64-bit range.\r
-    */\r
-    ullN ^= (ullN >> 21U) & ullT;\r
-    ullN ^= (ullN >> 43U) & ullT;\r
-    ullN ^= (ullN << 23U) & ~ullT;\r
-    ullN ^= (ullN << 31U) & ~ullT;\r
-\r
-    return ullN;\r
-}\r
-\r
-\r
-/** @brief Generate a 32-bit pseudo-random number.\r
-\r
-    @note   The 32-bit random number generator internally uses the 64-bit random\r
-            number generator, returning the low 32-bits of the pseudo-random\r
-            64-bit value.\r
-\r
-    @param pulSeed  A pointer to the seed to use.  Set this value to NULL to use\r
-                    the internal global seed value.\r
-\r
-    @return A pseudo-random number in the range [0, UINT32_MAX].\r
-*/\r
-uint32_t RedRand32(\r
-    uint32_t   *pulSeed)\r
-{\r
-    uint64_t    ullN;\r
-\r
-    if(pulSeed != NULL)\r
-    {\r
-        uint64_t ullLocalSeed;\r
-\r
-        ullLocalSeed = *pulSeed;\r
-        ullN = RedRand64(&ullLocalSeed);\r
-        *pulSeed = (uint32_t)ullLocalSeed;\r
-    }\r
-    else\r
-    {\r
-        ullN = RedRand64(NULL);\r
-    }\r
-\r
-    return (uint32_t)ullN;\r
-}\r
-\r
+/*             ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
+
+                   Copyright (c) 2014-2015 Datalight, Inc.
+                       All Rights Reserved Worldwide.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; use version 2 of the License.
+
+    This program is distributed in the hope that it will be useful,
+    but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty
+    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+/*  Businesses and individuals that for commercial or other reasons cannot
+    comply with the terms of the GPLv2 license may obtain a commercial license
+    before incorporating Reliance Edge into proprietary software for
+    distribution in any form.  Visit http://www.datalight.com/reliance-edge for
+    more information.
+*/
+/** @file
+    @brief Implements a random number generator.
+*/
+#include <redfs.h>
+#include <redtestutils.h>
+
+
+/*  This is the global seed used by the random number generator when the caller
+    has not provided a seed to either the RedRand32() or RedRand64() functions.
+*/
+static uint64_t ullGlobalRandomNumberSeed;
+
+/*  Whether the above seed has been initialized.
+*/
+static bool fGlobalSeedInited;
+
+
+/** @brief Set the global seed used by the random number generator.
+
+    The global seed gets used when RedRand64() or RedRand32() are called with
+    a NULL seed argument.
+
+    @param ullSeed  The value to use as the global RNG seed.
+*/
+void RedRandSeed(
+    uint64_t ullSeed)
+{
+    ullGlobalRandomNumberSeed = ullSeed;
+    fGlobalSeedInited = true;
+}
+
+
+/** @brief Generate a 64-bit pseudo-random number.
+
+    The period of this random number generator is 2^64 (1.8 x 1019).  These
+    parameters are the same as the default one-stream SPRNG lcg64 generator and
+    it satisfies the requirements for a maximal period.
+
+    The tempering value is used and an AND mask and is specifically selected to
+    favor the distribution of lower bits.
+
+    @param pullSeed A pointer to the seed to use.  Set this value to NULL to
+                    use the internal global seed value.
+
+    @return A pseudo-random number in the range [0, UINT64_MAX].
+*/
+uint64_t RedRand64(
+    uint64_t       *pullSeed)
+{
+    const uint64_t  ullA = UINT64_SUFFIX(2862933555777941757);
+    const uint64_t  ullC = UINT64_SUFFIX(3037000493);
+    const uint64_t  ullT = UINT64_SUFFIX(4921441182957829599);
+    uint64_t        ullN;
+    uint64_t       *pullSeedPtr;
+    uint64_t        ullLocalSeed;
+
+    if(pullSeed != NULL)
+    {
+        ullLocalSeed = *pullSeed;
+        pullSeedPtr = pullSeed;
+    }
+    else
+    {
+        if(!fGlobalSeedInited)
+        {
+            /*  Unfortunately, the Reliance Edge OS services don't give us much
+                to work with to initialize the global seed.  There is no entropy
+                abstraction, no tick count abstraction, and the timestamp
+                abstraction uses an opaque type which is not guaranteed to be an
+                integer.  The best we can do is use the RTC.
+
+                Tests using the RNG should be supplying a seed anyway, for
+                reproducibility.
+            */
+            RedRandSeed((uint64_t)RedOsClockGetTime());
+        }
+
+        ullLocalSeed = ullGlobalRandomNumberSeed;
+        pullSeedPtr = &ullGlobalRandomNumberSeed;
+    }
+
+    ullN = (ullLocalSeed * ullA) + ullC;
+
+    *pullSeedPtr = ullN;
+
+    /*  The linear congruential generator used above produces good psuedo-random
+        64-bit number sequences, however, as with any LCG, the period of the
+        lower order bits is much shorter resulting in alternately odd/even pairs
+        in bit zero.
+
+        The result of the LGC above is tempered below with a series of XOR and
+        shift operations to produce a more acceptable equidistribution of bits
+        throughout the 64-bit range.
+    */
+    ullN ^= (ullN >> 21U) & ullT;
+    ullN ^= (ullN >> 43U) & ullT;
+    ullN ^= (ullN << 23U) & ~ullT;
+    ullN ^= (ullN << 31U) & ~ullT;
+
+    return ullN;
+}
+
+
+/** @brief Generate a 32-bit pseudo-random number.
+
+    @note   The 32-bit random number generator internally uses the 64-bit random
+            number generator, returning the low 32-bits of the pseudo-random
+            64-bit value.
+
+    @param pulSeed  A pointer to the seed to use.  Set this value to NULL to use
+                    the internal global seed value.
+
+    @return A pseudo-random number in the range [0, UINT32_MAX].
+*/
+uint32_t RedRand32(
+    uint32_t   *pulSeed)
+{
+    uint64_t    ullN;
+
+    if(pulSeed != NULL)
+    {
+        uint64_t ullLocalSeed;
+
+        ullLocalSeed = *pulSeed;
+        ullN = RedRand64(&ullLocalSeed);
+        *pulSeed = (uint32_t)ullLocalSeed;
+    }
+    else
+    {
+        ullN = RedRand64(NULL);
+    }
+
+    return (uint32_t)ullN;
+}
+