123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- #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;
- USED(buf2);
- 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;
- }
|