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