]> www.ginac.de Git - cln.git/blob - src/base/random/cl_random_from.cc
0470a4e76bd105e8b3484d2bf745e06db7ebe4e8
[cln.git] / src / base / random / cl_random_from.cc
1 // random_state constructor.
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cln/random.h"
8
9
10 // Implementation.
11
12 #if defined(_WIN32)
13 #include <windows.h> // for GetCurrentProcessId()
14 #endif
15
16 #include "cl_base_config.h"
17 #include "cl_low.h"
18 #include <cstdlib>  // declares rand()
19
20 #if defined(unix) || defined(__unix) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(_AIX) || defined(sinix) || (defined(__MACH__) && defined(__APPLE__)) || (defined(__CYGWIN__) && defined(__GNUC__)) || defined(__BEOS__)
21
22 #include <sys/types.h>
23 #include <unistd.h> // declares getpid()
24
25 #if defined(HAVE_GETTIMEOFDAY)
26
27 #include <sys/time.h>
28 #ifdef GETTIMEOFDAY_DOTS
29   extern "C" int gettimeofday (struct timeval * tp, ...);
30 #else
31   extern "C" int gettimeofday (struct timeval * tp, GETTIMEOFDAY_TZP_T tzp);
32 #endif
33
34 inline uint32 get_seed (void)
35 {
36         var struct timeval tv;
37         gettimeofday(&tv,0);
38         return cln::highlow32(tv.tv_sec,tv.tv_usec); // 16+16 zufällige Bits
39 }
40
41 #elif defined(HAVE_TIMES_CLOCK)
42
43 #include <ctime>
44 #ifndef CLK_TCK
45 #include <sys/time.h>
46 #endif
47 #include <sys/times.h>
48 extern "C" clock_t times (struct tms * buffer);
49
50 namespace cln {
51 inline uint32 get_seed (void)
52 {
53         var struct tms tmsbuf;
54         var uint32 seed_lo = times(&tmsbuf);
55         return seed_lo + tmsbuf.tms_utime + tmsbuf.tms_stime;
56 }
57 }  // namespace cln
58
59 #endif
60
61 #elif defined(_WIN32)
62 #include <sys/time.h>
63 #include <sys/timeb.h>
64
65 namespace cln {
66 inline uint32 get_seed (void)
67 {
68         struct timeb timebuf;
69         ftime(&timebuf);
70         return cln::highlow32(timebuf.time, (long)(timebuf.millitm)*1000);
71 }
72 }  // namespace cln
73
74 #endif
75
76 namespace cln {
77
78 // Counter, to avoid that two random-states created immediately one after
79 // the other contain the same seed.
80 static uint32 counter = 0;
81
82 random_state::random_state ()
83 {
84         var uint32 seed_hi;
85         var uint32 seed_lo;
86 #if defined(unix) || defined(__unix) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(_AIX) || defined(sinix) || (defined(__MACH__) && defined(__APPLE__)) || (defined(__CYGWIN__) && defined(__GNUC__)) || defined(__BEOS__)
87         seed_lo = ::get_seed();
88         seed_hi = (rand() // zufällige 31 Bit (bei UNIX_BSD) bzw. 16 Bit (bei UNIX_SYSV)
89                           << 8) ^ (uintL)(getpid()); // ca. 8 Bit von der Process ID
90 #elif defined(__OpenBSD__)
91         seed_lo = arc4random();
92         seed_hi = arc4random();
93 #elif defined(_WIN32)
94         seed_lo = ::get_seed();
95         seed_hi = (rand() << 8) ^ (uintL)(GetCurrentProcessId());
96 #elif defined(__atarist)
97         seed_lo = highlow32(GEMDOS_GetDate(),GEMDOS_GetTime()); // 16+16 zufällige Bits
98         seed_hi = XBIOS_Random(); // 24 Bit zufällig vom XBIOS, vorne 8 Nullbits
99 #elif defined(amiga) || defined(AMIGA)
100         seed_lo = get_real_time(); // Uhrzeit
101         seed_hi = FindTask(NULL); // Pointer auf eigene Task
102 #elif defined(__MSDOS__) || defined(__EMX__) || defined(__riscos)
103         // Keine Zufallszahlen, keine PID, nichts Zufälliges da.
104         seed_lo = get_real_time(); // Uhrzeit, 100 Hz
105         seed_hi = time(NULL);
106 #else
107 #error "Must implement random_state constructor!"
108 #endif
109         seed_hi ^= counter++ << 5;
110         seed.hi = seed_hi;
111         seed.lo = seed_lo;
112 }
113
114 }  // namespace cln