00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00036 #include "OW_config.h"
00037 #include "OW_RandomNumber.hpp"
00038 #include "OW_Assertion.hpp"
00039 #include "OW_ThreadOnce.hpp"
00040 #include "OW_Mutex.hpp"
00041 #include "OW_MutexLock.hpp"
00042 #include <fstream>
00043 #include <sys/types.h>
00044
00045 #ifdef OW_HAVE_UNISTD_H
00046 #include <unistd.h>
00047 #endif
00048
00049 #ifdef OW_HAVE_SYS_TIME_H
00050 #include <sys/time.h>
00051 #endif
00052
00053 #include <stdlib.h>
00054 #include <time.h>
00055
00056 namespace OW_NAMESPACE
00057 {
00058
00060 namespace
00061 {
00062 OnceFlag guard;
00063 unsigned int seed = 0;
00064 }
00065
00067 RandomNumber::RandomNumber(Int32 lowVal, Int32 highVal)
00068 : m_lowVal(lowVal), m_highVal(highVal)
00069 {
00070 if (lowVal > highVal)
00071 {
00072 m_lowVal = highVal;
00073 m_highVal = lowVal;
00074 }
00075 callOnce(guard, &initRandomness);
00076 }
00077
00079 void
00080 RandomNumber::initRandomness()
00081 {
00082 #ifdef OW_WIN32
00083 time_t timeval = ::time(NULL);
00084 seed = timeval;
00085 #else
00086
00087 struct timeval tv;
00088 gettimeofday(&tv, 0);
00089
00090 std::ifstream infile("/dev/urandom", std::ios::in);
00091 if (!infile)
00092 {
00093 infile.open("/dev/random", std::ios::in);
00094 }
00095
00096
00097 unsigned int dev_rand_input;
00098 if (infile)
00099 {
00100 infile.read(reinterpret_cast<char*>(&dev_rand_input), sizeof(dev_rand_input));
00101 infile.close();
00102 }
00103
00104 seed = dev_rand_input ^ (getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec;
00105 #endif
00106 #ifdef OW_HAVE_SRANDOM
00107 srandom(seed);
00108 #else
00109 srand(seed);
00110 #endif
00111 }
00112
00114 void
00115 RandomNumber::saveRandomState()
00116 {
00117
00118 }
00119
00120 namespace
00121 {
00122 Mutex g_guard;
00123 }
00125 Int32
00126 RandomNumber::getNextNumber()
00127 {
00128 MutexLock lock(g_guard);
00129 #ifdef OW_HAVE_RANDOM
00130 return m_lowVal + (random() % (m_highVal - m_lowVal + 1));
00131 #else
00132 return m_lowVal + (rand() % (m_highVal - m_lowVal + 1));
00133 #endif
00134 }
00135
00136 }
00137