ref: 2869a292caf121ee26d4fc5f0594c051210e9e2f
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);
}