]> www.ginac.de Git - cln.git/blob - src/base/random/cl_random_from.cc
Finalize CLN 1.3.7 release.
[cln.git] / src / base / random / cl_random_from.cc
1 // random_state constructor.
2
3
4 #if defined(_WIN32) && !defined(__CYGWIN__)
5 #include <windows.h> // For GetCurrentProcessId(), must be included first, sorry.
6 #endif
7
8 // General includes.
9 #include "base/cl_sysdep.h"
10
11 // Specification.
12 #include "cln/random.h"
13
14
15 // Implementation.
16
17 #include "base/cl_base_config.h"
18 #include "base/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 #include <sys/time.h>
28
29 namespace cln {
30 inline uint32 get_seed (void)
31 {
32         var struct timeval tv;
33         gettimeofday(&tv,NULL);
34         return highlow32(tv.tv_sec,tv.tv_usec); // 16+16 zufällige Bits
35 }
36 }  // namespace cln
37
38 #endif
39
40 #elif defined(_WIN32) && !defined(__CYGWIN__)
41
42 /* <windows.h> included above. */
43
44 namespace cln {
45 inline uint32 get_seed (void)
46 {
47         FILETIME current_time;
48
49         GetSystemTimeAsFileTime (&current_time);
50
51         /* Convert from FILETIME to 'struct timeval'.  */
52         /* FILETIME: <https://docs.microsoft.com/en-us/windows/desktop/api/minwinbase/ns-minwinbase-filetime> */
53         ULONGLONG since_1601 =
54                 ((ULONGLONG) current_time.dwHighDateTime << 32)
55                 | (ULONGLONG) current_time.dwLowDateTime;
56         /* Divide by 20 ms, and take the low-order 32 bits. */
57         return (ULONG) (since_1601 / 2000000);
58 }
59 }  // namespace cln
60
61 #endif
62
63 namespace cln {
64
65 // Counter, to avoid that two random-states created immediately one after
66 // the other contain the same seed.
67 static uint32 counter = 0;
68
69 random_state::random_state ()
70 {
71         var uint32 seed_hi;
72         var uint32 seed_lo;
73 #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__)
74         seed_lo = get_seed();
75         seed_hi = (rand() // zufällige 31 Bit (bei UNIX_BSD) bzw. 16 Bit (bei UNIX_SYSV)
76                           << 8) ^ (uintL)(getpid()); // ca. 8 Bit von der Process ID
77 #elif defined(__OpenBSD__)
78         seed_lo = arc4random();
79         seed_hi = arc4random();
80 #elif defined(_WIN32) && !defined(__CYGWIN__)
81         seed_lo = get_seed();
82         seed_hi = (rand() << 8) ^ (uintL)(GetCurrentProcessId());
83 #elif defined(__atarist)
84         seed_lo = highlow32(GEMDOS_GetDate(),GEMDOS_GetTime()); // 16+16 zufällige Bits
85         seed_hi = XBIOS_Random(); // 24 Bit zufällig vom XBIOS, vorne 8 Nullbits
86 #elif defined(amiga) || defined(AMIGA)
87         seed_lo = get_real_time(); // Uhrzeit
88         seed_hi = FindTask(NULL); // Pointer auf eigene Task
89 #elif defined(__MSDOS__) || defined(__EMX__) || defined(__riscos)
90         // Keine Zufallszahlen, keine PID, nichts Zufälliges da.
91         seed_lo = get_real_time(); // Uhrzeit, 100 Hz
92         seed_hi = time(NULL);
93 #else
94 #error "Must implement random_state constructor!"
95 #endif
96         seed_hi ^= counter++ << 5;
97         seed.hi = seed_hi;
98         seed.lo = seed_lo;
99 }
100
101 }  // namespace cln