diff options
| author | Richard Kistruck | 2010-03-22 23:00:42 +0000 |
|---|---|---|
| committer | Richard Kistruck | 2010-03-22 23:00:42 +0000 |
| commit | 1ff022cae16e98ff565fbfd76b14bd892418e653 (patch) | |
| tree | 91f2ff05d1c9517dde22486e1195c0feab8d1122 /mps/code/testlib.c | |
| parent | 968eafea906c60658f5c412935e9352a645ca2fa (diff) | |
| download | emacs-1ff022cae16e98ff565fbfd76b14bd892418e653.tar.gz emacs-1ff022cae16e98ff565fbfd76b14bd892418e653.zip | |
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
Diffstat (limited to 'mps/code/testlib.c')
| -rw-r--r-- | mps/code/testlib.c | 88 |
1 files changed, 70 insertions, 18 deletions
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) | |||
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | 223 | ||
| 224 | /* randomize -- randomize the generator, or initialize to replay */ | 224 | /* randomize -- randomize the generator, or initialize to replay |
| 225 | * | ||
| 226 | * There have been 3 versions of the rnd-states reported by this | ||
| 227 | * function: | ||
| 228 | * | ||
| 229 | * 1. before RHSK got his hands on rnd(). These seed values are not | ||
| 230 | * currently supported, but it might be easy to add support. | ||
| 231 | * | ||
| 232 | * 2. v2 states: the published "seed" (state) value was the seed | ||
| 233 | * *before* the 10 rnds to churn up and separate nearby values | ||
| 234 | * from time(). This is unfortunate: you can't write a rnd_state | ||
| 235 | * getter, because it would have to go 10 steps back in time. | ||
| 236 | * | ||
| 237 | * 3. v3 states: when autogenerated from time(), the published | ||
| 238 | * state is that *after* the 10 rnds. Therefore you can get this | ||
| 239 | * easily, store it, re-use it, etc. | ||
| 240 | */ | ||
| 225 | 241 | ||
| 226 | void randomize(int argc, char **argv) | 242 | void randomize(int argc, char **argv) |
| 227 | { | 243 | { |
| 244 | int i; | ||
| 228 | int n; | 245 | int n; |
| 246 | unsigned long seedt; | ||
| 229 | unsigned long seed0; | 247 | unsigned long seed0; |
| 230 | int i; | ||
| 231 | 248 | ||
| 232 | if (argc > 1) { | 249 | if (argc > 1) { |
| 233 | n = sscanf(argv[1], "%lu", &seed0); | 250 | n = sscanf(argv[1], "%lu", &seed0); |
| 234 | Insist(n == 1); | 251 | Insist(n == 1); |
| 235 | printf("randomize(): resetting initial seed to: %lu.\n", seed0); | 252 | printf("randomize(): resetting initial state (v3) to: %lu.\n", seed0); |
| 253 | rnd_state_set(seed0); | ||
| 236 | } else { | 254 | } else { |
| 237 | /* time_t uses an arbitrary encoding, but hopefully the low order */ | 255 | /* time_t uses an arbitrary encoding, but hopefully the low order */ |
| 238 | /* 31 bits will have at least one bit changed from run to run. */ | 256 | /* 31 bits will have at least one bit changed from run to run. */ |
| 239 | seed0 = 1 + time(NULL) % (R_m - 1); | 257 | seedt = 1 + time(NULL) % (R_m - 1); |
| 240 | printf("randomize(): choosing initial seed: %lu.\n", seed0); | 258 | |
| 259 | /* The value returned by time() on some OSs may simply be a | ||
| 260 | * count of seconds: therefore successive runs may start with | ||
| 261 | * nearby seeds, possibly differing only by 1. So the first value | ||
| 262 | * returned by rnd() may differ by only 48271. It is conceivable | ||
| 263 | * that some tests might be able to 'spot' this pattern (for | ||
| 264 | * example: by using the first rnd() value, mod 100M and rounded | ||
| 265 | * to multiple of 1024K, as arena size in bytes). | ||
| 266 | * | ||
| 267 | * So to mix it up a bit, we do a few iterations now. How many? | ||
| 268 | * Very roughly, 48271^2 is of the same order as 2^31, so two | ||
| 269 | * iterations would make the characteristic difference similar to | ||
| 270 | * the period. Hey, let's go wild and do 10. | ||
| 271 | */ | ||
| 272 | rnd_state_set(seedt); | ||
| 273 | for(i = 0; i < 10; i += 1) { | ||
| 274 | (void)rnd(); | ||
| 275 | } | ||
| 276 | |||
| 277 | seed0 = rnd_state(); | ||
| 278 | printf("randomize(): choosing initial state (v3): %lu.\n", seed0); | ||
| 279 | rnd_state_set(seed0); | ||
| 241 | } | 280 | } |
| 281 | } | ||
| 282 | |||
| 283 | unsigned long rnd_state(void) | ||
| 284 | { | ||
| 285 | return seed; | ||
| 286 | } | ||
| 242 | 287 | ||
| 288 | void rnd_state_set(unsigned long seed0) | ||
| 289 | { | ||
| 243 | Insist(seed0 < R_m); | 290 | Insist(seed0 < R_m); |
| 244 | Insist(seed0 != 0); | 291 | Insist(seed0 != 0); |
| 245 | seed = seed0; | 292 | seed = seed0; |
| 246 | 293 | ||
| 247 | rnd_verify(0); | 294 | rnd_verify(0); |
| 248 | Insist(seed == seed0); | 295 | Insist(seed == seed0); |
| 296 | } | ||
| 297 | |||
| 298 | /* rnd_state_set_2 -- legacy support for v2 rnd states | ||
| 299 | * | ||
| 300 | * In v2, the published "seed" (state) value was the seed *before* | ||
| 301 | * the 10 rnds to churn up and separate nearby values from time(). | ||
| 302 | * | ||
| 303 | * Set the seed, then convert it to a v3 state by doing those 10 rnds. | ||
| 304 | */ | ||
| 305 | void rnd_state_set_v2(unsigned long seed0_v2) | ||
| 306 | { | ||
| 307 | int i; | ||
| 308 | unsigned long seed0; | ||
| 249 | 309 | ||
| 250 | /* The 'random' seed is taken from time(), which may simply be a | 310 | rnd_state_set(seed0_v2); |
| 251 | * count of seconds: therefore successive runs may start with | ||
| 252 | * nearby seeds, possibly differing only by 1. So the first value | ||
| 253 | * returned by rnd() may differ by only 48271. It is conceivable | ||
| 254 | * that some tests might be able to 'spot' this pattern (for | ||
| 255 | * example: by using the first rnd() value, mod 100M and rounded | ||
| 256 | * to multiple of 1024K, as arena size in bytes). | ||
| 257 | * | ||
| 258 | * So to mix it up a bit, we do a few iterations now. How many? | ||
| 259 | * Very roughly, 48271^2 is of the same order as 2^31, so two | ||
| 260 | * iterations would make the characteristic difference similar to | ||
| 261 | * the period. Hey, let's go wild and do 10. | ||
| 262 | */ | ||
| 263 | for(i = 0; i < 10; i += 1) { | 311 | for(i = 0; i < 10; i += 1) { |
| 264 | (void)rnd(); | 312 | (void)rnd(); |
| 265 | } | 313 | } |
| 314 | |||
| 315 | seed0 = rnd_state(); | ||
| 316 | printf("rnd_state_set_v2(): seed0_v2 = %lu, converted to state_v3 = %lu.\n", seed0_v2, seed0); | ||
| 317 | rnd_state_set(seed0); | ||
| 266 | } | 318 | } |
| 267 | 319 | ||
| 268 | 320 | ||