Index: sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c +++ sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c @@ -135,6 +135,10 @@ #include "dtrace_debug.c" #endif +#include + +#include "dtrace_xoroshiro128_plus.h" + /* * DTrace Tunable Variables * @@ -4104,7 +4108,8 @@ switch (subr) { case DIF_SUBR_RAND: - regs[rd] = (dtrace_gethrtime() * 2416 + 374441) % 1771875; + regs[rd] = dtrace_xoroshiro128_plus_next( + state->dts_rstate[curcpu]); break; #ifdef illumos @@ -14277,6 +14282,7 @@ dtrace_state_t *state; dtrace_optval_t *opt; int bufsize = NCPU * sizeof (dtrace_buffer_t), i; + int cpu_it; ASSERT(MUTEX_HELD(&dtrace_lock)); ASSERT(MUTEX_HELD(&cpu_lock)); @@ -14332,6 +14338,21 @@ state->dts_buffer = kmem_zalloc(bufsize, KM_SLEEP); state->dts_aggbuffer = kmem_zalloc(bufsize, KM_SLEEP); + /* + * Allocate and initialise the per-process per-CPU random state. + * SI_SUB_RANDOM < SI_SUB_DTRACE_ANON therefore entropy device is + * assumed to be seeded at this point (if from Fortuna seed file). + */ + (void) read_random(&state->dts_rstate[0], 2 * sizeof(uint64_t)); + for (cpu_it = 1; cpu_it < NCPU; cpu_it++) { + /* + * Each CPU is assigned a 2^64 period, non-overlapping + * subsequence. + */ + dtrace_xoroshiro128_plus_jump(state->dts_rstate[cpu_it-1], + state->dts_rstate[cpu_it]); + } + #ifdef illumos state->dts_cleaner = CYCLIC_NONE; state->dts_deadman = CYCLIC_NONE; @@ -15125,7 +15146,7 @@ dtrace_buffer_free(state->dts_buffer); dtrace_buffer_free(state->dts_aggbuffer); - + for (i = 0; i < nspec; i++) dtrace_buffer_free(spec[i].dtsp_buffer); Index: sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace_xoroshiro128_plus.h =================================================================== --- /dev/null +++ sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace_xoroshiro128_plus.h @@ -0,0 +1,18 @@ + +#ifndef _DTRACE_XOROSHIRO128_PLUS_H +#define _DTRACE_XOROSHIRO128_PLUS_H +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern void dtrace_xoroshiro128_plus_jump(uint64_t * const, uint64_t * const); +extern uint64_t dtrace_xoroshiro128_plus_next(uint64_t * const); + +#ifdef __cplusplus +} +#endif + Index: sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace_xoroshiro128_plus.c =================================================================== --- /dev/null +++ sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace_xoroshiro128_plus.c @@ -0,0 +1,57 @@ +#include + +#include "dtrace_xoroshiro128_plus.h" + +static __inline uint64_t +rotl(const uint64_t x, int k) +{ + return (x << k) | (x >> (64 - k)); +} + +/* + * This is the jump function for the generator. It is equivalent to 2^64 calls + * to next(); it can be used to generate 2^64 non-overlapping subsequences for + * parallel computations. + */ +void +dtrace_xoroshiro128_plus_jump(uint64_t * const state, + uint64_t * const jump_state) +{ + static const uint64_t JUMP[] = { 0xbeac0467eba5facb, + 0xd86b048b86aa9922 }; + + uint64_t s0 = 0; + uint64_t s1 = 0; + int i = 0; + int b = 0; + for (i = 0; i < sizeof JUMP / sizeof *JUMP; i++) { + for (b = 0; b < 64; b++) { + if (JUMP[i] & 1ULL << b) { + s0 ^= state[0]; + s1 ^= state[1]; + } + dtrace_xoroshiro128_plus_next(state); + } + } + jump_state[0] = s0; + jump_state[1] = s1; +} + +/* + * xoroshiro128+ - XOR/rotate/shift/rotate + * xorshift.di.unimi.it + */ +uint64_t +dtrace_xoroshiro128_plus_next(uint64_t * const state) +{ + const uint64_t s0 = state[0]; + uint64_t s1 = state[1]; + uint64_t result; + result = s0 + s1; + + s1 ^= s0; + state[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); + state[1] = rotl(s1, 36); + + return result; +} Index: sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h +++ sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h @@ -50,6 +50,10 @@ */ #include +#include +#include +#include + #ifndef illumos #ifdef __sparcv9 typedef uint32_t pc_t; @@ -1168,6 +1172,7 @@ dtrace_cred_t dts_cred; /* credentials */ size_t dts_nretained; /* number of retained enabs */ int dts_getf; /* number of getf() calls */ + uint64_t dts_rstate[MAXCPU][2]; /* per-CPU random state */ }; struct dtrace_provider { Index: sys/modules/dtrace/dtrace/Makefile =================================================================== --- sys/modules/dtrace/dtrace/Makefile +++ sys/modules/dtrace/dtrace/Makefile @@ -12,6 +12,7 @@ KMOD= dtrace SRCS= dtrace.c \ + dtrace_xoroshiro128_plus.c \ dtrace_asm.S \ dtrace_subr.c @@ -42,6 +43,7 @@ -I${SYSDIR}/cddl/dev/dtrace \ -I${SYSDIR}/cddl/dev/dtrace/${ARCHDIR} \ -I${SYSDIR}/cddl/contrib/opensolaris/uts/common \ + -I${SYSDIR}/cddl/contrib/opensolaris/uts/common/dtrace \ -I${SYSDIR}/cddl/contrib/opensolaris/common/util \ -I${SYSDIR} -DDIS_MEM Index: sys/modules/dtrace/fasttrap/Makefile =================================================================== --- sys/modules/dtrace/fasttrap/Makefile +++ sys/modules/dtrace/fasttrap/Makefile @@ -10,6 +10,7 @@ CFLAGS+= -I${SYSDIR}/cddl/compat/opensolaris \ -I${SYSDIR}/cddl/contrib/opensolaris/uts/common \ + -I${SYSDIR}/cddl/contrib/opensolaris/uts/common/dtrace \ -I${SYSDIR} .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" Index: sys/modules/dtrace/systrace/Makefile =================================================================== --- sys/modules/dtrace/systrace/Makefile +++ sys/modules/dtrace/systrace/Makefile @@ -10,6 +10,7 @@ CFLAGS+= -I${SYSDIR}/cddl/compat/opensolaris \ -I${SYSDIR}/cddl/contrib/opensolaris/uts/common \ + -I${SYSDIR}/cddl/contrib/opensolaris/uts/common/dtrace \ -I${SYSDIR} .include