diff options
author | rsc <devnull@localhost> | 2005-07-12 15:23:36 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2005-07-12 15:23:36 +0000 |
commit | a0d146edd7a7de6236a0d60baafeeb59f8452aae (patch) | |
tree | b55baa526d9f5adfc73246e6ee2fadf455e0b7a2 /src/cmd/venti/randtest.c | |
parent | 88bb285e3d87ec2508840af33f7e0af53ec3c13c (diff) | |
download | plan9port-a0d146edd7a7de6236a0d60baafeeb59f8452aae.tar.gz plan9port-a0d146edd7a7de6236a0d60baafeeb59f8452aae.tar.bz2 plan9port-a0d146edd7a7de6236a0d60baafeeb59f8452aae.zip |
return of venti
Diffstat (limited to 'src/cmd/venti/randtest.c')
-rw-r--r-- | src/cmd/venti/randtest.c | 334 |
1 files changed, 334 insertions, 0 deletions
diff --git a/src/cmd/venti/randtest.c b/src/cmd/venti/randtest.c new file mode 100644 index 00000000..b7a09ef8 --- /dev/null +++ b/src/cmd/venti/randtest.c @@ -0,0 +1,334 @@ +#include <u.h> +#include <libc.h> +#include <venti.h> +#include <libsec.h> +#include <thread.h> + + +enum { STACK = 32768 }; +void xxxsrand(long); +long xxxlrand(void); + +Channel *cw; +Channel *cr; +char *host; +int blocksize, seed, randpct; +int doread, dowrite, packets, permute; +vlong totalbytes, cur; +VtConn *z; +int multi; +int maxpackets; +int sequence; +int doublecheck = 1; +uint *order; + +void +usage(void) +{ + fprint(2, "usage: randtest [-q] [-h host] [-s seed] [-b blocksize] [-p randpct] [-n totalbytes] [-M maxblocks] [-P] [-r] [-w]\n"); + threadexitsall("usage"); +} + +void +wr(char *buf, char *buf2) +{ + uchar score[VtScoreSize], score2[VtScoreSize]; + DigestState ds; + + memset(&ds, 0, sizeof ds); + if(doublecheck) + sha1((uchar*)buf, blocksize, score, &ds); + if(vtwrite(z, score2, VtDataType, (uchar*)buf, blocksize) < 0) + sysfatal("vtwrite %V at %,lld: %r", score, cur); + if(doublecheck && memcmp(score, score2, VtScoreSize) != 0) + sysfatal("score mismatch! %V %V", score, score2); +} + +void +wrthread(void *v) +{ + char *p; + + USED(v); + while((p = recvp(cw)) != nil){ + wr(p, nil); + free(p); + } +} + +void +rd(char *buf, char *buf2) +{ + uchar score[VtScoreSize]; + DigestState ds; + + memset(&ds, 0, sizeof ds); + sha1((uchar*)buf, blocksize, score, &ds); + if(vtread(z, score, VtDataType, (uchar*)buf2, blocksize) < 0) + sysfatal("vtread %V at %,lld: %r", score, cur); + if(memcmp(buf, buf2, blocksize) != 0) + sysfatal("bad data read! %V", score); +} + +void +rdthread(void *v) +{ + char *p, *buf2; + + buf2 = vtmalloc(blocksize); + USED(v); + while((p = recvp(cr)) != nil){ + rd(p, buf2); + free(p); + } +} + +char *template; + +void +run(void (*fn)(char*, char*), Channel *c) +{ + int i, t, j, packets; + char *buf2, *buf; + + buf2 = vtmalloc(blocksize); + buf = vtmalloc(blocksize); + cur = 0; + packets = totalbytes/blocksize; + if(maxpackets == 0) + maxpackets = packets; + order = vtmalloc(packets*sizeof order[0]); + for(i=0; i<packets; i++) + order[i] = i; + if(permute){ + for(i=1; i<packets; i++){ + j = nrand(i+1); + t = order[i]; + order[i] = order[j]; + order[j] = t; + } + } + for(i=0; i<packets && i<maxpackets; i++){ + memmove(buf, template, blocksize); + *(uint*)buf = order[i]; + if(c){ + sendp(c, buf); + buf = vtmalloc(blocksize); + }else + (*fn)(buf, buf2); + cur += blocksize; + } + free(order); +} + +#define TWID64 ((u64int)~(u64int)0) + +u64int +unittoull(char *s) +{ + char *es; + u64int n; + + if(s == nil) + return TWID64; + n = strtoul(s, &es, 0); + if(*es == 'k' || *es == 'K'){ + n *= 1024; + es++; + }else if(*es == 'm' || *es == 'M'){ + n *= 1024*1024; + es++; + }else if(*es == 'g' || *es == 'G'){ + n *= 1024*1024*1024; + es++; + }else if(*es == 't' || *es == 'T'){ + n *= 1024*1024; + n *= 1024*1024; + } + if(*es != '\0') + return TWID64; + return n; +} + +void +threadmain(int argc, char *argv[]) +{ + int i, max; + vlong t0; + double t; + + blocksize = 8192; + seed = 0; + randpct = 50; + host = nil; + doread = 0; + dowrite = 0; + totalbytes = 1*1024*1024*1024; + fmtinstall('V', vtscorefmt); + fmtinstall('F', vtfcallfmt); + + ARGBEGIN{ + case 'b': + blocksize = unittoull(EARGF(usage())); + break; + case 'h': + host = EARGF(usage()); + break; + case 'M': + maxpackets = unittoull(EARGF(usage())); + break; + case 'm': + multi = atoi(EARGF(usage())); + break; + case 'n': + totalbytes = unittoull(EARGF(usage())); + break; + case 'p': + randpct = atoi(EARGF(usage())); + break; + case 'P': + permute = 1; + break; + case 'S': + doublecheck = 0; + ventidoublechecksha1 = 0; + break; + case 's': + seed = atoi(EARGF(usage())); + break; + case 'r': + doread = 1; + break; + case 'w': + dowrite = 1; + break; + case 'V': + chattyventi++; + break; + default: + usage(); + }ARGEND + + if(doread==0 && dowrite==0){ + doread = 1; + dowrite = 1; + } + + z = vtdial(host); + if(z == nil) + sysfatal("could not connect to server: %r"); + if(vtconnect(z) < 0) + sysfatal("vtconnect: %r"); + + if(multi){ + cr = chancreate(sizeof(void*), 0); + cw = chancreate(sizeof(void*), 0); + for(i=0; i<multi; i++){ + proccreate(wrthread, nil, STACK); + proccreate(rdthread, nil, STACK); + } + } + + template = vtmalloc(blocksize); + xxxsrand(seed); + max = (256*randpct)/100; + if(max == 0) + max = 1; + for(i=0; i<blocksize; i++) + template[i] = xxxlrand()%max; + if(dowrite){ + t0 = nsec(); + run(wr, cw); + for(i=0; i<multi; i++) + sendp(cw, nil); + t = (nsec() - t0)/1.e9; + print("write: %lld bytes / %.3f seconds = %.6f MB/s\n", + totalbytes, t, (double)totalbytes/1e6/t); + } + if(doread){ + t0 = nsec(); + run(rd, cr); + for(i=0; i<multi; i++) + sendp(cr, nil); + t = (nsec() - t0)/1.e9; + print("read: %lld bytes / %.3f seconds = %.6f MB/s\n", + totalbytes, t, (double)totalbytes/1e6/t); + } + threadexitsall(nil); +} + + +/* + * algorithm by + * D. P. Mitchell & J. A. Reeds + */ + +#define LEN 607 +#define TAP 273 +#define MASK 0x7fffffffL +#define A 48271 +#define M 2147483647 +#define Q 44488 +#define R 3399 +#define NORM (1.0/(1.0+MASK)) + +static ulong rng_vec[LEN]; +static ulong* rng_tap = rng_vec; +static ulong* rng_feed = 0; + +static void +isrand(long seed) +{ + long lo, hi, x; + int i; + + rng_tap = rng_vec; + rng_feed = rng_vec+LEN-TAP; + seed = seed%M; + if(seed < 0) + seed += M; + if(seed == 0) + seed = 89482311; + x = seed; + /* + * Initialize by x[n+1] = 48271 * x[n] mod (2**31 - 1) + */ + for(i = -20; i < LEN; i++) { + hi = x / Q; + lo = x % Q; + x = A*lo - R*hi; + if(x < 0) + x += M; + if(i >= 0) + rng_vec[i] = x; + } +} + +void +xxxsrand(long seed) +{ + isrand(seed); +} + +long +xxxlrand(void) +{ + ulong x; + + rng_tap--; + if(rng_tap < rng_vec) { + if(rng_feed == 0) { + isrand(1); + rng_tap--; + } + rng_tap += LEN; + } + rng_feed--; + if(rng_feed < rng_vec) + rng_feed += LEN; + x = (*rng_feed + *rng_tap) & MASK; + *rng_feed = x; + + return x; +} + |