#ifdef __cplusplus
extern "C" {
#endif

#include "uulib/splitmix.h"
#include "uulib/gettime.h"

#ifdef __cplusplus
}
#endif

/* based on splitmix64
 * https://xorshift.di.unimi.it/splitmix64.c
*/

/* called from boot */
void sm_srand(pUCXT) {
  struct timeval  tv;
  int             i, n;
  UV              ptod[2];

  /* gettimeofday(&tv, 0); */
  (*UCXT.myU2time)(aTHX_ (UV*)&ptod);
  tv.tv_sec  = ptod[0];
  tv.tv_usec = ptod[1];

  /* XXX - this needs a rethink */
  UCXT.sm_x = gt_100ns64(aUCXT)
    ^ (U64)UCXT.thread_id
    ^ (U64)tv.tv_sec  << 16
    ^ (U64)tv.tv_usec << 32
    ^ (U64)getpid()   << 48;

  n = (tv.tv_sec ^ tv.tv_usec) & 0x1f;

  for (i=0; i<n; ++i)
    (void)sm_rand(aUCXT);
}

U64 sm_rand(pUCXT) {
  U64 z = (UCXT.sm_x += 0x9e3779b97f4a7c15ULL);
  z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9ULL;
  z = (z ^ (z >> 27)) * 0x94d049bb133111ebULL;
  return z ^ (z >> 31);
}

/* ex:set ts=2 sw=2 itab=spaces: */
