glx-oml-sync-control-timing: Fix error message if glXWaitForMscOML fails
[piglit.git] / tests / util / mersenne.hpp
blob3e311fc6db3fab5a2065885a8e52eee5583269a3
1 /**************************************************************************
3 * Copyright 2012 VMware, Inc.
4 * All Rights Reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
28 #ifndef MERSENNE_HPP
29 #define MERSENNE_HPP
31 #include <string>
32 #include <stdio.h>
33 #include <stdint.h>
35 /**
36 * Variant of Mersenne Twister which can be skipped to any point in time.
38 * Instead of producing a new state table by mutating the previous table it initiates
39 * again using a seed which is the last random value of the previous state
42 class Mersenne
44 public:
45 static const uint32_t n = 624;
46 static const uint32_t m = 397;
47 static const uint32_t b32 = 1 << 31;
48 static const uint32_t rand_max = 0xFFFFFFFF;
50 public:
51 Mersenne() :
52 mSeed(0), mIndex(0), mState()
56 Mersenne(unsigned int seed)
58 init(seed);
61 unsigned int value()
63 uint32_t x = mState[mIndex++];
64 x ^= (x >> 11);
65 x ^= (x << 7) & 0x9D2C5680;
66 x ^= (x << 15) & 0xEFC60000;
67 x ^= (x >> 18);
69 if (mIndex == n){
70 init(x);
71 return value();
74 return x;
77 unsigned int max()
79 return 0xFFFFFFFF;
82 std::string state()
84 char buffer[32];
85 sprintf(buffer, "%08x%03d", mSeed, mIndex);
86 return buffer;
89 void setState(const std::string& state){
90 uint32_t seed, index;
91 sscanf(state.c_str(), "%08x%03d", &seed, &index);
93 init(seed);
94 mIndex = index;
97 void init(uint32_t seed)
99 mIndex = 0;
100 mSeed = seed;
102 /* Standard MT initialiser */
103 mState[0] = seed;
105 for (uint32_t i = 1; i < n; ++i)
106 mState[i] = 1812433253 * (mState[i - 1] ^ (mState[i - 1] >> 30)) + i;
108 /* Standard MT number generator, split into parts to avoid having to do % n */
109 for (uint32_t i = 0; i < (n - m); ++i)
110 mState[i] = mState[i + m] ^ twist(mState[i], mState[i + 1]);
112 for (uint32_t i = n - m; i < (n - 1); ++i)
113 mState[i] = mState[i + m - n] ^ twist(mState[i], mState[i + 1]);
115 mState[n - 1] = mState[m - 1] ^ twist(mState[n - 1], mState[0]);
118 private:
119 inline uint32_t twist(uint32_t a, uint32_t b)
121 return (((a & b32) | (b & ~b32)) >> 1) ^ ((b & 1) ? 0x9908B0DF : 0);
124 private:
125 uint32_t mSeed;
126 uint32_t mIndex;
127 uint32_t mState[n];
130 #endif // MERSENNE_HPP