ref: 4f82fa5701c1676f78c6aa123cc68e76d0e3e694
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(); } } } 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()); } #define LKB(nthr) \ void benchlock##nthr(B *b){lockbench(hammerlock, nthr, b->N);} \ void benchqlock##nthr(B *b){lockbench(hammerqlock, nthr, b->N);} \ void benchslock##nthr(B *b){lockbench(hammerslock, nthr, b->N);} LKB(1) LKB(4) LKB(32) LKB(512) 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("lock32", benchlock32); bench("qlock32", benchqlock32); bench("slock32", benchslock32); bench("lock512", benchlock512); bench("qlock512", benchqlock512); bench("slock512", benchslock512); exits(0); }