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