From 1ff022cae16e98ff565fbfd76b14bd892418e653 Mon Sep 17 00:00:00 2001 From: Richard Kistruck Date: Mon, 22 Mar 2010 23:00:42 +0000 Subject: mps br/vmem: simple-chunk-return: zcoll.c: How to get rid of all the objects, so full collect really collects all automatic objects: - Rootdrop() helps, but we can still retain a 1.2MB object; - stackwipe() does not help much -- these unwanted ambig refs are being left on the stack by MPS code that runs between mps_arena_collect and the flip! - therefore StackScan(0/1) to destroy stack+reg root before full collect: it's the only way to be sure. Reproducibility: - give Make() a random? switch, acted on by df() = diversity function, to allow bypass of rnd(); - ZRndStateSet, to set the seed for rnd() Output: - print_M: switchable Mebibytes or Megabytes (more useful, to be honest); - get(): don't report message times, it messes up diffs. testlib.c/h: Reproducibility: - fix rnd_state so a rnd_state getter is possible; - testlib.h += rnd_state_t, rnd_state(), rnd_state_set(), rnd_state_set_v2() trace.c: traceFindGrey diag: no newline please Copied from Perforce Change: 170093 ServerID: perforce.ravenbrook.com --- mps/code/testlib.c | 88 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 70 insertions(+), 18 deletions(-) (limited to 'mps/code/testlib.c') diff --git a/mps/code/testlib.c b/mps/code/testlib.c index 71cc05d330e..0bc8771f134 100644 --- a/mps/code/testlib.c +++ b/mps/code/testlib.c @@ -221,48 +221,100 @@ mps_addr_t rnd_addr(void) } -/* randomize -- randomize the generator, or initialize to replay */ +/* randomize -- randomize the generator, or initialize to replay + * + * There have been 3 versions of the rnd-states reported by this + * function: + * + * 1. before RHSK got his hands on rnd(). These seed values are not + * currently supported, but it might be easy to add support. + * + * 2. v2 states: the published "seed" (state) value was the seed + * *before* the 10 rnds to churn up and separate nearby values + * from time(). This is unfortunate: you can't write a rnd_state + * getter, because it would have to go 10 steps back in time. + * + * 3. v3 states: when autogenerated from time(), the published + * state is that *after* the 10 rnds. Therefore you can get this + * easily, store it, re-use it, etc. + */ void randomize(int argc, char **argv) { + int i; int n; + unsigned long seedt; unsigned long seed0; - int i; if (argc > 1) { n = sscanf(argv[1], "%lu", &seed0); Insist(n == 1); - printf("randomize(): resetting initial seed to: %lu.\n", seed0); + printf("randomize(): resetting initial state (v3) to: %lu.\n", seed0); + rnd_state_set(seed0); } else { /* time_t uses an arbitrary encoding, but hopefully the low order */ /* 31 bits will have at least one bit changed from run to run. */ - seed0 = 1 + time(NULL) % (R_m - 1); - printf("randomize(): choosing initial seed: %lu.\n", seed0); + seedt = 1 + time(NULL) % (R_m - 1); + + /* The value returned by time() on some OSs may simply be a + * count of seconds: therefore successive runs may start with + * nearby seeds, possibly differing only by 1. So the first value + * returned by rnd() may differ by only 48271. It is conceivable + * that some tests might be able to 'spot' this pattern (for + * example: by using the first rnd() value, mod 100M and rounded + * to multiple of 1024K, as arena size in bytes). + * + * So to mix it up a bit, we do a few iterations now. How many? + * Very roughly, 48271^2 is of the same order as 2^31, so two + * iterations would make the characteristic difference similar to + * the period. Hey, let's go wild and do 10. + */ + rnd_state_set(seedt); + for(i = 0; i < 10; i += 1) { + (void)rnd(); + } + + seed0 = rnd_state(); + printf("randomize(): choosing initial state (v3): %lu.\n", seed0); + rnd_state_set(seed0); } +} + +unsigned long rnd_state(void) +{ + return seed; +} +void rnd_state_set(unsigned long seed0) +{ Insist(seed0 < R_m); Insist(seed0 != 0); seed = seed0; rnd_verify(0); Insist(seed == seed0); +} + +/* rnd_state_set_2 -- legacy support for v2 rnd states + * + * In v2, the published "seed" (state) value was the seed *before* + * the 10 rnds to churn up and separate nearby values from time(). + * + * Set the seed, then convert it to a v3 state by doing those 10 rnds. + */ +void rnd_state_set_v2(unsigned long seed0_v2) +{ + int i; + unsigned long seed0; - /* The 'random' seed is taken from time(), which may simply be a - * count of seconds: therefore successive runs may start with - * nearby seeds, possibly differing only by 1. So the first value - * returned by rnd() may differ by only 48271. It is conceivable - * that some tests might be able to 'spot' this pattern (for - * example: by using the first rnd() value, mod 100M and rounded - * to multiple of 1024K, as arena size in bytes). - * - * So to mix it up a bit, we do a few iterations now. How many? - * Very roughly, 48271^2 is of the same order as 2^31, so two - * iterations would make the characteristic difference similar to - * the period. Hey, let's go wild and do 10. - */ + rnd_state_set(seed0_v2); for(i = 0; i < 10; i += 1) { (void)rnd(); } + + seed0 = rnd_state(); + printf("rnd_state_set_v2(): seed0_v2 = %lu, converted to state_v3 = %lu.\n", seed0_v2, seed0); + rnd_state_set(seed0); } -- cgit v1.2.1