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