Small whitespace cleanup
[lsnes.git] / src / library / crandom.cpp
blobc658d498a303e819dc9f2160693e809788ac4bc9
1 #include "arch-detect.hpp"
2 #include "crandom.hpp"
3 #include <stdexcept>
4 #include <iostream>
6 #if defined(_WIN32) || defined(_WIN64)
7 #include <windows.h>
9 namespace
11 typedef BOOLEAN (WINAPI *rtlgenrandom_t)(PVOID buf, ULONG buflen);
12 HMODULE advapi;
13 rtlgenrandom_t rtlgenrandom_fn;
16 namespace crandom
18 void init()
20 if(rtlgenrandom_fn) return;
21 advapi = LoadLibraryA("advapi32.dll");
22 if(!advapi)
23 throw std::runtime_error("Can't load advapi32.dll");
24 rtlgenrandom_fn = (rtlgenrandom_t)GetProcAddress(advapi, "SystemFunction036");
25 if(!rtlgenrandom_fn)
26 throw std::runtime_error("Can't find rtlgenrandom");
29 void generate(void* buffer, size_t buffersize)
31 if(!rtlgenrandom_fn)
32 init();
33 while(!rtlgenrandom_fn(buffer, buffersize));
37 #else
38 #include <unistd.h>
39 #include <fcntl.h>
40 #include <cerrno>
42 namespace
44 int fd = -1;
45 void try_file(const char* name)
47 int err = 0;
48 while(fd < 0 && err != ENOENT && err != ENXIO) {
49 fd = open(name, O_RDONLY);
50 if(fd < 0) err = errno;
55 namespace crandom
57 void init()
59 if(fd < 0) try_file("/dev/urandom");
60 if(fd < 0) try_file("/dev/random");
61 if(fd < 0) throw std::runtime_error("Can't open /dev/urandom");
64 void generate(void* buffer, size_t buffersize)
66 if(fd < 0)
67 init();
68 size_t out = 0;
69 while(out < buffersize) {
70 ssize_t r = read(fd, (char*)buffer + out, buffersize - out);
71 if(r > 0) out += r;
76 #endif
78 namespace crandom
80 uint64_t arch_get_tsc()
82 #ifdef ARCH_IS_I386
83 uint32_t a, b;
84 asm volatile("rdtsc" : "=a"(a), "=d"(b));
85 return ((uint64_t)b << 32) | a;
86 #else
87 return 0;
88 #endif
91 uint64_t arch_get_random()
93 #ifdef ARCH_IS_I386
94 uint32_t r;
95 asm volatile (".byte 0xb8, 0x01, 0x00, 0x00, 0x00, 0x0f, 0xa2, 0xf7, 0xc1, 0x00, 0x00, 0x00, 0x40, "
96 "0x74, 0x05, 0x0f, 0xc7, 0xf0, 0xeb, 0x02, 0x31, 0xc0" : "=a"(r) : : "ebx", "ecx", "edx");
97 return r;
98 #else
99 return 0;
100 #endif