ref: 16a2cc57f9cd49f84db08e9c46478d8d0acfdf45
dir: /lock.c/
#include <u.h> #include <libc.h> #include "bench.h" #define NLockIters 1 typedef struct SLock SLock; struct SLock { long state; long sem; }; int casl(long *, long, long); Lock l; QLock q; SLock s; static int count; void nop(void) { } void work(void) { int i; for(i = 0; i < 100*1000; i++) count++; } void slock(SLock *s) { int i; for(i = 0; i < 1000; 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 dolock(void (*work)(void), int n) { int i; for(i = 0; i < n; i++){ lock(&l); work(); unlock(&l); } } void doqlock(void (*work)(void), int n) { int i; for(i = 0; i < n; i++){ qlock(&q); work(); qunlock(&q); } } void doslock(void (*work)(void), int n) { int i; for(i = 0; i < n; i++){ slock(&s); work(); sunlock(&s); } } void lockbench(void (*fn)(void(*)(void), int), int nthr, void (*work)(void), int ninc) { static long thrwait; int i, p; thrwait = 0; for(i = 0; i < nthr; i++){ if((p = rfork(RFPROC|RFMEM)) == -1) sysfatal("rfork: %r"); if(p == 0){ semacquire(&thrwait, 1); (*fn)(work, ninc); exits(nil); } } semrelease(&thrwait, nthr); for(i = 0; i < nthr; i++) free(wait()); } void benchlock1(B *b) { lockbench(dolock, 1, nop, b->N); } void benchqlock1(B *b) { lockbench(doqlock, 1, nop, b->N); } void benchslock1(B *b) { lockbench(doslock, 1, nop, b->N); } void benchlock4(B *b) { lockbench(dolock, 4, nop, b->N); } void benchqlock4(B *b) { lockbench(doqlock, 4, nop, b->N); } void benchslock4(B *b) { lockbench(doslock, 4, nop, b->N); } void benchlock16(B *b) { lockbench(dolock, 16, nop, b->N); } void benchqlock16(B *b) { lockbench(doqlock, 16, nop, b->N); } void benchslock16(B *b) { lockbench(doslock, 16, nop, b->N); } void benchlock64(B *b) { lockbench(dolock, 64, nop, b->N); } void benchqlock64(B *b) { lockbench(doqlock, 64, nop, b->N); } void benchslock64(B *b) { lockbench(doslock, 64, nop, b->N); } void benchlock512(B *b) { lockbench(dolock, 512, nop, b->N); } void benchqlock512(B *b) { lockbench(doqlock, 512, nop, b->N); } void benchslock512(B *b) { lockbench(doslock, 512, nop, b->N); } void benchlock1_w(B *b) { lockbench(dolock, 1, work, b->N); } void benchqlock1_w(B *b) { lockbench(doqlock, 1, work, b->N); } void benchslock1_w(B *b) { lockbench(doslock, 1, work, b->N); } void benchlock4_w(B *b) { lockbench(dolock, 4, work, b->N); } void benchqlock4_w(B *b) { lockbench(doqlock, 4, work, b->N); } void benchslock4_w(B *b) { lockbench(doslock, 4, work, b->N); } void benchlock16_w(B *b) { lockbench(dolock, 16, work, b->N); } void benchqlock16_w(B *b) { lockbench(doqlock, 16, work, b->N); } void benchslock16_w(B *b) { lockbench(doslock, 16, work, b->N); } void benchlock64_w(B *b) { lockbench(dolock, 64, work, b->N); } void benchqlock64_w(B *b) { lockbench(doqlock, 64, work, b->N); } void benchslock64_w(B *b) { lockbench(doslock, 64, work, b->N); } void benchlock512_w(B *b) { lockbench(dolock, 512, work, b->N); } void benchqlock512_w(B *b) { lockbench(doqlock, 512, work, b->N); } void benchslock512_w(B *b) { lockbench(doslock, 512, work, b->N); } void main(int argc, char **argv) { benchinit(argc, argv); print("== locking (fast work) ==\n"); BM(benchlock1); BM(benchqlock1); BM(benchslock1); BM(benchlock4); BM(benchqlock4); BM(benchslock4); BM(benchlock16); BM(benchqlock16); BM(benchslock16); BM(benchlock64); BM(benchqlock64); BM(benchslock64); BM(benchlock512); BM(benchqlock512); BM(benchslock512); print("== locking (slow work) ==\n"); BM(benchlock1_w); BM(benchqlock1_w); BM(benchslock1_w); BM(benchlock4_w); BM(benchqlock4_w); BM(benchslock4_w); BM(benchlock16_w); BM(benchqlock16_w); BM(benchslock16_w); BM(benchlock64_w); BM(benchqlock64_w); BM(benchslock64_w); BM(benchlock512_w); BM(benchqlock512_w); BM(benchslock512_w); exits(nil); }