File Coverage

ulib/splitmix.c
Criterion Covered Total %
statement 17 17 100.0
branch 4 4 100.0
condition n/a
subroutine n/a
pod n/a
total 21 21 100.0


line stmt bran cond sub pod time code
1             #ifdef __cplusplus
2             extern "C" {
3             #endif
4              
5             #include "ulib/splitmix.h"
6             #include "ulib/gettime.h"
7              
8             #ifdef __cplusplus
9             }
10             #endif
11              
12             /* based on splitmix64
13             * https://xorshift.di.unimi.it/splitmix64.c
14             */
15              
16 104           void sm_srand(pUCXT, Pid_t pid) {
17             unsigned int n;
18             UV ptod[2];
19              
20             /*
21             * The idea is to just have a unique value here,
22             * so system time and process id should be enough.
23             * (Provided system time doesn't repeat!)
24             *
25             * But, since Unix epoch time with usec resolution
26             * is 51 bits, that only leaves 13 bits for pid.
27             *
28             * So, lets initially seed with TOD, mix, add the PID,
29             * then mix again.
30             */
31              
32             /* gettimeofday(&tv, 0); */
33 104           (*UCXT.myU2time)(aTHX_ (UV*)&ptod);
34 104           UCXT.sm_x = (U64)ptod[0] * 1000000
35 104           + (U64)ptod[1];
36              
37             /* stir 16 - 31 times, pid-based */
38 104           n = 16 + (pid & 0x0f);
39 2512 100         while (n-- > 0)
40 2408           (void)sm_rand(aUCXT);
41              
42 104           UCXT.sm_x ^= (U64)pid;
43              
44             /* stir 16 - 31 times, time-based */
45 104           n = 16 + ((ptod[0] ^ ptod[1]) & 0x0f);
46 2571 100         while (n-- > 0)
47 2467           (void)sm_rand(aUCXT);
48 104           }
49              
50 5395           U64 sm_rand(pUCXT) {
51 5395           U64 z = (UCXT.sm_x += 0x9e3779b97f4a7c15ULL);
52 5395           z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9ULL;
53 5395           z = (z ^ (z >> 27)) * 0x94d049bb133111ebULL;
54 5395           return z ^ (z >> 31);
55             }
56              
57             /* ex:set ts=2 sw=2 itab=spaces: */