File Coverage

lib/Random/rdtsc_rand.h
Criterion Covered Total %
statement 15 22 68.1
branch n/a
condition n/a
subroutine n/a
pod n/a
total 15 22 68.1


line stmt bran cond sub pod time code
1             #include
2             #include // for clock_gettime()
3              
4             ////////////////////////////////////////////////////////////////////////////////
5             // rdtsc_rand.h: v0.7
6             //
7             // https://github.com/scottchiefbaker/rdtsc_rand
8             ////////////////////////////////////////////////////////////////////////////////
9              
10             // Multiply-Shift Hash (Passes SmallCrush and PractRand up to 128GB)
11 2           static uint64_t hash_msh(uint64_t x) {
12 2           uint64_t prime = 0x9e3779b97f4a7c15; // A large prime constant
13 2           x ^= (x >> 30);
14 2           x *= prime;
15 2           x ^= (x >> 27);
16 2           x *= prime;
17 2           x ^= (x >> 31);
18 2           return x;
19             }
20              
21             // MurmurHash3 Finalizer (Passes SmallCrush and PractRand up to 32GB)
22 0           static uint64_t hash_mur3(uint64_t x) {
23 0           x ^= x >> 33;
24 0           x *= 0xff51afd7ed558ccd;
25 0           x ^= x >> 33;
26 0           x *= 0xc4ceb9fe1a85ec53;
27 0           x ^= x >> 33;
28 0           return x;
29             }
30              
31             #if (defined(__ARM_ARCH))
32             // Nanoseconds since Unix epoch
33             static uint64_t rdtsc_nanos() {
34             struct timespec ts;
35              
36             int8_t ok = clock_gettime(CLOCK_MONOTONIC, &ts); // Uptime
37             //int8_t ok = clock_gettime(CLOCK_REALTIME, &ts); // Since epoch
38              
39             if (ok != 0) {
40             return 0; // Return 0 on failure (you can handle this differently)
41             }
42              
43             // Calculate nanoseconds
44             uint64_t ret = (uint64_t)ts.tv_sec * 1000000000ULL + (uint64_t)ts.tv_nsec;
45              
46             //printf("N: %llu\n", ret);
47              
48             return ret;
49             }
50             #endif
51              
52             //////////////////////////////////////
53             // End hashing function definitions //
54             //////////////////////////////////////
55              
56             #if defined(_WIN32) || defined(_WIN64)
57             #include
58             #pragma intrinsic(__rdtsc)
59             #endif
60              
61             // Get the instruction counter for various CPU/Platforms
62 4           static uint64_t get_rdtsc() {
63             #if defined(_WIN32) || defined(_WIN64)
64             return __rdtsc();
65             #elif defined(__aarch64__) || defined(__arm64)
66             uint64_t count;
67             __asm__ volatile ("mrs %0, cntvct_el0" : "=r" (count));
68             return count;
69             #elif defined(ARDUINO)
70             return micros();
71             #elif (defined(__x86_64) || defined(__i386__) || defined(__i686__)) && (defined(__GNUC__) || defined(__clang__))
72             uint32_t low, high;
73 4           __asm__ volatile ("rdtsc" : "=a"(low), "=d"(high));
74 4           return ((uint64_t)(high) << 32) | low;
75             #elif (defined(__ARM_ARCH))
76             return rdtsc_nanos();
77             #else
78             #warning "rdtsc_rand: Unknown system type. Results will be 0."
79             return 0;
80             #endif
81             }
82              
83             // Get an unsigned 64bit random integer
84 2           static uint64_t rdtsc_rand64() {
85             // Hash the rdtsc value through hash64
86 2           uint64_t rdtsc_val = get_rdtsc();
87 2           uint64_t ret = hash_msh(rdtsc_val);
88              
89 2           return ret;
90             }