ref: 3df92bd8dd256de9b90fd12a4d63d8bf458f1b83
dir: /test.c/
#include <u.h> #include <libc.h> #include <bench.h> typedef struct SLock SLock; struct SLock { long state; long sem; }; int casl(long *, long, long); void slock(SLock *s) { int i; for(i = 0; i < 100; i++){ if(casl(&s->state, 0, 1)) return; sleep(0); } if(ainc(&s->state) == 1) return; while(semacquire(&s->sem, 1) == -1) /* retry */; } void sunlock(SLock *s) { if(adec(&s->state) == 0) return; semrelease(&s->sem, 1); } void benchsyscall(B *b) { int i; extern int sysr1(void); for(i = 0; i < b->N; i++) { (void)sysr1(); } } void benchmallocfree32(B *b) { int i; for(i = 0; i < b->N; i++) { free(malloc(32)); } } void benchrand(B *b) { int i; for(i = 0; i < b->N; i++) { (void)rand(); } } void benchtruerand(B *b) { int i; for(i = 0; i < b->N; i++) { (void)truerand(); } } void benchinc(B *b) { int i; long inc; inc = 0; for(i = 0; i < b->N; i++) { inc++; } } void benchainc(B *b) { int i; long inc; for(i = 0; i < b->N; i++) { ainc(&inc); } } void benchfork(B *b) { int i; for(i = 0; i < b->N; i++){ if(!rfork(RFPROC|RFMEM)) exits(nil); waitpid(); } } void benchmfork(B *b) { int i; for(i = 0; i < b->N; i++){ if(!fork()) exits(nil); waitpid(); } } void benchforkexecl(B *b) { int i; for(i = 0; i < b->N; i++){ switch(fork()){ case -1: abort(); case 0: execl("./6.true", "6.true", nil); print("exec: %r"); abort(); default: waitpid(); } } } void pingpongbench(B *b) { int i; int pfd[2]; char buf[32]; if(pipe(pfd) == -1) sysfatal("pipe: %r"); switch(fork()){ case -1: sysfatal("fork: %r"); break; case 0: while(1){ if(read(pfd[0], buf, sizeof(buf)) != 4) sysfatal("wrk: read: %r"); if(write(pfd[1], "pong", 4) != 4) sysfatal("wrk: write: %r"); } break; default: for(i = 0; i < b->N; i++){ if(write(pfd[1], "ping", 4) != 4) sysfatal("write: %r"); if(read(pfd[0], buf, sizeof(buf)) != 4) sysfatal("read: %r"); } break; } } Lock l; QLock q; SLock s; int count; void hammerlock(int n) { int i; for(i = 0; i < n; i++){ lock(&l); count++; unlock(&l); } } void hammerqlock(int n) { int i; for(i = 0; i < n; i++){ qlock(&q); count++; qunlock(&q); } } void hammerslock(int n) { int i; for(i = 0; i < n; i++){ slock(&s); count++; sunlock(&s); } } void lockbench(void (*fn)(int), int nthr, int ninc) { int i, p; for(i = 0; i < nthr; i++){ if((p = rfork(RFPROC|RFMEM)) == -1) sysfatal("rfork: %r"); if(p == 0){ (*fn)(ninc); exits(nil); } } for(i = 0; i < nthr; i++) free(wait()); } void benchlock1(B *b){lockbench(hammerlock, 1, b->N);} void benchqlock1(B *b){lockbench(hammerqlock, 1, b->N);} void benchslock1(B *b){lockbench(hammerslock, 1, b->N);} void benchlock4(B *b){lockbench(hammerlock, 4, b->N);} void benchqlock4(B *b){lockbench(hammerqlock, 4, b->N);} void benchslock4(B *b){lockbench(hammerslock, 4, b->N);} void benchlock16(B *b){lockbench(hammerlock, 16, b->N);} void benchqlock16(B *b){lockbench(hammerqlock, 16, b->N);} void benchslock16(B *b){lockbench(hammerslock, 16, b->N);} void benchlock64(B *b){lockbench(hammerlock, 64, b->N);} void benchqlock64(B *b){lockbench(hammerqlock, 64, b->N);} void benchslock64(B *b){lockbench(hammerslock, 64, b->N);} void benchlock512(B *b){lockbench(hammerlock, 512, b->N);} void benchqlock512(B *b){lockbench(hammerqlock, 512, b->N);} void benchslock512(B *b){lockbench(hammerslock, 512, b->N);} void main(void) { benchinit(); bench("syscall", benchsyscall); bench("mallocfree32", benchmallocfree32); bench("rand", benchrand); bench("truerand", benchtruerand); bench("inc", benchinc); bench("ainc", benchainc); bench("mfork", benchmfork); bench("fork", benchfork); bench("forkexecl", benchforkexecl); bench("lock1", benchlock1); bench("qlock1", benchqlock1); bench("slock1", benchslock1); bench("lock4", benchlock4); bench("qlock4", benchqlock4); bench("slock4", benchslock4); bench("lock16", benchlock16); bench("qlock16", benchqlock16); bench("slock16", benchslock16); bench("lock64", benchlock64); bench("qlock64", benchqlock64); bench("slock64", benchslock64); bench("lock512", benchlock512); bench("qlock512", benchqlock512); bench("slock512", benchslock512); bench("pingpong", pingpongbench); exits(0); }