]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/system/RandomMlcgC.nc
mark more modules as safe code
[tinyos-2.x.git] / tos / system / RandomMlcgC.nc
index b9c0dfd27608dc69b5b794f349b29511a1f45cf7..3e6a3f411917a6dcebca3564464f247642e32800 100644 (file)
  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
  */
-
-/**
- * This is the configuration for RandomMlcgC, a 
- * multiplicative linear congruential generator. 
+/** This code is a fast implementation of the Park-Miller Minimal Standard 
+ *  Generator for pseudo-random numbers.  It uses the 32 bit multiplicative 
+ *  linear congruential generator, 
+ *
+ *             S' = (A x S) mod (2^31 - 1) 
+ *
+ *  for A = 16807.
+ *
  *
- * @author  Barbara Hohlt
- * @author  Philip Levis
- * @date    March 1 2005
+ * @author Barbara Hohlt 
+ * @date   March 1 2005
  */
 
-configuration RandomMlcgC {
+module RandomMlcgC @safe() {
   provides interface Init;
   provides interface ParameterInit<uint16_t> as SeedInit;
-  provides interface Random as Random;
+  provides interface Random;
 }
+implementation
+{
+    uint32_t seed ;
 
-implementation {
-  components RandomMlcgP;
+  /* Initialize the seed from the ID of the node */
+  command error_t Init.init() {
+    atomic  seed = (uint32_t)(TOS_NODE_ID + 1);
+    
+    return SUCCESS;
+  }
 
-  Init = RandomMlcgP;
-  SeedInit = RandomMlcgP;
-  Random = RandomMlcgP;
+  /* Initialize with 16-bit seed */ 
+  command error_t SeedInit.init(uint16_t s) {
+    atomic  seed = (uint32_t)(s + 1);
+    
+    return SUCCESS;
+  }
 
-} 
+  /* Return the next 32 bit random number */
+  async command uint32_t Random.rand32() {
+    uint32_t mlcg,p,q;
+    uint64_t tmpseed;
+    atomic
+      {
+       tmpseed =  (uint64_t)33614U * (uint64_t)seed;
+       q = tmpseed;    /* low */
+       q = q >> 1;
+       p = tmpseed >> 32 ;             /* hi */
+       mlcg = p + q;
+        if (mlcg & 0x80000000) { 
+         mlcg = mlcg & 0x7FFFFFFF;
+         mlcg++;
+       }
+       seed = mlcg;
+      }
+    return mlcg; 
+  }
+
+  /* Return low 16 bits of next 32 bit random number */
+  async command uint16_t Random.rand16() {
+    return (uint16_t)call Random.rand32();
+  }
+
+#if 0
+ /* Return high 16 bits of 32 bit number */
+ inline uint16_t getHigh16(uint32_t num) {
+    return num >> 16;
+ }
+#endif
+}